init
@@ -0,0 +1,265 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQml 2.14 as Qml
|
||||
import QtQuick.Window 2.2
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype ApplicationWindow
|
||||
\since 5.1
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\ingroup applicationwindow
|
||||
\ingroup controls
|
||||
\brief Provides a top-level application window.
|
||||
|
||||
\image applicationwindow.png
|
||||
|
||||
ApplicationWindow is a \l Window that adds convenience for positioning items,
|
||||
such as \l MenuBar, \l ToolBar, and \l StatusBar in a platform independent
|
||||
manner.
|
||||
|
||||
\code
|
||||
ApplicationWindow {
|
||||
id: window
|
||||
visible: true
|
||||
|
||||
menuBar: MenuBar {
|
||||
Menu { MenuItem {...} }
|
||||
Menu { MenuItem {...} }
|
||||
}
|
||||
|
||||
toolBar: ToolBar {
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
ToolButton {...}
|
||||
}
|
||||
}
|
||||
|
||||
TabView {
|
||||
id: myContent
|
||||
anchors.fill: parent
|
||||
...
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
\note By default, an ApplicationWindow is not visible.
|
||||
|
||||
The \l{Qt Quick Controls 1 - Gallery} example is a good starting
|
||||
point to explore this type.
|
||||
*/
|
||||
|
||||
Window {
|
||||
id: root
|
||||
|
||||
/*!
|
||||
\qmlproperty MenuBar ApplicationWindow::menuBar
|
||||
|
||||
This property holds the \l MenuBar.
|
||||
|
||||
By default, this value is not set.
|
||||
*/
|
||||
property MenuBar menuBar: null
|
||||
|
||||
/*!
|
||||
\qmlproperty Item ApplicationWindow::toolBar
|
||||
|
||||
This property holds the toolbar \l Item.
|
||||
|
||||
It can be set to any Item type, but is generally used with \l ToolBar.
|
||||
|
||||
By default, this value is not set. When you set the toolbar item, it will
|
||||
be anchored automatically into the application window.
|
||||
*/
|
||||
property Item toolBar
|
||||
|
||||
/*!
|
||||
\qmlproperty Item ApplicationWindow::statusBar
|
||||
|
||||
This property holds the status bar \l Item.
|
||||
|
||||
It can be set to any Item type, but is generally used with \l StatusBar.
|
||||
|
||||
By default, this value is not set. When you set the status bar item, it
|
||||
will be anchored automatically into the application window.
|
||||
*/
|
||||
property Item statusBar
|
||||
|
||||
// The below documentation was supposed to be written as a grouped property, but qdoc would
|
||||
// not render it correctly due to a bug (QTBUG-34206)
|
||||
/*!
|
||||
\qmlproperty ContentItem ApplicationWindow::contentItem
|
||||
|
||||
This group holds the size constraints of the content item. This is the area between the
|
||||
\l ToolBar and the \l StatusBar.
|
||||
The \l ApplicationWindow will use this as input when calculating the effective size
|
||||
constraints of the actual window.
|
||||
It holds these 6 properties for describing the minimum, implicit and maximum sizes:
|
||||
\table
|
||||
\header \li Grouped property \li Description
|
||||
\row \li contentItem.minimumWidth \li The minimum width of the content item.
|
||||
\row \li contentItem.minimumHeight \li The minimum height of the content item.
|
||||
\row \li contentItem.implicitWidth \li The implicit width of the content item.
|
||||
\row \li contentItem.implicitHeight \li The implicit height of the content item.
|
||||
\row \li contentItem.maximumWidth \li The maximum width of the content item.
|
||||
\row \li contentItem.maximumHeight \li The maximum height of the content item.
|
||||
\endtable
|
||||
*/
|
||||
property alias contentItem : contentArea
|
||||
|
||||
/*! The style Component for the window.
|
||||
\sa {Qt Quick Controls 1 Styles QML Types}
|
||||
*/
|
||||
property Component style: Settings.styleComponent(Settings.style, "ApplicationWindowStyle.qml", root)
|
||||
|
||||
/*! \internal */
|
||||
property alias __style: styleLoader.item
|
||||
|
||||
/*! \internal */
|
||||
property alias __panel: panelLoader.item
|
||||
|
||||
/*! \internal */
|
||||
property real __topBottomMargins: __panel.contentArea.y + __panel.statusBarArea.height
|
||||
/*! \internal
|
||||
There is a similar macro QWINDOWSIZE_MAX in qwindow_p.h that is used to limit the
|
||||
range of QWindow::maximum{Width,Height}
|
||||
However, in case we have a very big number (> 2^31) conversion will fail, and it will be
|
||||
converted to 0, resulting in that we will call setMaximumWidth(0)....
|
||||
We therefore need to enforce the limit at a level where we are still operating on
|
||||
floating point values.
|
||||
*/
|
||||
readonly property real __qwindowsize_max: (1 << 24) - 1
|
||||
|
||||
/*! \internal */
|
||||
property real __width: 0
|
||||
Qml.Binding {
|
||||
target: root
|
||||
property: "__width"
|
||||
when: (root.minimumWidth <= root.maximumWidth) && !contentArea.__noImplicitWidthGiven
|
||||
value: Math.max(Math.min(root.maximumWidth, contentArea.implicitWidth), root.minimumWidth)
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
/*! \internal */
|
||||
property real __height: 0
|
||||
Qml.Binding {
|
||||
target: root
|
||||
property: "__height"
|
||||
when: (root.minimumHeight <= root.maximumHeight) && !contentArea.__noImplicitHeightGiven
|
||||
value: Math.max(Math.min(root.maximumHeight, contentArea.implicitHeight + __topBottomMargins), root.minimumHeight)
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
/* As soon as an application developer writes
|
||||
width: 200
|
||||
this binding will be broken. This is the reason for this indirection
|
||||
via __width (and __height)
|
||||
*/
|
||||
width: __width
|
||||
height: __height
|
||||
|
||||
minimumWidth: contentArea.__noMinimumWidthGiven ? 0 : contentArea.minimumWidth
|
||||
minimumHeight: contentArea.__noMinimumHeightGiven ? 0 : (contentArea.minimumHeight + __topBottomMargins)
|
||||
|
||||
maximumWidth: Math.min(__qwindowsize_max, contentArea.maximumWidth)
|
||||
maximumHeight: Math.min(__qwindowsize_max, contentArea.maximumHeight + __topBottomMargins)
|
||||
|
||||
/*! \internal */
|
||||
default property alias data: contentArea.data
|
||||
|
||||
flags: Qt.Window | Qt.WindowFullscreenButtonHint |
|
||||
Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.WindowMinMaxButtonsHint |
|
||||
Qt.WindowCloseButtonHint | Qt.WindowFullscreenButtonHint
|
||||
// QTBUG-35049: Windows is removing features we didn't ask for, even though Qt::CustomizeWindowHint is not set
|
||||
// Otherwise Qt.Window | Qt.WindowFullscreenButtonHint would be enough
|
||||
|
||||
Loader {
|
||||
id: panelLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: __style ? __style.panel : null
|
||||
onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", root)
|
||||
focus: true
|
||||
Loader {
|
||||
id: styleLoader
|
||||
sourceComponent: style
|
||||
property var __control: root
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property bool hasColor: root.color != "#ffffff"
|
||||
}
|
||||
onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", root)
|
||||
}
|
||||
|
||||
Qml.Binding {
|
||||
target: toolBar
|
||||
property: "parent"
|
||||
value: __panel.toolBarArea
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
Qml.Binding {
|
||||
target: statusBar
|
||||
property: "parent"
|
||||
value: __panel.statusBarArea
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
Qml.Binding {
|
||||
property: "parent"
|
||||
target: menuBar ? menuBar.__contentItem : null
|
||||
when: menuBar && !menuBar.__isNative
|
||||
value: __panel.menuBarArea
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
Qml.Binding {
|
||||
target: menuBar
|
||||
property: "__parentWindow"
|
||||
value: root
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
Keys.forwardTo: menuBar ? [menuBar.__contentItem, __panel] : []
|
||||
|
||||
ContentItem {
|
||||
id: contentArea
|
||||
anchors.fill: parent
|
||||
parent: __panel.contentArea
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype BusyIndicator
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.2
|
||||
\ingroup controls
|
||||
\brief A busy indicator.
|
||||
|
||||
\image busyindicator.png
|
||||
|
||||
The busy indicator should be used to indicate activity while content is
|
||||
being loaded or the UI is blocked waiting for a resource to become available.
|
||||
|
||||
The following snippet shows how to use the BusyIndicator:
|
||||
|
||||
\qml
|
||||
BusyIndicator {
|
||||
running: image.status === Image.Loading
|
||||
}
|
||||
\endqml
|
||||
|
||||
You can create a custom appearance for a Busy Indicator by
|
||||
assigning a \l {BusyIndicatorStyle}.
|
||||
*/
|
||||
Control {
|
||||
id: indicator
|
||||
|
||||
/*! \qmlproperty bool BusyIndicator::running
|
||||
|
||||
This property holds whether the busy indicator is currently indicating
|
||||
activity.
|
||||
|
||||
\note The indicator is only visible when this property is set to \c true.
|
||||
|
||||
The default value is \c true.
|
||||
*/
|
||||
property bool running: true
|
||||
|
||||
Accessible.role: Accessible.Indicator
|
||||
Accessible.name: "busy"
|
||||
|
||||
style: Settings.styleComponent(Settings.style, "BusyIndicatorStyle.qml", indicator)
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQml 2.14 as Qml
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype Button
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup controls
|
||||
\brief A push button with a text label.
|
||||
|
||||
\image button.png
|
||||
|
||||
The push button is perhaps the most commonly used widget in any graphical
|
||||
user interface. Pushing (or clicking) a button commands the computer to
|
||||
perform some action or answer a question. Common examples of buttons are
|
||||
OK, Apply, Cancel, Close, Yes, No, and Help buttons.
|
||||
|
||||
\qml
|
||||
Button {
|
||||
text: "Button"
|
||||
}
|
||||
\endqml
|
||||
|
||||
Button is similar to the QPushButton widget.
|
||||
|
||||
You can create a custom appearance for a Button by
|
||||
assigning a \l {ButtonStyle}.
|
||||
*/
|
||||
BasicButton {
|
||||
id: button
|
||||
|
||||
/*! This property holds whether the push button is the default button.
|
||||
Default buttons decide what happens when the user presses enter in a
|
||||
dialog without giving a button explicit focus. \note This property only
|
||||
changes the appearance of the button. The expected behavior needs to be
|
||||
implemented by the user.
|
||||
|
||||
The default value is \c false.
|
||||
*/
|
||||
property bool isDefault: false
|
||||
|
||||
/*! Assign a \l Menu to this property to get a pull-down menu button.
|
||||
|
||||
The default value is \c null.
|
||||
*/
|
||||
property Menu menu: null
|
||||
|
||||
__effectivePressed: __behavior.effectivePressed || menu && menu.__popupVisible
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
Accessible.name: text
|
||||
|
||||
style: Settings.styleComponent(Settings.style, "ButtonStyle.qml", button)
|
||||
|
||||
Qml.Binding {
|
||||
target: menu
|
||||
property: "__minimumWidth"
|
||||
value: button.__panel.width
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
Qml.Binding {
|
||||
target: menu
|
||||
property: "__visualItem"
|
||||
value: button
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: __behavior
|
||||
function onEffectivePressedChanged() {
|
||||
if (!Settings.hasTouchScreen && __behavior.effectivePressed && menu)
|
||||
popupMenuTimer.start()
|
||||
}
|
||||
function onReleased() {
|
||||
if (Settings.hasTouchScreen && __behavior.containsMouse && menu)
|
||||
popupMenuTimer.start()
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: popupMenuTimer
|
||||
interval: 10
|
||||
onTriggered: {
|
||||
__behavior.keyPressed = false
|
||||
if (Qt.application.layoutDirection === Qt.RightToLeft)
|
||||
menu.__popup(Qt.rect(button.width, button.height, 0, 0), 0)
|
||||
else
|
||||
menu.__popup(Qt.rect(0, button.height, 0, 0), 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,456 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 1.5
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype Calendar
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.3
|
||||
\ingroup controls
|
||||
\brief Provides a way to select dates from a calendar.
|
||||
|
||||
\image calendar.png
|
||||
|
||||
Calendar allows selection of dates from a grid of days, similar to
|
||||
QCalendarWidget.
|
||||
|
||||
The dates on the calendar can be selected with the mouse, or navigated
|
||||
with the keyboard.
|
||||
|
||||
The selected date can be set through \l selectedDate.
|
||||
A minimum and maximum date can be set through \l minimumDate and
|
||||
\l maximumDate. The earliest minimum date that can be set is 1 January, 1
|
||||
AD. The latest maximum date that can be set is 25 October, 275759 AD.
|
||||
|
||||
\code
|
||||
Calendar {
|
||||
minimumDate: new Date(2017, 0, 1)
|
||||
maximumDate: new Date(2018, 0, 1)
|
||||
}
|
||||
\endcode
|
||||
|
||||
The selected date is displayed using the format in the application's
|
||||
default locale.
|
||||
|
||||
Week numbers can be displayed by setting the weekNumbersVisible property to
|
||||
\c true.
|
||||
|
||||
\qml
|
||||
Calendar {
|
||||
weekNumbersVisible: true
|
||||
}
|
||||
\endqml
|
||||
|
||||
You can create a custom appearance for Calendar by assigning a
|
||||
\l {CalendarStyle}.
|
||||
*/
|
||||
|
||||
Control {
|
||||
id: calendar
|
||||
|
||||
/*!
|
||||
\qmlproperty date Calendar::selectedDate
|
||||
|
||||
The date that has been selected by the user.
|
||||
|
||||
This property is subject to the following validation:
|
||||
|
||||
\list
|
||||
\li If selectedDate is outside the range of \l minimumDate and
|
||||
\l maximumDate, it will be clamped to be within that range.
|
||||
|
||||
\li selectedDate will not be changed if \c undefined or some other
|
||||
invalid value is assigned.
|
||||
|
||||
\li If there are hours, minutes, seconds or milliseconds set, they
|
||||
will be removed.
|
||||
\endlist
|
||||
|
||||
The default value is the current date, which is equivalent to:
|
||||
|
||||
\code
|
||||
new Date()
|
||||
\endcode
|
||||
*/
|
||||
property alias selectedDate: rangedDate.date
|
||||
|
||||
/*!
|
||||
\qmlproperty date Calendar::minimumDate
|
||||
|
||||
The earliest date that this calendar will accept.
|
||||
|
||||
By default, this property is set to the earliest minimum date
|
||||
(1 January, 1 AD).
|
||||
*/
|
||||
property alias minimumDate: rangedDate.minimumDate
|
||||
|
||||
/*!
|
||||
\qmlproperty date Calendar::maximumDate
|
||||
|
||||
The latest date that this calendar will accept.
|
||||
|
||||
By default, this property is set to the latest maximum date
|
||||
(25 October, 275759 AD).
|
||||
*/
|
||||
property alias maximumDate: rangedDate.maximumDate
|
||||
|
||||
/*!
|
||||
This property determines which month in visibleYear is shown on the
|
||||
calendar.
|
||||
|
||||
The month is from \c 0 to \c 11 to be consistent with the JavaScript
|
||||
Date object.
|
||||
|
||||
\sa visibleYear
|
||||
*/
|
||||
property int visibleMonth: selectedDate.getMonth()
|
||||
|
||||
/*!
|
||||
This property determines which year is shown on the
|
||||
calendar.
|
||||
|
||||
\sa visibleMonth
|
||||
*/
|
||||
property int visibleYear: selectedDate.getFullYear()
|
||||
|
||||
onSelectedDateChanged: {
|
||||
// When the selected date changes, the view should move back to that date.
|
||||
visibleMonth = selectedDate.getMonth();
|
||||
visibleYear = selectedDate.getFullYear();
|
||||
}
|
||||
|
||||
RangedDate {
|
||||
id: rangedDate
|
||||
date: new Date()
|
||||
minimumDate: CalendarUtils.minimumCalendarDate
|
||||
maximumDate: CalendarUtils.maximumCalendarDate
|
||||
}
|
||||
|
||||
/*!
|
||||
This property determines the visibility of the frame
|
||||
surrounding the calendar.
|
||||
|
||||
The default value is \c true.
|
||||
*/
|
||||
property bool frameVisible: true
|
||||
|
||||
/*!
|
||||
This property determines the visibility of week numbers.
|
||||
|
||||
The default value is \c false.
|
||||
*/
|
||||
property bool weekNumbersVisible: false
|
||||
|
||||
/*!
|
||||
This property determines the visibility of the navigation bar.
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
The default value is \c true.
|
||||
*/
|
||||
property bool navigationBarVisible: true
|
||||
|
||||
/*!
|
||||
\qmlproperty enum Calendar::dayOfWeekFormat
|
||||
|
||||
The format in which the days of the week (in the header) are displayed.
|
||||
|
||||
\c Locale.ShortFormat is the default and recommended format, as
|
||||
\c Locale.NarrowFormat may not be fully supported by each locale (see
|
||||
\l {Locale String Format Types}) and
|
||||
\c Locale.LongFormat may not fit within the header cells.
|
||||
*/
|
||||
property int dayOfWeekFormat: Locale.ShortFormat
|
||||
|
||||
/*!
|
||||
\qmlproperty object Calendar::locale
|
||||
\since QtQuick.Controls 1.6
|
||||
|
||||
This property controls the locale that this calendar uses to display
|
||||
itself.
|
||||
|
||||
The locale affects how dates and day names are localized, as well as
|
||||
which day is considered the first in a week.
|
||||
|
||||
The following example sets an Australian locale:
|
||||
|
||||
\code
|
||||
locale: Qt.locale("en_AU")
|
||||
\endcode
|
||||
|
||||
The default value is equivalent to \c Qt.locale().
|
||||
*/
|
||||
property var locale: Qt.locale()
|
||||
|
||||
// left for compatibility reasons; can be removed in next minor version/Qt 6
|
||||
property alias __locale: calendar.locale
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
This property holds the model that will be used by the Calendar to
|
||||
populate the dates available to the user.
|
||||
*/
|
||||
property CalendarModel __model: CalendarModel {
|
||||
locale: calendar.locale
|
||||
|
||||
// TODO: don't set the hour when QTBUG-56787 is fixed
|
||||
visibleDate: new Date(visibleYear, visibleMonth, 1, 12)
|
||||
}
|
||||
|
||||
style: Settings.styleComponent(Settings.style, "CalendarStyle.qml", calendar)
|
||||
|
||||
/*!
|
||||
\qmlsignal Calendar::hovered(date date)
|
||||
|
||||
Emitted when the mouse hovers over a valid date in the calendar.
|
||||
|
||||
\e date is the date that was hovered over.
|
||||
|
||||
The corresponding handler is \c onHovered.
|
||||
*/
|
||||
signal hovered(date date)
|
||||
|
||||
/*!
|
||||
\qmlsignal Calendar::pressed(date date)
|
||||
|
||||
Emitted when the mouse is pressed on a valid date in the calendar.
|
||||
|
||||
This is also emitted when dragging the mouse to another date while it is pressed.
|
||||
|
||||
\e date is the date that the mouse was pressed on.
|
||||
|
||||
The corresponding handler is \c onPressed.
|
||||
*/
|
||||
signal pressed(date date)
|
||||
|
||||
/*!
|
||||
\qmlsignal Calendar::released(date date)
|
||||
|
||||
Emitted when the mouse is released over a valid date in the calendar.
|
||||
|
||||
\e date is the date that the mouse was released over.
|
||||
|
||||
The corresponding handler is \c onReleased.
|
||||
*/
|
||||
signal released(date date)
|
||||
|
||||
/*!
|
||||
\qmlsignal Calendar::clicked(date date)
|
||||
|
||||
Emitted when the mouse is clicked on a valid date in the calendar.
|
||||
|
||||
\e date is the date that the mouse was clicked on.
|
||||
|
||||
The corresponding handler is \c onClicked.
|
||||
*/
|
||||
signal clicked(date date)
|
||||
|
||||
/*!
|
||||
\qmlsignal Calendar::doubleClicked(date date)
|
||||
|
||||
Emitted when the mouse is double-clicked on a valid date in the calendar.
|
||||
|
||||
\e date is the date that the mouse was double-clicked on.
|
||||
|
||||
The corresponding handler is \c onDoubleClicked.
|
||||
*/
|
||||
signal doubleClicked(date date)
|
||||
|
||||
/*!
|
||||
\qmlsignal Calendar::pressAndHold(date date)
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
Emitted when the mouse is pressed and held on a valid date in the calendar.
|
||||
|
||||
\e date is the date that the mouse was pressed on.
|
||||
|
||||
The corresponding handler is \c onPressAndHold.
|
||||
*/
|
||||
signal pressAndHold(date date)
|
||||
|
||||
/*!
|
||||
\qmlmethod void Calendar::showPreviousMonth()
|
||||
Sets visibleMonth to the previous month.
|
||||
*/
|
||||
function showPreviousMonth() {
|
||||
if (visibleMonth === 0) {
|
||||
visibleMonth = CalendarUtils.monthsInAYear - 1;
|
||||
--visibleYear;
|
||||
} else {
|
||||
--visibleMonth;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void Calendar::showNextMonth()
|
||||
Sets visibleMonth to the next month.
|
||||
*/
|
||||
function showNextMonth() {
|
||||
if (visibleMonth === CalendarUtils.monthsInAYear - 1) {
|
||||
visibleMonth = 0;
|
||||
++visibleYear;
|
||||
} else {
|
||||
++visibleMonth;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void Calendar::showPreviousYear()
|
||||
Sets visibleYear to the previous year.
|
||||
*/
|
||||
function showPreviousYear() {
|
||||
if (visibleYear - 1 >= minimumDate.getFullYear()) {
|
||||
--visibleYear;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void Calendar::showNextYear()
|
||||
Sets visibleYear to the next year.
|
||||
*/
|
||||
function showNextYear() {
|
||||
if (visibleYear + 1 <= maximumDate.getFullYear()) {
|
||||
++visibleYear;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Selects the month before the current month in \l selectedDate.
|
||||
*/
|
||||
function __selectPreviousMonth() {
|
||||
calendar.selectedDate = CalendarUtils.setMonth(calendar.selectedDate, calendar.selectedDate.getMonth() - 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
Selects the month after the current month in \l selectedDate.
|
||||
*/
|
||||
function __selectNextMonth() {
|
||||
calendar.selectedDate = CalendarUtils.setMonth(calendar.selectedDate, calendar.selectedDate.getMonth() + 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
Selects the week before the current week in \l selectedDate.
|
||||
*/
|
||||
function __selectPreviousWeek() {
|
||||
var newDate = new Date(calendar.selectedDate);
|
||||
newDate.setDate(newDate.getDate() - CalendarUtils.daysInAWeek);
|
||||
calendar.selectedDate = newDate;
|
||||
}
|
||||
|
||||
/*!
|
||||
Selects the week after the current week in \l selectedDate.
|
||||
*/
|
||||
function __selectNextWeek() {
|
||||
var newDate = new Date(calendar.selectedDate);
|
||||
newDate.setDate(newDate.getDate() + CalendarUtils.daysInAWeek);
|
||||
calendar.selectedDate = newDate;
|
||||
}
|
||||
|
||||
/*!
|
||||
Selects the first day of the current month in \l selectedDate.
|
||||
*/
|
||||
function __selectFirstDayOfMonth() {
|
||||
var newDate = new Date(calendar.selectedDate);
|
||||
newDate.setDate(1);
|
||||
calendar.selectedDate = newDate;
|
||||
}
|
||||
|
||||
/*!
|
||||
Selects the last day of the current month in \l selectedDate.
|
||||
*/
|
||||
function __selectLastDayOfMonth() {
|
||||
var newDate = new Date(calendar.selectedDate);
|
||||
newDate.setDate(CalendarUtils.daysInMonth(newDate));
|
||||
calendar.selectedDate = newDate;
|
||||
}
|
||||
|
||||
/*!
|
||||
Selects the day before the current day in \l selectedDate.
|
||||
*/
|
||||
function __selectPreviousDay() {
|
||||
var newDate = new Date(calendar.selectedDate);
|
||||
newDate.setDate(newDate.getDate() - 1);
|
||||
calendar.selectedDate = newDate;
|
||||
}
|
||||
|
||||
/*!
|
||||
Selects the day after the current day in \l selectedDate.
|
||||
*/
|
||||
function __selectNextDay() {
|
||||
var newDate = new Date(calendar.selectedDate);
|
||||
newDate.setDate(newDate.getDate() + 1);
|
||||
calendar.selectedDate = newDate;
|
||||
}
|
||||
|
||||
Keys.onLeftPressed: {
|
||||
calendar.__selectPreviousDay();
|
||||
}
|
||||
|
||||
Keys.onUpPressed: {
|
||||
calendar.__selectPreviousWeek();
|
||||
}
|
||||
|
||||
Keys.onDownPressed: {
|
||||
calendar.__selectNextWeek();
|
||||
}
|
||||
|
||||
Keys.onRightPressed: {
|
||||
calendar.__selectNextDay();
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
if (event.key === Qt.Key_Home) {
|
||||
calendar.__selectFirstDayOfMonth();
|
||||
event.accepted = true;
|
||||
} else if (event.key === Qt.Key_End) {
|
||||
calendar.__selectLastDayOfMonth();
|
||||
event.accepted = true;
|
||||
} else if (event.key === Qt.Key_PageUp) {
|
||||
calendar.__selectPreviousMonth();
|
||||
event.accepted = true;
|
||||
} else if (event.key === Qt.Key_PageDown) {
|
||||
calendar.__selectNextMonth();
|
||||
event.accepted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype CheckBox
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup controls
|
||||
\brief A checkbox with a text label.
|
||||
|
||||
\image checkbox.png
|
||||
|
||||
A CheckBox is an option button that can be toggled on (checked) or off
|
||||
(unchecked). Checkboxes are typically used to represent features in an
|
||||
application that can be enabled or disabled without affecting others.
|
||||
|
||||
The state of the checkbox can be set with the \l {AbstractCheckable::checked}{checked} property.
|
||||
|
||||
In addition to the checked and unchecked states, there is a third state:
|
||||
partially checked. This state indicates that the
|
||||
regular checked/unchecked state can not be determined; generally because of
|
||||
other states that affect the checkbox. This state is useful when several
|
||||
child nodes are selected in a treeview, for example.
|
||||
|
||||
The partially checked state can be made available to the user by setting
|
||||
\l partiallyCheckedEnabled to \c true, or set directly by setting
|
||||
\l checkedState to \c Qt.PartiallyChecked. \l checkedState behaves
|
||||
identically to \l {AbstractCheckable::checked}{checked} when \l partiallyCheckedEnabled
|
||||
is \c false; setting one will appropriately set the other.
|
||||
|
||||
The label is shown next to the checkbox, and you can set the label text using its
|
||||
\l {AbstractCheckable::text}{text} property.
|
||||
|
||||
\qml
|
||||
Column {
|
||||
CheckBox {
|
||||
text: qsTr("Breakfast")
|
||||
checked: true
|
||||
}
|
||||
CheckBox {
|
||||
text: qsTr("Lunch")
|
||||
}
|
||||
CheckBox {
|
||||
text: qsTr("Dinner")
|
||||
checked: true
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
Whenever a CheckBox is clicked, it emits the \l {AbstractCheckable::clicked}{clicked()} signal.
|
||||
|
||||
You can create a custom appearance for a CheckBox by
|
||||
assigning a \l {CheckBoxStyle}.
|
||||
*/
|
||||
|
||||
AbstractCheckable {
|
||||
id: checkBox
|
||||
|
||||
/*!
|
||||
\qmlproperty enumeration CheckBox::checkedState
|
||||
|
||||
This property indicates the current checked state of the checkbox.
|
||||
|
||||
Possible values:
|
||||
\c Qt.UnChecked - The checkbox is not checked (default).
|
||||
\c Qt.Checked - The checkbox is checked.
|
||||
\c Qt.PartiallyChecked - The checkbox is in a partially checked (or
|
||||
"mixed") state.
|
||||
|
||||
The \l {AbstractCheckable::checked}{checked} property also determines whether
|
||||
this property is \c Qt.Checked or \c Qt.UnChecked, and vice versa.
|
||||
*/
|
||||
property int checkedState: checked ? Qt.Checked : Qt.Unchecked
|
||||
|
||||
/*!
|
||||
This property determines whether the \c Qt.PartiallyChecked state is
|
||||
available.
|
||||
|
||||
A checkbox may be in a partially checked state when the regular checked
|
||||
state can not be determined.
|
||||
|
||||
Setting \l checkedState to \c Qt.PartiallyChecked will implicitly set
|
||||
this property to \c true.
|
||||
|
||||
If this property is \c true, \l {AbstractCheckable::checked}{checked} will be \c false.
|
||||
|
||||
By default, this property is \c false.
|
||||
*/
|
||||
property bool partiallyCheckedEnabled: false
|
||||
|
||||
/*!
|
||||
\internal
|
||||
True if onCheckedChanged should be ignored because we were reacting
|
||||
to onCheckedStateChanged.
|
||||
*/
|
||||
property bool __ignoreChecked: false
|
||||
|
||||
/*!
|
||||
\internal
|
||||
True if onCheckedStateChanged should be ignored because we were reacting
|
||||
to onCheckedChanged.
|
||||
*/
|
||||
property bool __ignoreCheckedState: false
|
||||
|
||||
style: Settings.styleComponent(Settings.style, "CheckBoxStyle.qml", checkBox)
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
Accessible.role: Accessible.CheckBox
|
||||
Accessible.name: text
|
||||
|
||||
__cycleStatesHandler: __cycleCheckBoxStates
|
||||
|
||||
onCheckedChanged: {
|
||||
if (!__ignoreChecked) {
|
||||
__ignoreCheckedState = true;
|
||||
checkedState = checked ? Qt.Checked : Qt.Unchecked;
|
||||
__ignoreCheckedState = false;
|
||||
}
|
||||
}
|
||||
|
||||
onCheckedStateChanged: {
|
||||
__ignoreChecked = true;
|
||||
if (checkedState === Qt.PartiallyChecked) {
|
||||
partiallyCheckedEnabled = true;
|
||||
checked = false;
|
||||
} else if (!__ignoreCheckedState) {
|
||||
checked = checkedState === Qt.Checked;
|
||||
}
|
||||
__ignoreChecked = false;
|
||||
}
|
||||
|
||||
onPartiallyCheckedEnabledChanged: {
|
||||
if (exclusiveGroup && partiallyCheckedEnabled) {
|
||||
console.warn("Cannot have partially checked boxes in an ExclusiveGroup.");
|
||||
}
|
||||
}
|
||||
|
||||
onExclusiveGroupChanged: {
|
||||
if (exclusiveGroup && partiallyCheckedEnabled) {
|
||||
console.warn("Cannot have partially checked boxes in an ExclusiveGroup.");
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __cycleCheckBoxStates() {
|
||||
if (!partiallyCheckedEnabled) {
|
||||
checked = !checked;
|
||||
} else {
|
||||
switch (checkedState) {
|
||||
case Qt.Unchecked: checkedState = Qt.Checked; break;
|
||||
case Qt.Checked: checkedState = Qt.PartiallyChecked; break;
|
||||
case Qt.PartiallyChecked: checkedState = Qt.Unchecked; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,717 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQml 2.14 as Qml
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype ComboBox
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup controls
|
||||
\brief Provides a drop-down list functionality.
|
||||
|
||||
\image combobox.png
|
||||
|
||||
Add items to the ComboBox by assigning it a ListModel, or a list of strings
|
||||
to the \l model property.
|
||||
|
||||
\qml
|
||||
ComboBox {
|
||||
width: 200
|
||||
model: [ "Banana", "Apple", "Coconut" ]
|
||||
}
|
||||
\endqml
|
||||
|
||||
In this example we are demonstrating how to use a ListModel with a combo box.
|
||||
|
||||
\qml
|
||||
ComboBox {
|
||||
currentIndex: 2
|
||||
model: ListModel {
|
||||
id: cbItems
|
||||
ListElement { text: "Banana"; color: "Yellow" }
|
||||
ListElement { text: "Apple"; color: "Green" }
|
||||
ListElement { text: "Coconut"; color: "Brown" }
|
||||
}
|
||||
width: 200
|
||||
onCurrentIndexChanged: console.debug(cbItems.get(currentIndex).text + ", " + cbItems.get(currentIndex).color)
|
||||
}
|
||||
\endqml
|
||||
|
||||
You can make a combo box editable by setting the \l editable property. An editable combo box will
|
||||
autocomplete its text based on what is available in the model.
|
||||
|
||||
In the next example we demonstrate how you can append content to an editable combo box by
|
||||
reacting to the \l accepted signal. Note that you have to explicitly prevent duplicates.
|
||||
|
||||
\qml
|
||||
ComboBox {
|
||||
editable: true
|
||||
model: ListModel {
|
||||
id: model
|
||||
ListElement { text: "Banana"; color: "Yellow" }
|
||||
ListElement { text: "Apple"; color: "Green" }
|
||||
ListElement { text: "Coconut"; color: "Brown" }
|
||||
}
|
||||
onAccepted: {
|
||||
if (find(currentText) === -1) {
|
||||
model.append({text: editText})
|
||||
currentIndex = find(editText)
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
|
||||
You can create a custom appearance for a ComboBox by
|
||||
assigning a \l {ComboBoxStyle}.
|
||||
*/
|
||||
|
||||
Control {
|
||||
id: comboBox
|
||||
|
||||
/*! \qmlproperty model ComboBox::model
|
||||
The model to populate the ComboBox from.
|
||||
|
||||
Changing the model after initialization will reset \l currentIndex to \c 0.
|
||||
*/
|
||||
property alias model: popupItems.model
|
||||
|
||||
/*! The model role used for populating the ComboBox. */
|
||||
property string textRole: ""
|
||||
|
||||
/*! \qmlproperty int ComboBox::currentIndex
|
||||
The index of the currently selected item in the ComboBox.
|
||||
|
||||
Setting currentIndex to \c -1 will reset the selection and clear the text
|
||||
label. If \l editable is \c true, you may also need to manually clear \l editText.
|
||||
|
||||
\sa model
|
||||
*/
|
||||
property alias currentIndex: popup.__selectedIndex
|
||||
|
||||
/*! \qmlproperty string ComboBox::currentText
|
||||
The text of the currently selected item in the ComboBox.
|
||||
|
||||
\note Since \c currentText depends on \c currentIndex, there's no way to ensure \c currentText
|
||||
will be up to date whenever a \c onCurrentIndexChanged handler is called.
|
||||
*/
|
||||
readonly property alias currentText: popup.currentText
|
||||
|
||||
/*! This property holds whether the combo box can be edited by the user.
|
||||
The default value is \c false.
|
||||
\since QtQuick.Controls 1.1
|
||||
*/
|
||||
property bool editable: false
|
||||
|
||||
/*! \qmlproperty string ComboBox::editText
|
||||
\since QtQuick.Controls 1.1
|
||||
This property specifies text being manipulated by the user for an editable combo box.
|
||||
*/
|
||||
property alias editText: input.text
|
||||
|
||||
/*! \qmlproperty enumeration ComboBox::inputMethodHints
|
||||
\since QtQuick.Controls 1.5
|
||||
Provides hints to the input method about the expected content of the combo box and how it
|
||||
should operate.
|
||||
|
||||
The value is a bit-wise combination of flags or \c Qt.ImhNone if no hints are set.
|
||||
|
||||
Flags that alter behavior are:
|
||||
|
||||
\list
|
||||
\li Qt.ImhHiddenText - Characters should be hidden, as is typically used when entering passwords.
|
||||
\li Qt.ImhSensitiveData - Typed text should not be stored by the active input method
|
||||
in any persistent storage like predictive user dictionary.
|
||||
\li Qt.ImhNoAutoUppercase - The input method should not try to automatically switch to upper case
|
||||
when a sentence ends.
|
||||
\li Qt.ImhPreferNumbers - Numbers are preferred (but not required).
|
||||
\li Qt.ImhPreferUppercase - Upper case letters are preferred (but not required).
|
||||
\li Qt.ImhPreferLowercase - Lower case letters are preferred (but not required).
|
||||
\li Qt.ImhNoPredictiveText - Do not use predictive text (i.e. dictionary lookup) while typing.
|
||||
|
||||
\li Qt.ImhDate - The text editor functions as a date field.
|
||||
\li Qt.ImhTime - The text editor functions as a time field.
|
||||
\endlist
|
||||
|
||||
Flags that restrict input (exclusive flags) are:
|
||||
|
||||
\list
|
||||
\li Qt.ImhDigitsOnly - Only digits are allowed.
|
||||
\li Qt.ImhFormattedNumbersOnly - Only number input is allowed. This includes decimal point and minus sign.
|
||||
\li Qt.ImhUppercaseOnly - Only upper case letter input is allowed.
|
||||
\li Qt.ImhLowercaseOnly - Only lower case letter input is allowed.
|
||||
\li Qt.ImhDialableCharactersOnly - Only characters suitable for phone dialing are allowed.
|
||||
\li Qt.ImhEmailCharactersOnly - Only characters suitable for email addresses are allowed.
|
||||
\li Qt.ImhUrlCharactersOnly - Only characters suitable for URLs are allowed.
|
||||
\endlist
|
||||
|
||||
Masks:
|
||||
|
||||
\list
|
||||
\li Qt.ImhExclusiveInputMask - This mask yields nonzero if any of the exclusive flags are used.
|
||||
\endlist
|
||||
*/
|
||||
property alias inputMethodHints: input.inputMethodHints
|
||||
|
||||
/*! This property specifies whether the combobox should gain active focus when pressed.
|
||||
The default value is \c false. */
|
||||
property bool activeFocusOnPress: false
|
||||
|
||||
/*! \qmlproperty bool ComboBox::pressed
|
||||
|
||||
This property holds whether the button is being pressed. */
|
||||
readonly property bool pressed: mouseArea.effectivePressed || popup.__popupVisible
|
||||
|
||||
/*! \qmlproperty bool ComboBox::hovered
|
||||
|
||||
This property indicates whether the control is being hovered.
|
||||
*/
|
||||
readonly property bool hovered: mouseArea.containsMouse || input.containsMouse
|
||||
|
||||
/*! \qmlproperty int ComboBox::count
|
||||
\since QtQuick.Controls 1.1
|
||||
This property holds the number of items in the combo box.
|
||||
*/
|
||||
readonly property alias count: popupItems.count
|
||||
|
||||
/*! \qmlmethod string ComboBox::textAt(int index)
|
||||
Returns the text for a given \a index.
|
||||
If an invalid index is provided, \c null is returned
|
||||
\since QtQuick.Controls 1.1
|
||||
*/
|
||||
function textAt (index) {
|
||||
if (index >= count || index < 0)
|
||||
return null;
|
||||
return popupItems.objectAt(index).text;
|
||||
}
|
||||
|
||||
/*! \qmlmethod int ComboBox::find(string text)
|
||||
Finds and returns the index of a given \a text
|
||||
If no match is found, \c -1 is returned. The search is case sensitive.
|
||||
\since QtQuick.Controls 1.1
|
||||
*/
|
||||
function find (text) {
|
||||
return input.find(text, Qt.MatchExactly)
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty Validator ComboBox::validator
|
||||
\since QtQuick.Controls 1.1
|
||||
|
||||
Allows you to set a text validator for an editable ComboBox.
|
||||
When a validator is set,
|
||||
the text field will only accept input which leaves the text property in
|
||||
an intermediate state. The accepted signal will only be sent
|
||||
if the text is in an acceptable state when enter is pressed.
|
||||
|
||||
Currently supported validators are \l[QtQuick]{IntValidator},
|
||||
\l[QtQuick]{DoubleValidator}, and \l[QtQuick]{RegExpValidator}. An
|
||||
example of using validators is shown below, which allows input of
|
||||
integers between 11 and 31 into the text field:
|
||||
|
||||
\note This property is only applied when \l editable is \c true
|
||||
|
||||
\qml
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
|
||||
ComboBox {
|
||||
editable: true
|
||||
model: 10
|
||||
validator: IntValidator {bottom: 0; top: 10;}
|
||||
focus: true
|
||||
}
|
||||
\endqml
|
||||
|
||||
\sa acceptableInput, accepted, editable
|
||||
*/
|
||||
property alias validator: input.validator
|
||||
|
||||
/*!
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
This property contains the edit \l Menu for working
|
||||
with text selection. Set it to \c null if no menu
|
||||
is wanted.
|
||||
|
||||
\note The menu is only in use when \l editable is \c true
|
||||
*/
|
||||
property Component menu: input.editMenu.defaultMenu
|
||||
|
||||
/*!
|
||||
\qmlproperty bool ComboBox::acceptableInput
|
||||
\since QtQuick.Controls 1.1
|
||||
|
||||
Returns \c true if the combo box contains acceptable
|
||||
text in the editable text field.
|
||||
|
||||
If a validator was set, this property will return \c
|
||||
true if the current text satisfies the validator or mask as
|
||||
a final string (not as an intermediate string).
|
||||
|
||||
\sa validator, accepted
|
||||
|
||||
*/
|
||||
readonly property alias acceptableInput: input.acceptableInput
|
||||
|
||||
/*!
|
||||
\qmlproperty bool ComboBox::selectByMouse
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
This property determines if the user can select the text in
|
||||
the editable text field with the mouse.
|
||||
|
||||
The default value is \c true.
|
||||
*/
|
||||
property bool selectByMouse: true
|
||||
|
||||
/*!
|
||||
\qmlproperty bool ComboBox::inputMethodComposing
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
This property holds whether an editable ComboBox has partial text input from an input method.
|
||||
|
||||
While it is composing an input method may rely on mouse or key events from the ComboBox
|
||||
to edit or commit the partial text. This property can be used to determine when to disable
|
||||
events handlers that may interfere with the correct operation of an input method.
|
||||
*/
|
||||
readonly property bool inputMethodComposing: !!input.inputMethodComposing
|
||||
|
||||
/*!
|
||||
\qmlsignal ComboBox::accepted()
|
||||
\since QtQuick.Controls 1.1
|
||||
|
||||
This signal is emitted when the Return or Enter key is pressed on an
|
||||
\l editable combo box. If the confirmed string is not currently in the model,
|
||||
the currentIndex will be set to -1 and the \l currentText will be updated
|
||||
accordingly.
|
||||
|
||||
\note If there is a \l validator set on the combobox,
|
||||
the signal will only be emitted if the input is in an acceptable state.
|
||||
|
||||
The corresponding handler is \c onAccepted.
|
||||
*/
|
||||
signal accepted
|
||||
|
||||
/*!
|
||||
\qmlsignal ComboBox::activated(int index)
|
||||
\since QtQuick.Controls 1.1
|
||||
|
||||
This signal is similar to currentIndex changed, but will only
|
||||
be emitted if the combo box index was changed by the user, not
|
||||
when set programmatically.
|
||||
|
||||
\e index is the activated model index, or \c -1 if a new string is
|
||||
accepted.
|
||||
|
||||
The corresponding handler is \c onActivated.
|
||||
*/
|
||||
signal activated(int index)
|
||||
|
||||
/*!
|
||||
\qmlmethod void ComboBox::selectAll()
|
||||
\since QtQuick.Controls 1.1
|
||||
|
||||
Causes all \l editText to be selected.
|
||||
*/
|
||||
function selectAll() {
|
||||
input.selectAll()
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __selectPrevItem() {
|
||||
input.blockUpdate = true
|
||||
if (currentIndex > 0) {
|
||||
currentIndex--;
|
||||
input.text = popup.currentText;
|
||||
activated(currentIndex);
|
||||
}
|
||||
input.blockUpdate = false;
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __selectNextItem() {
|
||||
input.blockUpdate = true;
|
||||
if (currentIndex < popupItems.count - 1) {
|
||||
currentIndex++;
|
||||
input.text = popup.currentText;
|
||||
activated(currentIndex);
|
||||
}
|
||||
input.blockUpdate = false;
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property var __popup: popup
|
||||
|
||||
style: Settings.styleComponent(Settings.style, "ComboBoxStyle.qml", comboBox)
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
Accessible.name: editable ? editText : currentText
|
||||
Accessible.role: Accessible.ComboBox
|
||||
Accessible.editable: editable
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
property bool overridePressed: false
|
||||
readonly property bool effectivePressed: (pressed || overridePressed) && containsMouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
onPressed: {
|
||||
if (comboBox.activeFocusOnPress)
|
||||
forceActiveFocus()
|
||||
if (!Settings.hasTouchScreen)
|
||||
popup.toggleShow()
|
||||
else
|
||||
overridePressed = true
|
||||
}
|
||||
onCanceled: overridePressed = false
|
||||
onClicked: {
|
||||
if (Settings.hasTouchScreen)
|
||||
popup.toggleShow()
|
||||
overridePressed = false
|
||||
}
|
||||
onWheel: {
|
||||
if (wheel.angleDelta.y > 0) {
|
||||
__selectPrevItem();
|
||||
} else if (wheel.angleDelta.y < 0){
|
||||
__selectNextItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (currentIndex === -1)
|
||||
currentIndex = 0
|
||||
|
||||
popup.ready = true
|
||||
popup.resolveTextValue(textRole)
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
// Perform one-character based lookup for non-editable combo box
|
||||
if (!editable && event.text.length > 0) {
|
||||
var index = input.find(event.text, Qt.MatchStartsWith);
|
||||
if (index >= 0 && index !== currentIndex) {
|
||||
currentIndex = index;
|
||||
activated(currentIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextInputWithHandles {
|
||||
id: input
|
||||
|
||||
visible: editable
|
||||
enabled: editable
|
||||
focus: true
|
||||
clip: contentWidth > width
|
||||
|
||||
control: comboBox
|
||||
cursorHandle: __style ? __style.__cursorHandle : undefined
|
||||
selectionHandle: __style ? __style.__selectionHandle : undefined
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: __style ? __style.padding.left : 0
|
||||
anchors.topMargin: __style ? __style.padding.top : 0
|
||||
anchors.rightMargin: __style ? __panel.dropDownButtonWidth + __style.padding.right : 0
|
||||
anchors.bottomMargin: __style ? __style.padding.bottom: 0
|
||||
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
font: __panel && __panel.font !== undefined ? __panel.font : TextSingleton.font
|
||||
renderType: __style ? __style.renderType : Text.NativeRendering
|
||||
color: __panel ? __panel.textColor : "black"
|
||||
selectionColor: __panel ? __panel.selectionColor : "blue"
|
||||
selectedTextColor: __panel ? __panel.selectedTextColor : "white"
|
||||
onAccepted: {
|
||||
var idx = input.find(editText, Qt.MatchFixedString)
|
||||
if (idx > -1) {
|
||||
editTextMatches = true;
|
||||
currentIndex = idx;
|
||||
editText = textAt(idx);
|
||||
} else {
|
||||
editTextMatches = false;
|
||||
currentIndex = -1;
|
||||
popup.currentText = editText;
|
||||
}
|
||||
comboBox.accepted();
|
||||
}
|
||||
|
||||
property bool blockUpdate: false
|
||||
property string prevText
|
||||
property bool editTextMatches: true
|
||||
|
||||
function find (text, searchType) {
|
||||
for (var i = 0 ; i < popupItems.count ; ++i) {
|
||||
var currentString = popupItems.objectAt(i).text
|
||||
if (searchType === Qt.MatchExactly) {
|
||||
if (text === currentString)
|
||||
return i;
|
||||
} else if (searchType === Qt.CaseSensitive) {
|
||||
if (currentString.indexOf(text) === 0)
|
||||
return i;
|
||||
} else if (searchType === Qt.MatchFixedString) {
|
||||
if (currentString.toLowerCase().indexOf(text.toLowerCase()) === 0
|
||||
&& currentString.length === text.length)
|
||||
return i;
|
||||
} else if (currentString.toLowerCase().indexOf(text.toLowerCase()) === 0) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Finds first entry and shortest entry. Used by editable combo
|
||||
function tryComplete (inputText) {
|
||||
var candidate = "";
|
||||
var shortestString = "";
|
||||
for (var i = 0 ; i < popupItems.count ; ++i) {
|
||||
var currentString = popupItems.objectAt(i).text;
|
||||
|
||||
if (currentString.toLowerCase().indexOf(inputText.toLowerCase()) === 0) {
|
||||
if (candidate.length) { // Find smallest possible match
|
||||
var cmp = 0;
|
||||
|
||||
// We try to complete the shortest string that matches our search
|
||||
if (currentString.length < candidate.length)
|
||||
candidate = currentString
|
||||
|
||||
while (cmp < Math.min(currentString.length, shortestString.length)
|
||||
&& shortestString[cmp].toLowerCase() === currentString[cmp].toLowerCase())
|
||||
cmp++;
|
||||
shortestString = shortestString.substring(0, cmp);
|
||||
} else { // First match, select as current index and find other matches
|
||||
candidate = currentString;
|
||||
shortestString = currentString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (candidate.length)
|
||||
return inputText + candidate.substring(inputText.length, candidate.length);
|
||||
return inputText;
|
||||
}
|
||||
|
||||
property bool allowComplete: false
|
||||
Keys.forwardTo: comboBox
|
||||
Keys.onPressed: allowComplete = (event.key !== Qt.Key_Backspace && event.key !== Qt.Key_Delete);
|
||||
|
||||
onTextChanged: {
|
||||
if (editable && !blockUpdate && allowComplete && text.length > 0) {
|
||||
var completed = input.tryComplete(text)
|
||||
if (completed.length > text.length) {
|
||||
var oldtext = input.text;
|
||||
input.text = completed;
|
||||
input.select(text.length, oldtext.length);
|
||||
}
|
||||
}
|
||||
prevText = text
|
||||
}
|
||||
}
|
||||
|
||||
Qml.Binding {
|
||||
target: input
|
||||
property: "text"
|
||||
value: popup.currentText
|
||||
when: input.editTextMatches
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
onTextRoleChanged: popup.resolveTextValue(textRole)
|
||||
|
||||
ExclusiveGroup { id: eg }
|
||||
|
||||
Menu {
|
||||
id: popup
|
||||
objectName: "popup"
|
||||
|
||||
style: isPopup ? __style.__popupStyle : __style.__dropDownStyle
|
||||
|
||||
property string currentText: selectedText
|
||||
onSelectedTextChanged: popup.currentText = selectedText
|
||||
|
||||
property string selectedText
|
||||
property int triggeredIndex: -1
|
||||
on__SelectedIndexChanged: {
|
||||
if (__selectedIndex === -1)
|
||||
popup.currentText = ""
|
||||
else
|
||||
updateSelectedText()
|
||||
if (triggeredIndex >= 0 && triggeredIndex == __selectedIndex) {
|
||||
activated(currentIndex)
|
||||
triggeredIndex = -1
|
||||
}
|
||||
}
|
||||
property string textRole: ""
|
||||
|
||||
property bool ready: false
|
||||
property bool isPopup: !editable && !!__panel && __panel.popup
|
||||
|
||||
property int y: isPopup ? (comboBox.__panel.height - comboBox.__panel.implicitHeight) / 2.0 : comboBox.__panel.height
|
||||
__minimumWidth: comboBox.width
|
||||
__visualItem: comboBox
|
||||
|
||||
property bool modelIsArray: false
|
||||
|
||||
Instantiator {
|
||||
id: popupItems
|
||||
active: false
|
||||
|
||||
property bool updatingModel: false
|
||||
onModelChanged: {
|
||||
popup.modelIsArray = !!model ? model.constructor === Array : false
|
||||
if (active) {
|
||||
if (updatingModel && popup.__selectedIndex === 0) {
|
||||
// We still want to update the currentText
|
||||
popup.updateSelectedText()
|
||||
} else {
|
||||
updatingModel = true
|
||||
popup.__selectedIndex = 0
|
||||
}
|
||||
}
|
||||
popup.resolveTextValue(comboBox.textRole)
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: popup.textRole === '' ?
|
||||
modelData :
|
||||
((popup.modelIsArray ? modelData[popup.textRole] : model[popup.textRole]) || '')
|
||||
onTriggered: {
|
||||
popup.triggeredIndex = index
|
||||
comboBox.editText = text
|
||||
}
|
||||
onTextChanged: if (index === currentIndex) popup.updateSelectedText();
|
||||
checkable: true
|
||||
exclusiveGroup: eg
|
||||
}
|
||||
onObjectAdded: {
|
||||
popup.insertItem(index, object)
|
||||
if (!updatingModel && index === popup.__selectedIndex)
|
||||
popup.selectedText = object["text"]
|
||||
}
|
||||
onObjectRemoved: popup.removeItem(object)
|
||||
|
||||
}
|
||||
|
||||
function resolveTextValue(initialTextRole) {
|
||||
if (!ready || !model) {
|
||||
popupItems.active = false
|
||||
return;
|
||||
}
|
||||
|
||||
var get = model['get'];
|
||||
if (!get && popup.modelIsArray && !!model[0]) {
|
||||
if (model[0].constructor !== String && model[0].constructor !== Number)
|
||||
get = function(i) { return model[i]; }
|
||||
}
|
||||
|
||||
var modelMayHaveRoles = get !== undefined
|
||||
textRole = initialTextRole
|
||||
if (textRole === "" && modelMayHaveRoles && get(0)) {
|
||||
// No text role set, check whether model has a suitable role
|
||||
// If 'text' is found, or there's only one role, pick that.
|
||||
var listElement = get(0)
|
||||
var roleName = ""
|
||||
var roleCount = 0
|
||||
for (var role in listElement) {
|
||||
if (listElement[role].constructor === Function)
|
||||
continue;
|
||||
if (role === "text") {
|
||||
roleName = role
|
||||
break
|
||||
} else if (!roleName) {
|
||||
roleName = role
|
||||
}
|
||||
++roleCount
|
||||
}
|
||||
if (roleCount > 1 && roleName !== "text") {
|
||||
console.warn("No suitable 'textRole' found for ComboBox.")
|
||||
} else {
|
||||
textRole = roleName
|
||||
}
|
||||
}
|
||||
|
||||
if (!popupItems.active)
|
||||
popupItems.active = true
|
||||
else
|
||||
updateSelectedText()
|
||||
}
|
||||
|
||||
function toggleShow() {
|
||||
if (popup.__popupVisible) {
|
||||
popup.__dismissAndDestroy()
|
||||
} else {
|
||||
if (items[__selectedIndex])
|
||||
items[__selectedIndex].checked = true
|
||||
__currentIndex = comboBox.currentIndex
|
||||
if (Qt.application.layoutDirection === Qt.RightToLeft)
|
||||
__popup(Qt.rect(comboBox.width, y, 0, 0), isPopup ? __selectedIndex : 0)
|
||||
else
|
||||
__popup(Qt.rect(0, y, 0, 0), isPopup ? __selectedIndex : 0)
|
||||
}
|
||||
}
|
||||
|
||||
function updateSelectedText() {
|
||||
var selectedItem;
|
||||
if (__selectedIndex !== -1 && (selectedItem = items[__selectedIndex])) {
|
||||
input.editTextMatches = true
|
||||
selectedText = Qt.binding(function () { return selectedItem.text })
|
||||
if (currentText !== selectedText) // __selectedIndex went form -1 to 0
|
||||
selectedTextChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The key bindings below will only be in use when popup is
|
||||
// not visible. Otherwise, native popup key handling will take place:
|
||||
Keys.onSpacePressed: {
|
||||
if (!editable)
|
||||
popup.toggleShow()
|
||||
else
|
||||
event.accepted = false
|
||||
}
|
||||
|
||||
Keys.onUpPressed: __selectPrevItem()
|
||||
Keys.onDownPressed: __selectNextItem()
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
import QtQuick.Layouts 1.0
|
||||
|
||||
/*!
|
||||
\qmltype GroupBox
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup controls
|
||||
\brief GroupBox provides a group box frame with a title.
|
||||
|
||||
\image groupbox.png
|
||||
|
||||
A group box provides a frame, a title on top and displays various other controls inside itself. Group boxes can also be checkable.
|
||||
|
||||
Child controls in checkable group boxes are enabled or disabled depending on whether or not the group box is checked.
|
||||
|
||||
You can minimize the space consumption of a group box by enabling the flat property.
|
||||
In most styles, enabling this property results in the removal of the left, right and bottom edges of the frame.
|
||||
|
||||
To add content to a group box, you can reparent it to its contentItem property.
|
||||
|
||||
The implicit size of the GroupBox is calculated based on the size of its content. If you want to anchor
|
||||
items inside the group box, you must specify an explicit width and height on the GroupBox itself.
|
||||
|
||||
The following example shows how we use a GroupBox:
|
||||
|
||||
\qml
|
||||
GroupBox {
|
||||
title: "Joining for?"
|
||||
|
||||
Column {
|
||||
spacing: 10
|
||||
|
||||
CheckBox {
|
||||
text: "Breakfast"
|
||||
checked: true
|
||||
}
|
||||
CheckBox {
|
||||
text: "Lunch"
|
||||
checked: false
|
||||
}
|
||||
CheckBox {
|
||||
text: "Dinner"
|
||||
checked: true
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
\sa CheckBox, RadioButton, Layout
|
||||
|
||||
*/
|
||||
|
||||
FocusScope {
|
||||
id: groupbox
|
||||
|
||||
/*!
|
||||
This property holds the group box title text.
|
||||
|
||||
There is no default title text.
|
||||
*/
|
||||
property string title
|
||||
|
||||
/*!
|
||||
This property holds whether the group box is painted flat or has a frame.
|
||||
|
||||
A group box usually consists of a surrounding frame with a title at the top.
|
||||
If this property is enabled, only the top part of the frame is drawn in most styles;
|
||||
otherwise, the whole frame is drawn.
|
||||
|
||||
By default, this property is disabled, so group boxes are not flat unless explicitly specified.
|
||||
|
||||
\note In some styles, flat and non-flat group boxes have similar representations and may not be as
|
||||
distinguishable as they are in other styles.
|
||||
*/
|
||||
property bool flat: false
|
||||
|
||||
/*!
|
||||
This property holds whether the group box has a checkbox in its title.
|
||||
|
||||
If this property is true, the group box displays its title using a checkbox in place of an ordinary label.
|
||||
If the checkbox is checked, the group box's children are enabled; otherwise, they are disabled and inaccessible.
|
||||
|
||||
By default, group boxes are not checkable.
|
||||
*/
|
||||
property bool checkable: false
|
||||
|
||||
/*!
|
||||
\qmlproperty bool GroupBox::checked
|
||||
|
||||
This property holds whether the group box is checked.
|
||||
|
||||
If the group box is checkable, it is displayed with a check box. If the check box is checked, the group
|
||||
box's children are enabled; otherwise, the children are disabled and are inaccessible to the user.
|
||||
|
||||
By default, checkable group boxes are also checked.
|
||||
*/
|
||||
property alias checked: check.checked
|
||||
|
||||
|
||||
/*! \internal */
|
||||
default property alias __content: container.data
|
||||
|
||||
/*!
|
||||
\qmlproperty Item GroupBox::contentItem
|
||||
|
||||
This property holds the content Item of the group box.
|
||||
|
||||
Items declared as children of a GroupBox are automatically parented to the GroupBox's contentItem.
|
||||
Items created dynamically need to be explicitly parented to the contentItem:
|
||||
|
||||
\note The implicit size of the GroupBox is calculated based on the size of its content. If you want to anchor
|
||||
items inside the group box, you must specify an explicit width and height on the GroupBox itself.
|
||||
*/
|
||||
readonly property alias contentItem: container
|
||||
|
||||
/*! \internal */
|
||||
property Component style: Settings.styleComponent(Settings.style, "GroupBoxStyle.qml", groupbox)
|
||||
|
||||
/*! \internal */
|
||||
property alias __checkbox: check
|
||||
|
||||
/*! \internal */
|
||||
property alias __style: styleLoader.item
|
||||
|
||||
implicitWidth: Math.max((!anchors.fill ? container.calcWidth() : 0) + loader.leftMargin + loader.rightMargin,
|
||||
sizeHint.implicitWidth + (checkable ? 24 : 6))
|
||||
implicitHeight: (!anchors.fill ? container.calcHeight() : 0) + loader.topMargin + loader.bottomMargin
|
||||
|
||||
Layout.minimumWidth: implicitWidth
|
||||
Layout.minimumHeight: implicitHeight
|
||||
|
||||
Accessible.role: Accessible.Grouping
|
||||
Accessible.name: title
|
||||
|
||||
activeFocusOnTab: false
|
||||
|
||||
|
||||
data: [
|
||||
Loader {
|
||||
id: loader
|
||||
anchors.fill: parent
|
||||
property int topMargin: __style ? __style.padding.top : 0
|
||||
property int bottomMargin: __style ? __style.padding.bottom : 0
|
||||
property int leftMargin: __style ? __style.padding.left : 0
|
||||
property int rightMargin: __style ? __style.padding.right : 0
|
||||
sourceComponent: styleLoader.item ? styleLoader.item.panel : null
|
||||
onLoaded: item.z = -1
|
||||
Text { id: sizeHint ; visible: false ; text: title }
|
||||
Loader {
|
||||
id: styleLoader
|
||||
property alias __control: groupbox
|
||||
sourceComponent: groupbox.style
|
||||
}
|
||||
},
|
||||
CheckBox {
|
||||
id: check
|
||||
objectName: "check"
|
||||
checked: true
|
||||
text: groupbox.title
|
||||
visible: checkable
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: loader.topMargin
|
||||
activeFocusOnTab: groupbox.checkable
|
||||
style: CheckBoxStyle { panel: Item{} }
|
||||
},
|
||||
Item {
|
||||
id: container
|
||||
objectName: "container"
|
||||
z: 1
|
||||
focus: true
|
||||
anchors.fill: parent
|
||||
|
||||
anchors.topMargin: loader.topMargin
|
||||
anchors.leftMargin: loader.leftMargin
|
||||
anchors.rightMargin: loader.rightMargin
|
||||
anchors.bottomMargin: loader.bottomMargin
|
||||
enabled: (!groupbox.checkable || groupbox.checked)
|
||||
|
||||
property Item layoutItem: container.children.length === 1 ? container.children[0] : null
|
||||
function calcWidth () { return (layoutItem ? (layoutItem.implicitWidth || layoutItem.width) +
|
||||
(layoutItem.anchors.fill ? layoutItem.anchors.leftMargin +
|
||||
layoutItem.anchors.rightMargin : 0) : container.childrenRect.width) }
|
||||
function calcHeight () { return (layoutItem ? (layoutItem.implicitHeight || layoutItem.height) +
|
||||
(layoutItem.anchors.fill ? layoutItem.anchors.topMargin +
|
||||
layoutItem.anchors.bottomMargin : 0) : container.childrenRect.height) }
|
||||
}]
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype Label
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup controls
|
||||
\brief A text label.
|
||||
|
||||
\image label.png
|
||||
|
||||
In addition to the normal \l Text type, Label follows the font and
|
||||
color scheme of the system.
|
||||
Use the \c text property to assign a text to the label. For other properties
|
||||
check \l Text.
|
||||
|
||||
A simple label looks like this:
|
||||
\qml
|
||||
Label {
|
||||
text: "Hello world"
|
||||
}
|
||||
\endqml
|
||||
|
||||
You can use the properties of \l Text to change the appearance
|
||||
of the text as desired:
|
||||
\qml
|
||||
Label {
|
||||
text: "Hello world"
|
||||
font.pixelSize: 22
|
||||
font.italic: true
|
||||
color: "steelblue"
|
||||
}
|
||||
\endqml
|
||||
|
||||
\sa Text, TextField, TextEdit
|
||||
*/
|
||||
|
||||
Text {
|
||||
/*!
|
||||
\qmlproperty string Label::text
|
||||
|
||||
The text to display. Use this property to get and set it.
|
||||
*/
|
||||
|
||||
id: label
|
||||
color: SystemPaletteSingleton.windowText(enabled)
|
||||
activeFocusOnTab: false
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
Accessible.name: text
|
||||
Accessible.role: Accessible.StaticText
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype Menu
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup menus
|
||||
\ingroup controls
|
||||
\brief Provides a menu component for use as a context menu, popup menu, or
|
||||
as part of a menu bar.
|
||||
|
||||
\image menu.png
|
||||
|
||||
\code
|
||||
Menu {
|
||||
title: "Edit"
|
||||
|
||||
MenuItem {
|
||||
text: "Cut"
|
||||
shortcut: "Ctrl+X"
|
||||
onTriggered: ...
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: "Copy"
|
||||
shortcut: "Ctrl+C"
|
||||
onTriggered: ...
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: "Paste"
|
||||
shortcut: "Ctrl+V"
|
||||
onTriggered: ...
|
||||
}
|
||||
|
||||
MenuSeparator { }
|
||||
|
||||
Menu {
|
||||
title: "More Stuff"
|
||||
|
||||
MenuItem {
|
||||
text: "Do Nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
The main uses for menus:
|
||||
\list
|
||||
\li
|
||||
as a \e top-level menu in a \l MenuBar
|
||||
\li
|
||||
as a \e submenu inside another menu
|
||||
\li
|
||||
as a standalone or \e context menu
|
||||
\endlist
|
||||
|
||||
Note that some properties, such as \c enabled, \c text, or \c iconSource,
|
||||
only make sense in a particular use case of the menu.
|
||||
|
||||
\sa MenuBar, MenuItem, MenuSeparator
|
||||
*/
|
||||
|
||||
MenuPrivate {
|
||||
id: root
|
||||
|
||||
/*! \internal
|
||||
\omit
|
||||
Documented in qqquickmenu.cpp.
|
||||
\endomit
|
||||
*/
|
||||
function addMenu(title) {
|
||||
return root.insertMenu(items.length, title)
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
\omit
|
||||
Documented in qquickmenu.cpp.
|
||||
\endomit
|
||||
*/
|
||||
function insertMenu(index, title) {
|
||||
if (!__selfComponent)
|
||||
__selfComponent = Qt.createComponent("Menu.qml", root)
|
||||
var submenu = __selfComponent.createObject(__selfComponent, { "title": title })
|
||||
root.insertItem(index, submenu)
|
||||
return submenu
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component __selfComponent: null
|
||||
|
||||
/*! \qmlproperty Component Menu::style
|
||||
\since QtQuick.Controls.Styles 1.2
|
||||
|
||||
The style Component for this control.
|
||||
\sa {MenuStyle}
|
||||
|
||||
*/
|
||||
property Component style
|
||||
|
||||
Component.onCompleted: {
|
||||
if (!style) {
|
||||
__usingDefaultStyle = true
|
||||
style = Qt.binding(function() { return Settings.styleComponent(Settings.style, "MenuStyle.qml", root) })
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property bool __usingDefaultStyle: false
|
||||
/*! \internal */
|
||||
property var __parentContentItem: __parentMenu ? __parentMenu.__contentItem : null
|
||||
/*! \internal */
|
||||
property int __currentIndex: -1
|
||||
/*! \internal */
|
||||
onAboutToHide: __currentIndex = -1
|
||||
on__MenuPopupDestroyed: contentLoader.active = false
|
||||
onPopupVisibleChanged: {
|
||||
if (__popupVisible)
|
||||
contentLoader.active = true
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
__contentItem: Loader {
|
||||
id: contentLoader
|
||||
Component {
|
||||
id: menuContent
|
||||
MenuContentItem {
|
||||
__menu: root
|
||||
}
|
||||
}
|
||||
|
||||
sourceComponent: root.__isNative ? null : menuContent
|
||||
active: false
|
||||
focus: true
|
||||
Keys.forwardTo: item ? [item, root.__parentContentItem] : []
|
||||
property bool altPressed: root.__parentContentItem ? root.__parentContentItem.altPressed : false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQml 2.14 as Qml
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype MenuBar
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup applicationwindow
|
||||
\ingroup controls
|
||||
\brief Provides a horizontal menu bar.
|
||||
|
||||
\image menubar.png
|
||||
|
||||
MenuBar can be added to an \l ApplicationWindow, providing menu options
|
||||
to access additional functionality of the application.
|
||||
|
||||
\code
|
||||
ApplicationWindow {
|
||||
...
|
||||
menuBar: MenuBar {
|
||||
Menu {
|
||||
title: "File"
|
||||
MenuItem { text: "Open..." }
|
||||
MenuItem { text: "Close" }
|
||||
}
|
||||
|
||||
Menu {
|
||||
title: "Edit"
|
||||
MenuItem { text: "Cut" }
|
||||
MenuItem { text: "Copy" }
|
||||
MenuItem { text: "Paste" }
|
||||
}
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
\sa ApplicationWindow::menuBar
|
||||
*/
|
||||
|
||||
MenuBarPrivate {
|
||||
id: root
|
||||
|
||||
/*! \qmlproperty Component MenuBar::style
|
||||
\since QtQuick.Controls.Styles 1.2
|
||||
|
||||
The style Component for this control.
|
||||
\sa {MenuBarStyle}
|
||||
|
||||
*/
|
||||
property Component style: Settings.styleComponent(Settings.style, "MenuBarStyle.qml", root)
|
||||
|
||||
/*! \internal */
|
||||
property QtObject __style: styleLoader.item
|
||||
|
||||
__isNative: !__style.hasOwnProperty("__isNative") || __style.__isNative
|
||||
|
||||
/*! \internal */
|
||||
__contentItem: Loader {
|
||||
id: topLoader
|
||||
sourceComponent: __menuBarComponent
|
||||
active: !root.__isNative
|
||||
focus: true
|
||||
Keys.forwardTo: [item]
|
||||
property real preferredWidth: parent && active ? parent.width : 0
|
||||
property bool altPressed: item ? item.__altPressed : false
|
||||
|
||||
Loader {
|
||||
id: styleLoader
|
||||
property alias __control: topLoader.item
|
||||
sourceComponent: root.style
|
||||
onStatusChanged: {
|
||||
if (status === Loader.Error)
|
||||
console.error("Failed to load Style for", root)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component __menuBarComponent: Loader {
|
||||
id: menuBarLoader
|
||||
|
||||
Accessible.role: Accessible.MenuBar
|
||||
|
||||
onStatusChanged: if (status === Loader.Error) console.error("Failed to load panel for", root)
|
||||
|
||||
visible: status === Loader.Ready
|
||||
sourceComponent: d.style ? d.style.background : undefined
|
||||
|
||||
width: implicitWidth || root.__contentItem.preferredWidth
|
||||
height: Math.max(row.height + d.heightPadding, item ? item.implicitHeight : 0)
|
||||
|
||||
Qml.Binding {
|
||||
// Make sure the styled menu bar is in the background
|
||||
target: menuBarLoader.item
|
||||
property: "z"
|
||||
value: menuMouseArea.z - 1
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property Style style: __style
|
||||
|
||||
property int openedMenuIndex: -1
|
||||
property bool preselectMenuItem: false
|
||||
property real heightPadding: style ? style.padding.top + style.padding.bottom : 0
|
||||
|
||||
property bool altPressed: false
|
||||
property bool altPressedAgain: false
|
||||
property var mnemonicsMap: ({})
|
||||
|
||||
function openMenuAtIndex(index) {
|
||||
if (openedMenuIndex === index)
|
||||
return;
|
||||
|
||||
var oldIndex = openedMenuIndex
|
||||
openedMenuIndex = index
|
||||
|
||||
if (oldIndex !== -1) {
|
||||
var menu = root.menus[oldIndex]
|
||||
if (menu.__popupVisible)
|
||||
menu.__dismissAndDestroy()
|
||||
}
|
||||
|
||||
if (openedMenuIndex !== -1) {
|
||||
menu = root.menus[openedMenuIndex]
|
||||
if (menu.enabled) {
|
||||
if (menu.__usingDefaultStyle)
|
||||
menu.style = d.style.menuStyle
|
||||
|
||||
var xPos = row.LayoutMirroring.enabled ? menuItemLoader.width : 0
|
||||
menu.__popup(Qt.rect(xPos, menuBarLoader.height - d.heightPadding, 0, 0), 0)
|
||||
|
||||
if (preselectMenuItem)
|
||||
menu.__currentIndex = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function dismissActiveFocus(event, reason) {
|
||||
if (reason) {
|
||||
altPressedAgain = false
|
||||
altPressed = false
|
||||
openMenuAtIndex(-1)
|
||||
root.__contentItem.parent.forceActiveFocus()
|
||||
} else {
|
||||
event.accepted = false
|
||||
}
|
||||
}
|
||||
|
||||
function maybeOpenFirstMenu(event) {
|
||||
if (altPressed && openedMenuIndex === -1) {
|
||||
preselectMenuItem = true
|
||||
openMenuAtIndex(0)
|
||||
} else {
|
||||
event.accepted = false
|
||||
}
|
||||
}
|
||||
}
|
||||
property alias __altPressed: d.altPressed // Needed for the menu contents
|
||||
|
||||
focus: true
|
||||
|
||||
Keys.onPressed: {
|
||||
var action = null
|
||||
if (event.key === Qt.Key_Alt) {
|
||||
if (!d.altPressed)
|
||||
d.altPressed = true
|
||||
else
|
||||
d.altPressedAgain = true
|
||||
} else if (d.altPressed && (action = d.mnemonicsMap[event.text.toUpperCase()])) {
|
||||
d.preselectMenuItem = true
|
||||
action.trigger()
|
||||
event.accepted = true
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onReleased: d.dismissActiveFocus(event, d.altPressedAgain && d.openedMenuIndex === -1)
|
||||
Keys.onEscapePressed: d.dismissActiveFocus(event, d.openedMenuIndex === -1)
|
||||
|
||||
Keys.onUpPressed: d.maybeOpenFirstMenu(event)
|
||||
Keys.onDownPressed: d.maybeOpenFirstMenu(event)
|
||||
|
||||
Keys.onLeftPressed: {
|
||||
if (d.openedMenuIndex > 0) {
|
||||
var idx = d.openedMenuIndex - 1
|
||||
while (idx >= 0 && !(root.menus[idx].enabled && root.menus[idx].visible))
|
||||
idx--
|
||||
if (idx >= 0) {
|
||||
d.preselectMenuItem = true
|
||||
d.openMenuAtIndex(idx)
|
||||
}
|
||||
} else {
|
||||
event.accepted = false;
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onRightPressed: {
|
||||
if (d.openedMenuIndex !== -1 && d.openedMenuIndex < root.menus.length - 1) {
|
||||
var idx = d.openedMenuIndex + 1
|
||||
while (idx < root.menus.length && !(root.menus[idx].enabled && root.menus[idx].visible))
|
||||
idx++
|
||||
if (idx < root.menus.length) {
|
||||
d.preselectMenuItem = true
|
||||
d.openMenuAtIndex(idx)
|
||||
}
|
||||
} else {
|
||||
event.accepted = false;
|
||||
}
|
||||
}
|
||||
|
||||
Keys.forwardTo: d.openedMenuIndex !== -1 ? [root.menus[d.openedMenuIndex].__contentItem] : []
|
||||
|
||||
Row {
|
||||
id: row
|
||||
x: d.style ? d.style.padding.left : 0
|
||||
y: d.style ? d.style.padding.top : 0
|
||||
width: parent.width - (d.style ? d.style.padding.left + d.style.padding.right : 0)
|
||||
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
|
||||
|
||||
Repeater {
|
||||
id: itemsRepeater
|
||||
model: root.menus
|
||||
Loader {
|
||||
id: menuItemLoader
|
||||
|
||||
Accessible.role: Accessible.MenuItem
|
||||
Accessible.name: StyleHelpers.removeMnemonics(opts.text)
|
||||
Accessible.onPressAction: d.openMenuAtIndex(opts.index)
|
||||
|
||||
property var styleData: QtObject {
|
||||
id: opts
|
||||
readonly property int index: __menuItemIndex
|
||||
readonly property string text: !!__menuItem && __menuItem.title
|
||||
readonly property bool enabled: !!__menuItem && __menuItem.enabled
|
||||
readonly property bool selected: menuMouseArea.hoveredItem === menuItemLoader
|
||||
readonly property bool open: !!__menuItem && __menuItem.__popupVisible || d.openedMenuIndex === index
|
||||
readonly property bool underlineMnemonic: d.altPressed
|
||||
}
|
||||
|
||||
height: Math.max(menuBarLoader.height - d.heightPadding,
|
||||
menuItemLoader.item ? menuItemLoader.item.implicitHeight : 0)
|
||||
|
||||
readonly property var __menuItem: modelData
|
||||
readonly property int __menuItemIndex: index
|
||||
sourceComponent: d.style ? d.style.itemDelegate : null
|
||||
visible: __menuItem.visible
|
||||
|
||||
Connections {
|
||||
target: __menuItem
|
||||
function onAboutToHide() {
|
||||
if (d.openedMenuIndex === index) {
|
||||
d.openMenuAtIndex(-1)
|
||||
menuMouseArea.hoveredItem = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: __menuItem.__action
|
||||
function onTriggered() { d.openMenuAtIndex(__menuItemIndex) }
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
__menuItem.__visualItem = menuItemLoader
|
||||
|
||||
var title = __menuItem.title
|
||||
var ampersandPos = title.indexOf("&")
|
||||
if (ampersandPos !== -1)
|
||||
d.mnemonicsMap[title[ampersandPos + 1].toUpperCase()] = __menuItem.__action
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: menuMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
|
||||
onPositionChanged: updateCurrentItem(mouse)
|
||||
onPressed: updateCurrentItem(mouse)
|
||||
onExited: hoveredItem = null
|
||||
|
||||
property Item currentItem: null
|
||||
property Item hoveredItem: null
|
||||
function updateCurrentItem(mouse) {
|
||||
var pos = mapToItem(row, mouse.x, mouse.y)
|
||||
if (pressed || !hoveredItem
|
||||
|| !hoveredItem.contains(Qt.point(pos.x - currentItem.x, pos.y - currentItem.y))) {
|
||||
hoveredItem = row.childAt(pos.x, pos.y)
|
||||
if (!hoveredItem)
|
||||
return false;
|
||||
currentItem = hoveredItem
|
||||
if (pressed || d.openedMenuIndex !== -1) {
|
||||
d.preselectMenuItem = false
|
||||
d.openMenuAtIndex(currentItem.__menuItemIndex)
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
/*!
|
||||
\qmltype AbstractCheckable
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\brief An abstract representation of a checkable control with a label
|
||||
\qmlabstract
|
||||
\internal
|
||||
|
||||
A checkable control is one that has two states: checked (on) and
|
||||
unchecked (off). AbstractCheckable encapsulates the basic behavior and
|
||||
states that are required by checkable controls.
|
||||
|
||||
Examples of checkable controls are RadioButton and
|
||||
CheckBox. CheckBox extends AbstractCheckable's behavior by adding a third
|
||||
state: partially checked.
|
||||
*/
|
||||
|
||||
Control {
|
||||
id: abstractCheckable
|
||||
|
||||
/*!
|
||||
Emitted whenever the control is clicked.
|
||||
*/
|
||||
signal clicked
|
||||
|
||||
/*!
|
||||
\qmlproperty bool AbstractCheckable::pressed
|
||||
|
||||
This property is \c true if the control is being pressed.
|
||||
Set this property to manually invoke a mouse click.
|
||||
*/
|
||||
property alias pressed: mouseArea.effectivePressed
|
||||
|
||||
/*! \qmlproperty bool AbstractCheckcable::hovered
|
||||
|
||||
This property indicates whether the control is being hovered.
|
||||
*/
|
||||
readonly property alias hovered: mouseArea.containsMouse
|
||||
|
||||
/*!
|
||||
This property is \c true if the control is checked.
|
||||
*/
|
||||
property bool checked: false
|
||||
Accessible.checked: checked
|
||||
Accessible.checkable: true
|
||||
|
||||
/*!
|
||||
This property is \c true if the control takes the focus when it is
|
||||
pressed; \l{QQuickItem::forceActiveFocus()}{forceActiveFocus()} will be
|
||||
called on the control.
|
||||
*/
|
||||
property bool activeFocusOnPress: false
|
||||
|
||||
/*!
|
||||
This property stores the ExclusiveGroup that the control belongs to.
|
||||
*/
|
||||
property ExclusiveGroup exclusiveGroup: null
|
||||
|
||||
/*!
|
||||
This property holds the text that the label should display.
|
||||
*/
|
||||
property string text
|
||||
|
||||
/*!
|
||||
This property holds the button tooltip.
|
||||
|
||||
\since QtQuick.Controls 1.7
|
||||
*/
|
||||
property string tooltip
|
||||
Accessible.description: tooltip
|
||||
|
||||
/*! \internal */
|
||||
property var __cycleStatesHandler: cycleRadioButtonStates
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
focus: true
|
||||
anchors.fill: parent
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
enabled: !keyPressed
|
||||
|
||||
property bool keyPressed: false
|
||||
property bool effectivePressed: pressed && containsMouse || keyPressed
|
||||
|
||||
onClicked: abstractCheckable.clicked();
|
||||
|
||||
onPressed: if (activeFocusOnPress) forceActiveFocus();
|
||||
|
||||
onExited: Tooltip.hideText()
|
||||
onCanceled: Tooltip.hideText()
|
||||
|
||||
onReleased: {
|
||||
if (containsMouse && (!exclusiveGroup || !checked))
|
||||
__cycleStatesHandler();
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 1000
|
||||
running: mouseArea.containsMouse && !pressed && tooltip.length && mouseArea.Window.visibility !== Window.Hidden
|
||||
onTriggered: Tooltip.showText(mouseArea, Qt.point(mouseArea.mouseX, mouseArea.mouseY), tooltip)
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
onExclusiveGroupChanged: {
|
||||
if (exclusiveGroup)
|
||||
exclusiveGroup.bindCheckable(abstractCheckable)
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
if (event.key === Qt.Key_Space && !event.isAutoRepeat && !mouseArea.pressed)
|
||||
mouseArea.keyPressed = true;
|
||||
}
|
||||
|
||||
Keys.onReleased: {
|
||||
if (event.key === Qt.Key_Space && !event.isAutoRepeat && mouseArea.keyPressed) {
|
||||
mouseArea.keyPressed = false;
|
||||
if (!exclusiveGroup || !checked)
|
||||
__cycleStatesHandler();
|
||||
clicked();
|
||||
}
|
||||
}
|
||||
|
||||
Action {
|
||||
// handle mnemonic
|
||||
text: abstractCheckable.text
|
||||
onTriggered: {
|
||||
if (!abstractCheckable.exclusiveGroup || !abstractCheckable.checked)
|
||||
abstractCheckable.__cycleStatesHandler();
|
||||
abstractCheckable.clicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
/*!
|
||||
\qmltype BasicButton
|
||||
\internal
|
||||
\qmlabstract
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
|
||||
Control {
|
||||
id: button
|
||||
|
||||
/*! This signal is emitted when the button is clicked. */
|
||||
signal clicked
|
||||
|
||||
/*! \qmlproperty bool BasicButton::pressed
|
||||
|
||||
This property holds whether the button is being pressed. */
|
||||
readonly property alias pressed: button.__effectivePressed
|
||||
|
||||
/*! \qmlproperty bool BasicButton::hovered
|
||||
|
||||
This property indicates whether the control is being hovered.
|
||||
*/
|
||||
readonly property alias hovered: behavior.containsMouse
|
||||
|
||||
/*! This property holds whether the button is checkable.
|
||||
|
||||
The default value is \c false. */
|
||||
property bool checkable: false
|
||||
Accessible.checkable: checkable
|
||||
|
||||
/*! This property holds whether the button is checked.
|
||||
|
||||
Only checkable buttons can be checked.
|
||||
|
||||
The default value is \c false. */
|
||||
property bool checked: false
|
||||
Accessible.checked: checked
|
||||
|
||||
/*! This property holds the ExclusiveGroup that the button belongs to.
|
||||
|
||||
The default value is \c null. */
|
||||
property ExclusiveGroup exclusiveGroup: null
|
||||
|
||||
/*! This property holds the associated button action.
|
||||
|
||||
If a button has an action associated, the action defines the
|
||||
button's properties like checked, text, tooltip etc.
|
||||
|
||||
When an action is set, it's still possible to override the \l text,
|
||||
\l tooltip, \l iconSource, and \l iconName properties.
|
||||
|
||||
The default value is \c null. */
|
||||
property Action action: null
|
||||
|
||||
/*! This property specifies whether the button should gain active focus when pressed.
|
||||
|
||||
The default value is \c false. */
|
||||
property bool activeFocusOnPress: false
|
||||
|
||||
/*! This property holds the text shown on the button. If the button has no
|
||||
text, the \l text property will be an empty string.
|
||||
|
||||
The default value is the empty string.
|
||||
*/
|
||||
property string text: action ? action.text : ""
|
||||
|
||||
/*! This property holds the button tooltip. */
|
||||
property string tooltip: action ? (action.tooltip || StyleHelpers.removeMnemonics(action.text)) : ""
|
||||
|
||||
/*! This property holds the icon shown on the button. If the button has no
|
||||
icon, the iconSource property will be an empty string.
|
||||
|
||||
The default value is the empty string.
|
||||
*/
|
||||
property url iconSource: action ? action.iconSource : ""
|
||||
|
||||
/*! The image label source as theme name.
|
||||
When an icon from the platform icon theme is found, this takes
|
||||
precedence over iconSource.
|
||||
|
||||
\include icons.qdocinc iconName
|
||||
*/
|
||||
property string iconName: action ? action.iconName : ""
|
||||
|
||||
/*! \internal */
|
||||
property string __position: "only"
|
||||
/*! \internal */
|
||||
readonly property bool __iconOverriden: button.action && (button.action.iconSource !== button.iconSource || button.action.iconName !== button.iconName)
|
||||
/*! \internal */
|
||||
property Action __action: action || ownAction
|
||||
/*! \internal */
|
||||
readonly property Action __iconAction: __iconOverriden ? ownAction : __action
|
||||
|
||||
/*! \internal */
|
||||
onExclusiveGroupChanged: {
|
||||
if (exclusiveGroup)
|
||||
exclusiveGroup.bindCheckable(button)
|
||||
}
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.description: tooltip
|
||||
|
||||
/*! \internal */
|
||||
function accessiblePressAction() {
|
||||
__action.trigger(button)
|
||||
}
|
||||
|
||||
Action {
|
||||
id: ownAction
|
||||
enabled: button.enabled
|
||||
iconSource: !button.action || __iconOverriden ? button.iconSource : ""
|
||||
iconName: !button.action || __iconOverriden ? button.iconName : ""
|
||||
|
||||
// let ownAction handle mnemonic if and only if the button does
|
||||
// not already have an action assigned to avoid ambiguous shortcuts
|
||||
text: button.action ? "" : button.text
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: __action
|
||||
function onTriggered() { button.clicked() }
|
||||
}
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
Keys.onPressed: {
|
||||
if (event.key === Qt.Key_Space && !event.isAutoRepeat && !behavior.pressed) {
|
||||
behavior.keyPressed = true;
|
||||
event.accepted = true;
|
||||
}
|
||||
}
|
||||
|
||||
onFocusChanged: if (!focus) behavior.keyPressed = false
|
||||
|
||||
Keys.onReleased: {
|
||||
if (event.key === Qt.Key_Space && !event.isAutoRepeat && behavior.keyPressed) {
|
||||
behavior.keyPressed = false;
|
||||
__action.trigger(button)
|
||||
behavior.toggle()
|
||||
event.accepted = true;
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: behavior
|
||||
property bool keyPressed: false
|
||||
property bool effectivePressed: pressed && containsMouse || keyPressed
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
enabled: !keyPressed
|
||||
|
||||
function toggle() {
|
||||
if (button.checkable && !button.action && !(button.checked && button.exclusiveGroup))
|
||||
button.checked = !button.checked
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
if (containsMouse) {
|
||||
toggle()
|
||||
__action.trigger(button)
|
||||
}
|
||||
}
|
||||
onExited: Tooltip.hideText()
|
||||
onCanceled: Tooltip.hideText()
|
||||
onPressed: {
|
||||
if (activeFocusOnPress)
|
||||
button.forceActiveFocus()
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 1000
|
||||
running: behavior.containsMouse && !pressed && tooltip.length && behavior.Window.visibility !== Window.Hidden
|
||||
onTriggered: Tooltip.showText(behavior, Qt.point(behavior.mouseX, behavior.mouseY), tooltip)
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property var __behavior: behavior
|
||||
|
||||
/*! \internal */
|
||||
property bool __effectivePressed: behavior.effectivePressed
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "boundAction"
|
||||
when: action !== null
|
||||
PropertyChanges {
|
||||
target: button
|
||||
enabled: action.enabled
|
||||
checkable: action.checkable
|
||||
checked: action.checked
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,792 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
import QtQml 2.14 as Qml
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 1.5
|
||||
import QtQuick.Controls.Private 1.0
|
||||
import QtQuick.Controls.Styles 1.2
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
/*!
|
||||
\qmltype BasicTableView
|
||||
\qmlabstract
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
|
||||
ScrollView {
|
||||
id: root
|
||||
|
||||
/*! \qmlproperty bool BasicTableView::alternatingRowColors
|
||||
|
||||
This property is set to \c true if the view alternates the row color.
|
||||
The default value is \c true.
|
||||
*/
|
||||
property bool alternatingRowColors: true
|
||||
|
||||
/*! \qmlproperty bool BasicTableView::headerVisible
|
||||
|
||||
This property determines if the header is visible.
|
||||
The default value is \c true.
|
||||
*/
|
||||
property bool headerVisible: true
|
||||
|
||||
/*! \qmlproperty bool BasicTableView::backgroundVisible
|
||||
|
||||
This property determines if the background should be filled or not.
|
||||
|
||||
The default value is \c true.
|
||||
|
||||
\note The rowDelegate is not affected by this property
|
||||
*/
|
||||
property alias backgroundVisible: colorRect.visible
|
||||
|
||||
/*! \qmlproperty Component BasicTableView::itemDelegate
|
||||
\internal
|
||||
|
||||
Documentation differs between TableView and TreeView.
|
||||
See qtquickcontrols-treeview.qdoc and qtquickcontrols-tableview.qdoc
|
||||
*/
|
||||
property Component itemDelegate: __style ? __style.itemDelegate : null
|
||||
|
||||
/*! \qmlproperty Component BasicTableView::rowDelegate
|
||||
|
||||
This property defines a delegate to draw a row.
|
||||
|
||||
In the row delegate you have access to the following special properties:
|
||||
\list
|
||||
\li styleData.alternate - true when the row uses the alternate background color
|
||||
\li styleData.selected - true when the row is currently selected
|
||||
\li styleData.row - the index of the row
|
||||
\li styleData.hasActiveFocus - true when the row has focus (since QtQuick.Controls 1.3)
|
||||
\li styleData.pressed - true when the row is pressed (since QtQuick.Controls 1.3)
|
||||
\endlist
|
||||
|
||||
\note For performance reasons, created delegates can be recycled
|
||||
across multiple table rows. This implies that when you make use of implicit
|
||||
properties such as \c styleData.row or \c model, these values can change
|
||||
after the delegate has been constructed. This means that you should not assume
|
||||
that content is fixed when \c Component.onCompleted is called, but instead rely on
|
||||
bindings to such properties.
|
||||
*/
|
||||
property Component rowDelegate: __style ? __style.rowDelegate : null
|
||||
|
||||
/*! \qmlproperty Component BasicTableView::headerDelegate
|
||||
|
||||
This property defines a delegate to draw a header.
|
||||
|
||||
In the header delegate you have access to the following special properties:
|
||||
\list
|
||||
\li styleData.value - the value or text for this item
|
||||
\li styleData.column - the index of the column
|
||||
\li styleData.pressed - true when the column is being pressed
|
||||
\li styleData.containsMouse - true when the column is under the mouse
|
||||
\li styleData.textAlignment - the horizontal text alignment of the column (since QtQuickControls 1.1)
|
||||
\endlist
|
||||
*/
|
||||
property Component headerDelegate: __style ? __style.headerDelegate : null
|
||||
|
||||
/*! \qmlproperty int BasicTableView::sortIndicatorColumn
|
||||
|
||||
Index of the current sort column.
|
||||
The default value is \c {0}.
|
||||
*/
|
||||
property int sortIndicatorColumn
|
||||
|
||||
/*! \qmlproperty bool BasicTableView::sortIndicatorVisible
|
||||
|
||||
This property shows or hides the sort indicator
|
||||
The default value is \c false.
|
||||
\note The view itself does not sort the data.
|
||||
*/
|
||||
property bool sortIndicatorVisible: false
|
||||
|
||||
/*! \qmlproperty enumeration BasicTableView::sortIndicatorOrder
|
||||
|
||||
This sets the sorting order of the sort indicator
|
||||
The allowed values are:
|
||||
\list
|
||||
\li Qt.AscendingOrder - the default
|
||||
\li Qt.DescendingOrder
|
||||
\endlist
|
||||
*/
|
||||
property int sortIndicatorOrder: Qt.AscendingOrder
|
||||
|
||||
/*! \qmlproperty Component BasicTableView::contentHeader
|
||||
This is the content header of the view.
|
||||
*/
|
||||
property alias contentHeader: listView.header
|
||||
|
||||
/*! \qmlproperty Component BasicTableView::contentFooter
|
||||
This is the content footer of the view.
|
||||
*/
|
||||
property alias contentFooter: listView.footer
|
||||
|
||||
/*! \qmlproperty int BasicTableView::columnCount
|
||||
The current number of columns
|
||||
*/
|
||||
readonly property alias columnCount: columnModel.count
|
||||
|
||||
/*! \qmlpropertygroup BasicTableView::section
|
||||
\internal
|
||||
\qmlproperty string BasicTableView::section.property
|
||||
\qmlproperty enumeration BasicTableView::section.criteria
|
||||
\qmlproperty Component BasicTableView::section.delegate
|
||||
\qmlproperty enumeration BasicTableView::section.labelPositioning
|
||||
|
||||
Moved to the qdoc files to keep the grouped property layout.
|
||||
See qtquickcontrols-treeview.qdoc and qtquickcontrols-tableview.qdoc
|
||||
*/
|
||||
property alias section: listView.section
|
||||
|
||||
/*!
|
||||
\qmlproperty enumeration BasicTableView::selectionMode
|
||||
\since QtQuick.Controls 1.1
|
||||
|
||||
This enum indicates how the view responds to user selections:
|
||||
|
||||
The possible modes are:
|
||||
|
||||
\list
|
||||
|
||||
\li SelectionMode.NoSelection - Items cannot be selected.
|
||||
|
||||
\li SelectionMode.SingleSelection - When the user selects an item,
|
||||
any already-selected item becomes unselected, and the user cannot
|
||||
unselect the selected item. (Default)
|
||||
|
||||
\li SelectionMode.MultiSelection - When the user selects an item in the usual way,
|
||||
the selection status of that item is toggled and the other items are left alone.
|
||||
|
||||
\li SelectionMode.ExtendedSelection - When the user selects an item in the usual way,
|
||||
the selection is cleared and the new item selected. However, if the user presses the
|
||||
Ctrl key when clicking on an item, the clicked item gets toggled and all other items
|
||||
are left untouched. If the user presses the Shift key while clicking
|
||||
on an item, all items between the current item and the clicked item are selected or unselected,
|
||||
depending on the state of the clicked item. Multiple items can be selected by dragging the
|
||||
mouse over them.
|
||||
|
||||
\li SelectionMode.ContiguousSelection - When the user selects an item in the usual way,
|
||||
the selection is cleared and the new item selected. However, if the user presses the Shift key while
|
||||
clicking on an item, all items between the current item and the clicked item are selected.
|
||||
|
||||
\endlist
|
||||
*/
|
||||
property int selectionMode: SelectionMode.SingleSelection
|
||||
|
||||
/*!
|
||||
\qmlmethod TableViewColumn BasicTableView::addColumn(object column)
|
||||
|
||||
Adds a \a column and returns the added column.
|
||||
|
||||
The \a column argument can be an instance of TableViewColumn,
|
||||
or a Component. The component has to contain a TableViewColumn.
|
||||
Otherwise \c null is returned.
|
||||
*/
|
||||
function addColumn(column) {
|
||||
return insertColumn(columnCount, column)
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod TableViewColumn BasicTableView::insertColumn(int index, object column)
|
||||
|
||||
Inserts a \a column at the given \a index and returns the inserted column.
|
||||
|
||||
The \a column argument can be an instance of TableViewColumn,
|
||||
or a Component. The component has to contain a TableViewColumn.
|
||||
Otherwise \c null is returned.
|
||||
*/
|
||||
function insertColumn(index, column) {
|
||||
if (__isTreeView && index === 0 && columnCount > 0) {
|
||||
console.warn(__viewTypeName + "::insertColumn(): Can't replace column 0")
|
||||
return null
|
||||
}
|
||||
var object = column
|
||||
if (typeof column['createObject'] === 'function') {
|
||||
object = column.createObject(root)
|
||||
} else if (object.__view) {
|
||||
console.warn(__viewTypeName + "::insertColumn(): you cannot add a column to multiple views")
|
||||
return null
|
||||
}
|
||||
if (index >= 0 && index <= columnCount && object.accessibleRole === Accessible.ColumnHeader) {
|
||||
object.__view = root
|
||||
columnModel.insert(index, {columnItem: object})
|
||||
if (root.__columns[index] !== object) {
|
||||
// The new column needs to be put into __columns at the specified index
|
||||
// so the list needs to be recreated to be correct
|
||||
var arr = []
|
||||
for (var i = 0; i < index; ++i)
|
||||
arr.push(root.__columns[i])
|
||||
arr.push(object)
|
||||
for (i = index; i < root.__columns.length; ++i)
|
||||
arr.push(root.__columns[i])
|
||||
root.__columns = arr
|
||||
}
|
||||
return object
|
||||
}
|
||||
|
||||
if (object !== column)
|
||||
object.destroy()
|
||||
console.warn(__viewTypeName + "::insertColumn(): invalid argument")
|
||||
return null
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void BasicTableView::removeColumn(int index)
|
||||
|
||||
Removes and destroys a column at the given \a index.
|
||||
*/
|
||||
function removeColumn(index) {
|
||||
if (index < 0 || index >= columnCount) {
|
||||
console.warn(__viewTypeName + "::removeColumn(): invalid argument")
|
||||
return
|
||||
}
|
||||
if (__isTreeView && index === 0) {
|
||||
console.warn(__viewTypeName + "::removeColumn(): Can't remove column 0")
|
||||
return
|
||||
}
|
||||
var column = columnModel.get(index).columnItem
|
||||
columnModel.remove(index, 1)
|
||||
column.destroy()
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void BasicTableView::moveColumn(int from, int to)
|
||||
|
||||
Moves a column \a from index \a to another.
|
||||
*/
|
||||
function moveColumn(from, to) {
|
||||
if (from < 0 || from >= columnCount || to < 0 || to >= columnCount) {
|
||||
console.warn(__viewTypeName + "::moveColumn(): invalid argument")
|
||||
return
|
||||
}
|
||||
if (__isTreeView && to === 0) {
|
||||
console.warn(__viewTypeName + "::moveColumn(): Can't move column 0")
|
||||
return
|
||||
}
|
||||
if (sortIndicatorColumn === from)
|
||||
sortIndicatorColumn = to
|
||||
columnModel.move(from, to, 1)
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod TableViewColumn BasicTableView::getColumn(int index)
|
||||
|
||||
Returns the column at the given \a index
|
||||
or \c null if the \a index is invalid.
|
||||
*/
|
||||
function getColumn(index) {
|
||||
if (index < 0 || index >= columnCount)
|
||||
return null
|
||||
return columnModel.get(index).columnItem
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void BasicTableView::resizeColumnsToContents()
|
||||
|
||||
Resizes all columns to ensure that the column contents and the headers will fit.
|
||||
\since QtQuick.Controls 1.2
|
||||
*/
|
||||
function resizeColumnsToContents () {
|
||||
for (var i = 0; i < __columns.length; ++i) {
|
||||
var col = getColumn(i)
|
||||
var header = __listView.headerItem.headerRepeater.itemAt(i)
|
||||
if (col) {
|
||||
col.resizeToContents()
|
||||
if (col.width < header.implicitWidth)
|
||||
col.width = header.implicitWidth
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Internal stuff. Do not look
|
||||
|
||||
Component.onCompleted: {
|
||||
for (var i = 0; i < __columns.length; ++i) {
|
||||
var column = __columns[i]
|
||||
if (column.accessibleRole === Accessible.ColumnHeader)
|
||||
addColumn(column)
|
||||
}
|
||||
}
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
implicitWidth: 200
|
||||
implicitHeight: 150
|
||||
|
||||
frameVisible: true
|
||||
__scrollBarTopMargin: headerVisible && (listView.transientScrollBars || Qt.platform.os === "osx")
|
||||
? listView.headerItem.height : 0
|
||||
|
||||
/*! \internal
|
||||
Use this to display user-friendly messages in TableView and TreeView common functions.
|
||||
*/
|
||||
property string __viewTypeName
|
||||
|
||||
/*! \internal */
|
||||
readonly property bool __isTreeView: __viewTypeName === "TreeView"
|
||||
|
||||
/*! \internal */
|
||||
default property alias __columns: root.data
|
||||
|
||||
/*! \internal */
|
||||
property alias __currentRowItem: listView.currentItem
|
||||
|
||||
/*! \internal
|
||||
This property is forwarded to TableView::currentRow, but not to any TreeView property.
|
||||
*/
|
||||
property alias __currentRow: listView.currentIndex
|
||||
|
||||
/*! \internal */
|
||||
readonly property alias __listView: listView
|
||||
|
||||
/*! \internal */
|
||||
property Component __itemDelegateLoader: null
|
||||
|
||||
/*! \internal
|
||||
Allows to override the model property in cases like TreeView,
|
||||
where we want to use a proxy/adaptor model between the user's model
|
||||
and whatever a ListView can swallow.
|
||||
*/
|
||||
property var __model
|
||||
|
||||
/*! \internal */
|
||||
property bool __activateItemOnSingleClick: __style ? __style.activateItemOnSingleClick : false
|
||||
|
||||
/*! \internal */
|
||||
property Item __mouseArea
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
focus: true
|
||||
activeFocusOnTab: false
|
||||
Keys.forwardTo: [__mouseArea]
|
||||
anchors.fill: parent
|
||||
contentWidth: headerItem.headerRow.width + listView.vScrollbarPadding
|
||||
// ### FIXME Late configuration of the header item requires
|
||||
// this binding to get the header visible after creation
|
||||
contentY: -headerItem.height
|
||||
|
||||
currentIndex: -1
|
||||
visible: columnCount > 0
|
||||
interactive: Settings.hasTouchScreen
|
||||
property var rowItemStack: [] // Used as a cache for rowDelegates
|
||||
|
||||
readonly property bool transientScrollBars: __style && !!__style.transientScrollBars
|
||||
readonly property real vScrollbarPadding: __scroller.verticalScrollBar.visible
|
||||
&& !transientScrollBars && Qt.platform.os === "osx" ?
|
||||
__verticalScrollBar.width + __scroller.scrollBarSpacing + root.__style.padding.right : 0
|
||||
|
||||
Qml.Binding {
|
||||
// On Mac, we reserve the vSB space in the contentItem because the vSB should
|
||||
// appear under the header. Unfortunately, the ListView header won't expand
|
||||
// beyond the ListView's boundaries, that's why we need to ressort to this.
|
||||
target: root.__scroller
|
||||
when: Qt.platform.os === "osx"
|
||||
property: "verticalScrollbarOffset"
|
||||
value: 0
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
function incrementCurrentIndexBlocking() {
|
||||
var oldIndex = __listView.currentIndex
|
||||
__scroller.blockUpdates = true;
|
||||
incrementCurrentIndex();
|
||||
__scroller.blockUpdates = false;
|
||||
return oldIndex !== __listView.currentIndex
|
||||
}
|
||||
|
||||
function decrementCurrentIndexBlocking() {
|
||||
var oldIndex = __listView.currentIndex
|
||||
__scroller.blockUpdates = true;
|
||||
decrementCurrentIndex();
|
||||
__scroller.blockUpdates = false;
|
||||
return oldIndex !== __listView.currentIndex
|
||||
}
|
||||
|
||||
function scrollIfNeeded(key) {
|
||||
var diff = key === Qt.Key_PageDown ? height :
|
||||
key === Qt.Key_PageUp ? -height : 0
|
||||
if (diff !== 0)
|
||||
__verticalScrollBar.value += diff
|
||||
}
|
||||
|
||||
SystemPalette {
|
||||
id: palette
|
||||
colorGroup: enabled ? SystemPalette.Active : SystemPalette.Disabled
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: colorRect
|
||||
parent: viewport
|
||||
anchors.fill: parent
|
||||
color: __style ? __style.backgroundColor : palette.base
|
||||
z: -2
|
||||
}
|
||||
|
||||
// Fills extra rows with alternate color
|
||||
Column {
|
||||
id: rowfiller
|
||||
Loader {
|
||||
id: rowSizeItem
|
||||
sourceComponent: root.rowDelegate
|
||||
visible: false
|
||||
property QtObject styleData: QtObject {
|
||||
property bool alternate: false
|
||||
property bool selected: false
|
||||
property bool hasActiveFocus: false
|
||||
property bool pressed: false
|
||||
}
|
||||
}
|
||||
property int rowHeight: Math.floor(rowSizeItem.implicitHeight)
|
||||
property int paddedRowCount: rowHeight != 0 ? height/rowHeight : 0
|
||||
|
||||
y: listView.contentHeight - listView.contentY + listView.originY
|
||||
width: parent.width
|
||||
visible: alternatingRowColors
|
||||
height: listView.model && listView.model.count ? Math.max(viewport.height - listView.contentHeight, 0) : 0
|
||||
Repeater {
|
||||
model: visible ? parent.paddedRowCount : 0
|
||||
Loader {
|
||||
width: rowfiller.width
|
||||
height: rowfiller.rowHeight
|
||||
sourceComponent: root.rowDelegate
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property bool alternate: (index + __listView.count) % 2 === 1
|
||||
readonly property bool selected: false
|
||||
readonly property bool hasActiveFocus: false
|
||||
readonly property bool pressed: false
|
||||
}
|
||||
readonly property var model: null
|
||||
readonly property var modelData: null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: columnModel
|
||||
}
|
||||
|
||||
highlightFollowsCurrentItem: true
|
||||
model: root.__model
|
||||
|
||||
delegate: FocusScope {
|
||||
id: rowItemContainer
|
||||
|
||||
activeFocusOnTab: false
|
||||
z: rowItem.activeFocus ? 0.7 : rowItem.itemSelected ? 0.5 : 0
|
||||
|
||||
property Item rowItem
|
||||
// We recycle instantiated row items to speed up list scrolling
|
||||
|
||||
Component.onDestruction: {
|
||||
// move the rowItem back in cache
|
||||
if (rowItem) {
|
||||
rowItem.visible = false;
|
||||
rowItem.parent = null;
|
||||
rowItem.rowIndex = -1;
|
||||
listView.rowItemStack.push(rowItem); // return rowItem to cache
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
// retrieve row item from cache
|
||||
if (listView.rowItemStack.length > 0)
|
||||
rowItem = listView.rowItemStack.pop();
|
||||
else
|
||||
rowItem = rowComponent.createObject(listView);
|
||||
|
||||
// Bind container to item size
|
||||
rowItemContainer.width = Qt.binding( function() { return rowItem.width });
|
||||
rowItemContainer.height = Qt.binding( function() { return rowItem.height });
|
||||
|
||||
// Reassign row-specific bindings
|
||||
rowItem.rowIndex = Qt.binding( function() { return model.index });
|
||||
rowItem.itemModelData = Qt.binding( function() { return typeof modelData === "undefined" ? null : modelData });
|
||||
rowItem.itemModel = Qt.binding( function() { return model });
|
||||
rowItem.parent = rowItemContainer;
|
||||
rowItem.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: rowComponent
|
||||
|
||||
FocusScope {
|
||||
id: rowitem
|
||||
visible: false
|
||||
|
||||
property int rowIndex
|
||||
property var itemModelData
|
||||
property var itemModel
|
||||
property bool itemSelected: __mouseArea.selected(rowIndex)
|
||||
property bool alternate: alternatingRowColors && rowIndex % 2 === 1
|
||||
readonly property color itemTextColor: itemSelected ? __style.highlightedTextColor : __style.textColor
|
||||
property Item branchDecoration: null
|
||||
|
||||
width: itemrow.width
|
||||
height: rowstyle.height
|
||||
|
||||
onActiveFocusChanged: {
|
||||
if (activeFocus)
|
||||
listView.currentIndex = rowIndex
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: rowstyle
|
||||
// row delegate
|
||||
sourceComponent: rowitem.itemModel !== undefined ? root.rowDelegate : null
|
||||
// Row fills the view width regardless of item size
|
||||
// But scrollbar should not adjust to it
|
||||
height: item ? item.height : 16
|
||||
width: parent.width + __horizontalScrollBar.width
|
||||
x: listView.contentX
|
||||
|
||||
// these properties are exposed to the row delegate
|
||||
// Note: these properties should be mirrored in the row filler as well
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property int row: rowitem.rowIndex
|
||||
readonly property bool alternate: rowitem.alternate
|
||||
readonly property bool selected: rowitem.itemSelected
|
||||
readonly property bool hasActiveFocus: rowitem.activeFocus
|
||||
readonly property bool pressed: rowitem.rowIndex === __mouseArea.pressedRow
|
||||
}
|
||||
readonly property var model: rowitem.itemModel
|
||||
readonly property var modelData: rowitem.itemModelData
|
||||
}
|
||||
Row {
|
||||
id: itemrow
|
||||
height: parent.height
|
||||
Repeater {
|
||||
model: columnModel
|
||||
|
||||
delegate: __itemDelegateLoader
|
||||
|
||||
onItemAdded: {
|
||||
var columnItem = columnModel.get(index).columnItem
|
||||
item.__rowItem = rowitem
|
||||
item.__column = columnItem
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
headerPositioning: ListView.OverlayHeader
|
||||
header: Item {
|
||||
id: tableHeader
|
||||
visible: headerVisible
|
||||
width: Math.max(headerRow.width + listView.vScrollbarPadding, root.viewport.width)
|
||||
height: visible ? headerRow.height : 0
|
||||
|
||||
property alias headerRow: row
|
||||
property alias headerRepeater: repeater
|
||||
Row {
|
||||
id: row
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
|
||||
property int targetIndex: -1
|
||||
property int dragIndex: -1
|
||||
|
||||
model: columnModel
|
||||
|
||||
delegate: Item {
|
||||
id: headerRowDelegate
|
||||
readonly property int column: index
|
||||
z:-index
|
||||
width: modelData.width
|
||||
implicitWidth: columnCount === 1 ? viewport.width + __verticalScrollBar.width : headerStyle.implicitWidth
|
||||
visible: modelData.visible
|
||||
height: headerStyle.height
|
||||
|
||||
readonly property bool treeViewMovable: !__isTreeView || index > 0
|
||||
|
||||
Loader {
|
||||
id: headerStyle
|
||||
sourceComponent: root.headerDelegate
|
||||
width: parent.width
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property string value: modelData.title
|
||||
readonly property bool pressed: headerClickArea.pressed
|
||||
readonly property bool containsMouse: headerClickArea.containsMouse
|
||||
readonly property int column: index
|
||||
readonly property int textAlignment: modelData.horizontalAlignment
|
||||
readonly property bool resizable: modelData.resizable
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle{
|
||||
id: targetmark
|
||||
width: parent.width
|
||||
height:parent.height
|
||||
opacity: (treeViewMovable && index === repeater.targetIndex && repeater.targetIndex !== repeater.dragIndex) ? 0.5 : 0
|
||||
Behavior on opacity { NumberAnimation { duration: 160 } }
|
||||
color: palette.highlight
|
||||
visible: modelData.movable
|
||||
}
|
||||
|
||||
MouseArea{
|
||||
id: headerClickArea
|
||||
drag.axis: Qt.YAxis
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
if (sortIndicatorColumn === index)
|
||||
sortIndicatorOrder = sortIndicatorOrder === Qt.AscendingOrder ? Qt.DescendingOrder : Qt.AscendingOrder
|
||||
sortIndicatorColumn = index
|
||||
}
|
||||
// Here we handle moving header sections
|
||||
// NOTE: the direction is different from the master branch
|
||||
// so this indicates that I am using an invalid assumption on item ordering
|
||||
onPositionChanged: {
|
||||
if (drag.active && modelData.movable && pressed && columnCount > 1) { // only do this while dragging
|
||||
for (var h = columnCount-1 ; h >= 0 ; --h) {
|
||||
if (headerRow.children[h].visible && drag.target.x + headerRowDelegate.width/2 > headerRow.children[h].x) {
|
||||
repeater.targetIndex = h
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
repeater.dragIndex = index
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
if (repeater.targetIndex >= 0 && repeater.targetIndex !== index ) {
|
||||
var targetColumn = columnModel.get(repeater.targetIndex).columnItem
|
||||
if (targetColumn.movable && (!__isTreeView || repeater.targetIndex > 0)) {
|
||||
if (sortIndicatorColumn === index)
|
||||
sortIndicatorColumn = repeater.targetIndex
|
||||
columnModel.move(index, repeater.targetIndex, 1)
|
||||
}
|
||||
}
|
||||
repeater.targetIndex = -1
|
||||
repeater.dragIndex = -1
|
||||
}
|
||||
drag.target: treeViewMovable && modelData.movable && columnCount > 1 ? draghandle : null
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: draghandle
|
||||
property QtObject styleData: QtObject{
|
||||
readonly property string value: modelData.title
|
||||
readonly property bool pressed: headerClickArea.pressed
|
||||
readonly property bool containsMouse: headerClickArea.containsMouse
|
||||
readonly property int column: index
|
||||
readonly property int textAlignment: modelData.horizontalAlignment
|
||||
}
|
||||
parent: tableHeader
|
||||
x: __implicitX
|
||||
property double __implicitX: headerRowDelegate.x
|
||||
width: modelData.width
|
||||
height: parent.height
|
||||
sourceComponent: root.headerDelegate
|
||||
visible: headerClickArea.pressed
|
||||
onVisibleChanged: {
|
||||
if (!visible)
|
||||
x = Qt.binding(function () { return __implicitX })
|
||||
}
|
||||
opacity: 0.5
|
||||
}
|
||||
|
||||
|
||||
MouseArea {
|
||||
id: headerResizeHandle
|
||||
property int offset: 0
|
||||
readonly property int minimumSize: 20
|
||||
preventStealing: true
|
||||
anchors.rightMargin: -width/2
|
||||
width: Settings.hasTouchScreen ? Screen.pixelDensity * 3.5 : 16
|
||||
height: parent.height
|
||||
anchors.right: parent.right
|
||||
enabled: modelData.resizable && columnCount > 0
|
||||
onPositionChanged: {
|
||||
var newHeaderWidth = modelData.width + (mouseX - offset)
|
||||
modelData.width = Math.max(minimumSize, newHeaderWidth)
|
||||
}
|
||||
|
||||
onDoubleClicked: getColumn(index).resizeToContents()
|
||||
onPressedChanged: if (pressed) offset=mouseX
|
||||
cursorShape: enabled && repeater.dragIndex==-1 ? Qt.SplitHCursor : Qt.ArrowCursor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
property QtObject styleData: QtObject{
|
||||
readonly property string value: ""
|
||||
readonly property bool pressed: false
|
||||
readonly property bool containsMouse: false
|
||||
readonly property int column: -1
|
||||
readonly property int textAlignment: Text.AlignLeft
|
||||
}
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: headerRow.bottom
|
||||
sourceComponent: root.headerDelegate
|
||||
readonly property real __remainingWidth: parent.width - headerRow.width
|
||||
visible: __remainingWidth > 0
|
||||
width: __remainingWidth
|
||||
z:-1
|
||||
}
|
||||
}
|
||||
|
||||
function columnAt(offset) {
|
||||
var item = listView.headerItem.headerRow.childAt(offset, 0)
|
||||
return item ? item.column : -1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
/*
|
||||
CalendarHeaderModel contains a list of the days of a week,
|
||||
according to a \l locale. The \l locale affects which day of the week
|
||||
is first in the model.
|
||||
|
||||
The only role provided by the model is \c dayOfWeek, which is one of the
|
||||
following JavaScript values:
|
||||
|
||||
\list
|
||||
\li \c Locale.Sunday
|
||||
\li \c Locale.Monday
|
||||
\li \c Locale.Tuesday
|
||||
\li \c Locale.Wednesday
|
||||
\li \c Locale.Thursday
|
||||
\li \c Locale.Friday
|
||||
\li \c Locale.Saturday
|
||||
\endlist
|
||||
*/
|
||||
|
||||
ListModel {
|
||||
id: root
|
||||
|
||||
/*
|
||||
The locale that this model should be based on.
|
||||
This affects which day of the week is first in the model.
|
||||
*/
|
||||
property var locale
|
||||
|
||||
ListElement {
|
||||
dayOfWeek: Locale.Sunday
|
||||
}
|
||||
ListElement {
|
||||
dayOfWeek: Locale.Monday
|
||||
}
|
||||
ListElement {
|
||||
dayOfWeek: Locale.Tuesday
|
||||
}
|
||||
ListElement {
|
||||
dayOfWeek: Locale.Wednesday
|
||||
}
|
||||
ListElement {
|
||||
dayOfWeek: Locale.Thursday
|
||||
}
|
||||
ListElement {
|
||||
dayOfWeek: Locale.Friday
|
||||
}
|
||||
ListElement {
|
||||
dayOfWeek: Locale.Saturday
|
||||
}
|
||||
|
||||
Component.onCompleted: updateFirstDayOfWeek()
|
||||
onLocaleChanged: updateFirstDayOfWeek()
|
||||
|
||||
function updateFirstDayOfWeek() {
|
||||
var daysOfWeek = [Locale.Sunday, Locale.Monday, Locale.Tuesday,
|
||||
Locale.Wednesday, Locale.Thursday, Locale.Friday, Locale.Saturday];
|
||||
var firstDayOfWeek = root.locale.firstDayOfWeek;
|
||||
|
||||
var shifted = daysOfWeek.splice(firstDayOfWeek, daysOfWeek.length - firstDayOfWeek);
|
||||
daysOfWeek = shifted.concat(daysOfWeek)
|
||||
|
||||
if (firstDayOfWeek !== root.get(0).dayOfWeek) {
|
||||
for (var i = 0; i < daysOfWeek.length; ++i) {
|
||||
root.setProperty(i, "dayOfWeek", daysOfWeek[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
.pragma library
|
||||
|
||||
var daysInAWeek = 7;
|
||||
var monthsInAYear = 12;
|
||||
|
||||
// Not the number of weeks per month, but the number of weeks that are
|
||||
// shown on a typical calendar.
|
||||
var weeksOnACalendarMonth = 6;
|
||||
|
||||
// Can't create year 1 directly...
|
||||
var minimumCalendarDate = new Date(-1, 0, 1);
|
||||
minimumCalendarDate.setFullYear(minimumCalendarDate.getFullYear() + 2);
|
||||
var maximumCalendarDate = new Date(275759, 9, 25);
|
||||
|
||||
function daysInMonth(date) {
|
||||
// Passing 0 as the day will give us the previous month, which will be
|
||||
// date.getMonth() since we added 1 to it.
|
||||
return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a copy of \a date with its month set to \a month, keeping the same
|
||||
day if possible. Does not modify \a date.
|
||||
*/
|
||||
function setMonth(date, month) {
|
||||
var oldDay = date.getDate();
|
||||
var newDate = new Date(date);
|
||||
// Set the day first, because setting the month could cause it to skip ahead
|
||||
// a month if the day is larger than the latest day in that month.
|
||||
newDate.setDate(1);
|
||||
newDate.setMonth(month);
|
||||
// We'd like to have the previous day still selected when we change
|
||||
// months, but it might not be possible, so use the smallest of the two.
|
||||
newDate.setDate(Math.min(oldDay, daysInMonth(newDate)));
|
||||
return newDate;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the cell rectangle for the cell at the given \a index, assuming
|
||||
that the grid has a number of columns equal to \a columns and rows
|
||||
equal to \a rows, with an available width of \a availableWidth and height
|
||||
of \a availableHeight.
|
||||
|
||||
If \a gridLineWidth is greater than \c 0, the cell rectangle will be
|
||||
calculated under the assumption that there is a grid between the cells:
|
||||
|
||||
31 | 1 | 2 | 3 | 4 | 5 | 6
|
||||
--------------------------------
|
||||
7 | 8 | 9 | 10 | 11 | 12 | 13
|
||||
--------------------------------
|
||||
14 | 15 | 16 | 17 | 18 | 19 | 20
|
||||
--------------------------------
|
||||
21 | 22 | 23 | 24 | 25 | 26 | 27
|
||||
--------------------------------
|
||||
28 | 29 | 30 | 31 | 1 | 2 | 3
|
||||
--------------------------------
|
||||
4 | 5 | 6 | 7 | 8 | 9 | 10
|
||||
*/
|
||||
function cellRectAt(index, columns, rows, availableWidth, availableHeight, gridLineWidth) {
|
||||
var col = Math.floor(index % columns);
|
||||
var row = Math.floor(index / columns);
|
||||
|
||||
var availableWidthMinusGridLines = availableWidth - ((columns - 1) * gridLineWidth);
|
||||
var availableHeightMinusGridLines = availableHeight - ((rows - 1) * gridLineWidth);
|
||||
var remainingHorizontalSpace = Math.floor(availableWidthMinusGridLines % columns);
|
||||
var remainingVerticalSpace = Math.floor(availableHeightMinusGridLines % rows);
|
||||
var baseCellWidth = Math.floor(availableWidthMinusGridLines / columns);
|
||||
var baseCellHeight = Math.floor(availableHeightMinusGridLines / rows);
|
||||
|
||||
var rect = Qt.rect(0, 0, 0, 0);
|
||||
|
||||
rect.x = baseCellWidth * col;
|
||||
rect.width = baseCellWidth;
|
||||
if (remainingHorizontalSpace > 0) {
|
||||
if (col < remainingHorizontalSpace) {
|
||||
++rect.width;
|
||||
}
|
||||
|
||||
// This cell's x position should be increased by 1 for every column above it.
|
||||
rect.x += Math.min(remainingHorizontalSpace, col);
|
||||
}
|
||||
|
||||
rect.y = baseCellHeight * row;
|
||||
rect.height = baseCellHeight;
|
||||
if (remainingVerticalSpace > 0) {
|
||||
if (row < remainingVerticalSpace) {
|
||||
++rect.height;
|
||||
}
|
||||
|
||||
// This cell's y position should be increased by 1 for every row above it.
|
||||
rect.y += Math.min(remainingVerticalSpace, row);
|
||||
}
|
||||
|
||||
rect.x += col * gridLineWidth;
|
||||
rect.y += row * gridLineWidth;
|
||||
|
||||
return rect;
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQml 2.14 as Qml
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
Item {
|
||||
id: content
|
||||
|
||||
property Component menuItemDelegate
|
||||
property Component scrollIndicatorStyle
|
||||
property Component scrollerStyle
|
||||
property var itemsModel
|
||||
property int minWidth: 100
|
||||
property real maxHeight: 800
|
||||
readonly property bool mousePressed: hoverArea.pressed
|
||||
|
||||
signal triggered(var item)
|
||||
|
||||
function menuItemAt(index) {
|
||||
list.currentIndex = index
|
||||
return list.currentItem
|
||||
}
|
||||
|
||||
width: Math.max(list.contentWidth, minWidth)
|
||||
height: Math.min(list.contentHeight, fittedMaxHeight)
|
||||
|
||||
readonly property int currentIndex: __menu.__currentIndex
|
||||
property Item currentItem: null
|
||||
property int itemHeight: 23
|
||||
|
||||
Component.onCompleted: {
|
||||
var children = list.contentItem.children
|
||||
for (var i = 0; i < list.count; i++) {
|
||||
var child = children[i]
|
||||
if (child.visible && child.styleData.type === MenuItemType.Item) {
|
||||
itemHeight = children[i].height
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
readonly property int fittingItems: Math.floor((maxHeight - downScroller.height) / itemHeight)
|
||||
readonly property real fittedMaxHeight: itemHeight * fittingItems + downScroller.height
|
||||
readonly property bool shouldUseScrollers: scrollView.style === emptyScrollerStyle && itemsModel.length > fittingItems
|
||||
readonly property real upScrollerHeight: upScroller.visible ? upScroller.height : 0
|
||||
readonly property real downScrollerHeight: downScroller.visible ? downScroller.height : 0
|
||||
property var oldMousePos: undefined
|
||||
property var openedSubmenu: null
|
||||
|
||||
function updateCurrentItem(mouse) {
|
||||
var pos = mapToItem(list.contentItem, mouse.x, mouse.y)
|
||||
var dx = 0
|
||||
var dy = 0
|
||||
var dist = 0
|
||||
if (openedSubmenu && oldMousePos !== undefined) {
|
||||
dx = mouse.x - oldMousePos.x
|
||||
dy = mouse.y - oldMousePos.y
|
||||
dist = Math.sqrt(dx * dx + dy * dy)
|
||||
}
|
||||
oldMousePos = mouse
|
||||
if (openedSubmenu && dist > 5) {
|
||||
var menuRect = __menu.__popupGeometry
|
||||
var submenuRect = openedSubmenu.__popupGeometry
|
||||
var angle = Math.atan2(dy, dx)
|
||||
var ds = 0
|
||||
if (submenuRect.x > menuRect.x) {
|
||||
ds = menuRect.width - oldMousePos.x
|
||||
} else {
|
||||
angle = Math.PI - angle
|
||||
ds = oldMousePos.x
|
||||
}
|
||||
var above = submenuRect.y - menuRect.y - oldMousePos.y
|
||||
var below = submenuRect.height - above
|
||||
var minAngle = Math.atan2(above, ds)
|
||||
var maxAngle = Math.atan2(below, ds)
|
||||
// This tests that the current mouse position is in
|
||||
// the triangle defined by the previous mouse position
|
||||
// and the submenu's top-left and bottom-left corners.
|
||||
if (minAngle < angle && angle < maxAngle) {
|
||||
sloppyTimer.start()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!currentItem || !currentItem.contains(Qt.point(pos.x - currentItem.x, pos.y - currentItem.y))) {
|
||||
if (currentItem && !hoverArea.pressed
|
||||
&& currentItem.styleData.type === MenuItemType.Menu) {
|
||||
currentItem.__closeSubMenu()
|
||||
openedSubmenu = null
|
||||
}
|
||||
currentItem = list.itemAt(pos.x, pos.y)
|
||||
if (currentItem) {
|
||||
__menu.__currentIndex = currentItem.__menuItemIndex
|
||||
if (currentItem.styleData.type === MenuItemType.Menu) {
|
||||
showCurrentItemSubMenu(false)
|
||||
}
|
||||
} else {
|
||||
__menu.__currentIndex = -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showCurrentItemSubMenu(immediately) {
|
||||
if (!currentItem.__menuItem.__popupVisible) {
|
||||
currentItem.__showSubMenu(immediately)
|
||||
openedSubmenu = currentItem.__menuItem
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: sloppyTimer
|
||||
interval: 1000
|
||||
|
||||
// Stop timer as soon as we hover one of the submenu items
|
||||
property int currentIndex: openedSubmenu ? openedSubmenu.__currentIndex : -1
|
||||
onCurrentIndexChanged: if (currentIndex !== -1) stop()
|
||||
|
||||
onTriggered: {
|
||||
if (openedSubmenu && openedSubmenu.__currentIndex === -1)
|
||||
updateCurrentItem(oldMousePos)
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: emptyScrollerStyle
|
||||
Style {
|
||||
padding { left: 0; right: 0; top: 0; bottom: 0 }
|
||||
property bool scrollToClickedPosition: false
|
||||
property Component frame: Item { visible: false }
|
||||
property Component corner: Item { visible: false }
|
||||
property Component __scrollbar: Item { visible: false }
|
||||
}
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
id: scrollView
|
||||
anchors {
|
||||
fill: parent
|
||||
topMargin: upScrollerHeight
|
||||
bottomMargin: downScrollerHeight
|
||||
}
|
||||
|
||||
style: scrollerStyle || emptyScrollerStyle
|
||||
__wheelAreaScrollSpeed: itemHeight
|
||||
|
||||
ListView {
|
||||
id: list
|
||||
model: itemsModel
|
||||
delegate: menuItemDelegate
|
||||
snapMode: ListView.SnapToItem
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
highlightFollowsCurrentItem: true
|
||||
highlightMoveDuration: 0
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: hoverArea
|
||||
anchors.left: scrollView.left
|
||||
width: scrollView.width - scrollView.__verticalScrollBar.width
|
||||
height: parent.height
|
||||
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
acceptedButtons: Qt.AllButtons
|
||||
|
||||
onPositionChanged: updateCurrentItem({ "x": mouse.x, "y": mouse.y })
|
||||
onPressed: updateCurrentItem({ "x": mouse.x, "y": mouse.y })
|
||||
onReleased: {
|
||||
if (currentItem && currentItem.__menuItem.enabled) {
|
||||
if (currentItem.styleData.type === MenuItemType.Menu) {
|
||||
showCurrentItemSubMenu(true)
|
||||
} else {
|
||||
content.triggered(currentItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
if (currentItem && !currentItem.__menuItem.__popupVisible) {
|
||||
currentItem = null
|
||||
__menu.__currentIndex = -1
|
||||
}
|
||||
}
|
||||
|
||||
MenuContentScroller {
|
||||
id: upScroller
|
||||
direction: Qt.UpArrow
|
||||
visible: shouldUseScrollers && !list.atYBeginning
|
||||
function scrollABit() { list.contentY -= itemHeight }
|
||||
}
|
||||
|
||||
MenuContentScroller {
|
||||
id: downScroller
|
||||
direction: Qt.DownArrow
|
||||
visible: shouldUseScrollers && !list.atYEnd
|
||||
function scrollABit() { list.contentY += itemHeight }
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 1
|
||||
running: true
|
||||
repeat: false
|
||||
onTriggered: list.positionViewAtIndex(currentIndex, !scrollView.__style
|
||||
? ListView.Center : ListView.Beginning)
|
||||
}
|
||||
|
||||
Qml.Binding {
|
||||
target: scrollView.__verticalScrollBar
|
||||
property: "singleStep"
|
||||
value: itemHeight
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
Item {
|
||||
id: contentItem
|
||||
property real minimumWidth: __calcMinimum('Width')
|
||||
property real minimumHeight: __calcMinimum('Height')
|
||||
property real maximumWidth: Number.POSITIVE_INFINITY
|
||||
property real maximumHeight: Number.POSITIVE_INFINITY
|
||||
implicitWidth: __calcImplicitWidth()
|
||||
implicitHeight: __calcImplicitHeight()
|
||||
|
||||
/*! \internal */
|
||||
property Item __layoutItem: contentItem.visibleChildren.length === 1 ? contentItem.visibleChildren[0] : null
|
||||
/*! \internal */
|
||||
property real __marginsWidth: __layoutItem ? __layoutItem.anchors.leftMargin + __layoutItem.anchors.rightMargin : 0
|
||||
/*! \internal */
|
||||
property real __marginsHeight: __layoutItem ? __layoutItem.anchors.topMargin + __layoutItem.anchors.bottomMargin : 0
|
||||
|
||||
/*! \internal */
|
||||
property bool __noMinimumWidthGiven : false
|
||||
/*! \internal */
|
||||
property bool __noMinimumHeightGiven : false
|
||||
/*! \internal */
|
||||
property bool __noImplicitWidthGiven : false
|
||||
/*! \internal */
|
||||
property bool __noImplicitHeightGiven : false
|
||||
|
||||
function __calcImplicitWidth() {
|
||||
if (__layoutItem && __layoutItem.anchors.fill)
|
||||
return __calcImplicit('Width')
|
||||
return contentItem.childrenRect.x + contentItem.childrenRect.width
|
||||
}
|
||||
|
||||
function __calcImplicitHeight() {
|
||||
if (__layoutItem && __layoutItem.anchors.fill)
|
||||
return __calcImplicit('Height')
|
||||
return contentItem.childrenRect.y + contentItem.childrenRect.height
|
||||
}
|
||||
|
||||
function __calcImplicit(hw) {
|
||||
var pref = __layoutItem.Layout['preferred' + hw]
|
||||
if (pref < 0) {
|
||||
pref = __layoutItem['implicit' + hw]
|
||||
}
|
||||
contentItem['__noImplicit' + hw + 'Given'] = (pref === 0 ? true : false)
|
||||
pref += contentItem['__margins' + hw]
|
||||
return pref
|
||||
}
|
||||
|
||||
function __calcMinimum(hw) { // hw is 'Width' or 'Height'
|
||||
return (__layoutItem && __layoutItem.anchors.fill) ? __calcMinMax('minimum', hw) : 0
|
||||
}
|
||||
|
||||
function __calcMaximum(hw) { // hw is 'Width' or 'Height'
|
||||
return (__layoutItem && __layoutItem.anchors.fill) ? __calcMinMax('maximum', hw) : Number.POSITIVE_INFINITY
|
||||
}
|
||||
|
||||
function __calcMinMax(minMaxConstraint, hw) {
|
||||
var attachedPropName = minMaxConstraint + hw
|
||||
var extent = __layoutItem.Layout[attachedPropName]
|
||||
|
||||
if (minMaxConstraint === 'minimum')
|
||||
contentItem['__noMinimum' + hw + 'Given'] = (extent === 0 ? true : false)
|
||||
|
||||
extent += contentItem['__margins' + hw]
|
||||
return extent
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
|
||||
/*!
|
||||
\qmltype Control
|
||||
\internal
|
||||
\qmlabstract
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
FocusScope {
|
||||
id: root
|
||||
|
||||
/*! \qmlproperty Component Control::style
|
||||
|
||||
The style Component for this control.
|
||||
\sa {Qt Quick Controls Styles QML Types}
|
||||
|
||||
*/
|
||||
property Component style
|
||||
|
||||
/*! \internal */
|
||||
property QtObject __style: styleLoader.item
|
||||
|
||||
/*! \internal */
|
||||
property Item __panel: panelLoader.item
|
||||
|
||||
/*! \internal */
|
||||
property var styleHints
|
||||
|
||||
implicitWidth: __panel ? __panel.implicitWidth: 0
|
||||
implicitHeight: __panel ? __panel.implicitHeight: 0
|
||||
baselineOffset: __panel ? __panel.baselineOffset: 0
|
||||
activeFocusOnTab: false
|
||||
|
||||
/*! \internal */
|
||||
property alias __styleData: styleLoader.styleData
|
||||
|
||||
Loader {
|
||||
id: styleLoader
|
||||
sourceComponent: style
|
||||
property Item __control: root
|
||||
property QtObject styleData: null
|
||||
onStatusChanged: {
|
||||
if (status === Loader.Error)
|
||||
console.error("Failed to load Style for", root)
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: panelLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: __style ? __style.panel : null
|
||||
onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", root)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
Loader {
|
||||
property Item control
|
||||
property Item input
|
||||
property Item cursorHandle
|
||||
property Item selectionHandle
|
||||
property Flickable flickable
|
||||
property Component defaultMenu: item && item.defaultMenu ? item.defaultMenu : null
|
||||
property QtObject menuInstance: null
|
||||
property MouseArea mouseArea
|
||||
property QtObject style: __style
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
function onMenuChanged() {
|
||||
if (menuInstance !== null) {
|
||||
menuInstance.destroy()
|
||||
menuInstance = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getMenuInstance()
|
||||
{
|
||||
// Lazy load menu when first requested
|
||||
if (!menuInstance && control.menu) {
|
||||
menuInstance = control.menu.createObject(input);
|
||||
}
|
||||
return menuInstance;
|
||||
}
|
||||
|
||||
function syncStyle() {
|
||||
if (!style)
|
||||
return;
|
||||
|
||||
if (style.__editMenu)
|
||||
sourceComponent = style.__editMenu;
|
||||
else {
|
||||
// todo: get ios/android/base menus from style as well
|
||||
source = (Qt.resolvedUrl(Qt.platform.os === "ios" ? ""
|
||||
: Qt.platform.os === "android" ? "" : "EditMenu_base.qml"));
|
||||
}
|
||||
}
|
||||
onStyleChanged: syncStyle();
|
||||
Component.onCompleted: syncStyle();
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
Item {
|
||||
id: editMenuBase
|
||||
anchors.fill: parent
|
||||
|
||||
Component {
|
||||
id: undoAction
|
||||
Action {
|
||||
text: qsTr("&Undo")
|
||||
shortcut: StandardKey.Undo
|
||||
iconName: "edit-undo"
|
||||
enabled: input.canUndo
|
||||
onTriggered: input.undo()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: redoAction
|
||||
Action {
|
||||
text: qsTr("&Redo")
|
||||
shortcut: StandardKey.Redo
|
||||
iconName: "edit-redo"
|
||||
enabled: input.canRedo
|
||||
onTriggered: input.redo()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: cutAction
|
||||
Action {
|
||||
text: qsTr("Cu&t")
|
||||
shortcut: StandardKey.Cut
|
||||
iconName: "edit-cut"
|
||||
enabled: !input.readOnly && selectionStart !== selectionEnd
|
||||
onTriggered: {
|
||||
input.cut();
|
||||
input.select(input.cursorPosition, input.cursorPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: copyAction
|
||||
Action {
|
||||
text: qsTr("&Copy")
|
||||
shortcut: StandardKey.Copy
|
||||
iconName: "edit-copy"
|
||||
enabled: input.selectionStart !== input.selectionEnd
|
||||
onTriggered: {
|
||||
input.copy();
|
||||
input.select(input.cursorPosition, input.cursorPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: pasteAction
|
||||
Action {
|
||||
text: qsTr("&Paste")
|
||||
shortcut: StandardKey.Paste
|
||||
iconName: "edit-paste"
|
||||
enabled: input.canPaste
|
||||
onTriggered: input.paste()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: deleteAction
|
||||
Action {
|
||||
text: qsTr("Delete")
|
||||
shortcut: StandardKey.Delete
|
||||
iconName: "edit-delete"
|
||||
enabled: !input.readOnly && input.selectionStart !== input.selectionEnd
|
||||
onTriggered: input.remove(input.selectionStart, input.selectionEnd)
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: clearAction
|
||||
Action {
|
||||
text: qsTr("Clear")
|
||||
shortcut: StandardKey.DeleteCompleteLine
|
||||
iconName: "edit-clear"
|
||||
enabled: !input.readOnly && input.length > 0
|
||||
onTriggered: input.remove(0, input.length)
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: selectAllAction
|
||||
Action {
|
||||
text: qsTr("Select All")
|
||||
shortcut: StandardKey.SelectAll
|
||||
enabled: !(input.selectionStart === 0 && input.selectionEnd === input.length)
|
||||
onTriggered: input.selectAll()
|
||||
}
|
||||
}
|
||||
|
||||
property Component defaultMenu: Menu {
|
||||
MenuItem { action: undoAction.createObject(editMenuBase) }
|
||||
MenuItem { action: redoAction.createObject(editMenuBase) }
|
||||
MenuSeparator {}
|
||||
MenuItem { action: cutAction.createObject(editMenuBase) }
|
||||
MenuItem { action: copyAction.createObject(editMenuBase) }
|
||||
MenuItem { action: pasteAction.createObject(editMenuBase) }
|
||||
MenuItem { action: deleteAction.createObject(editMenuBase) }
|
||||
MenuItem { action: clearAction.createObject(editMenuBase) }
|
||||
MenuSeparator {}
|
||||
MenuItem { action: selectAllAction.createObject(editMenuBase) }
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: mouseArea
|
||||
|
||||
function onClicked() {
|
||||
if (input.selectionStart === input.selectionEnd) {
|
||||
var cursorPos = input.positionAt(mouse.x, mouse.y)
|
||||
input.moveHandles(cursorPos, cursorPos)
|
||||
}
|
||||
|
||||
input.activate()
|
||||
|
||||
if (control.menu) {
|
||||
var menu = getMenuInstance();
|
||||
menu.__dismissAndDestroy();
|
||||
var menuPos = mapToItem(null, mouse.x, mouse.y)
|
||||
menu.__popup(Qt.rect(menuPos.x, menuPos.y, 0, 0), -1, MenuPrivate.EditMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.4
|
||||
|
||||
Item {
|
||||
id: rootItem
|
||||
property variant source
|
||||
property real spread: 0.0
|
||||
property real blur: 0.0
|
||||
property color color: "white"
|
||||
property bool transparentBorder: false
|
||||
property bool cached: false
|
||||
|
||||
SourceProxy {
|
||||
id: sourceProxy
|
||||
input: rootItem.source
|
||||
}
|
||||
|
||||
ShaderEffectSource {
|
||||
id: cacheItem
|
||||
anchors.fill: shaderItem
|
||||
visible: rootItem.cached
|
||||
smooth: true
|
||||
sourceItem: shaderItem
|
||||
live: true
|
||||
hideSource: visible
|
||||
}
|
||||
|
||||
property string __internalBlurVertexShader: "qrc:/QtQuick/Controls/Shaders/blur.vert"
|
||||
|
||||
property string __internalBlurFragmentShader: "qrc:/QtQuick/Controls/Shaders/blur.frag"
|
||||
|
||||
ShaderEffect {
|
||||
id: level0
|
||||
property variant source: sourceProxy.output
|
||||
anchors.fill: parent
|
||||
visible: false
|
||||
smooth: true
|
||||
}
|
||||
|
||||
ShaderEffectSource {
|
||||
id: level1
|
||||
width: Math.ceil(shaderItem.width / 32) * 32
|
||||
height: Math.ceil(shaderItem.height / 32) * 32
|
||||
sourceItem: level0
|
||||
hideSource: rootItem.visible
|
||||
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0,0,0,0)
|
||||
smooth: true
|
||||
visible: false
|
||||
}
|
||||
|
||||
ShaderEffect {
|
||||
id: effect1
|
||||
property variant source: level1
|
||||
property real yStep: 1/height
|
||||
property real xStep: 1/width
|
||||
anchors.fill: level2
|
||||
visible: false
|
||||
smooth: true
|
||||
vertexShader: __internalBlurVertexShader
|
||||
fragmentShader: __internalBlurFragmentShader
|
||||
}
|
||||
|
||||
ShaderEffectSource {
|
||||
id: level2
|
||||
width: level1.width / 2
|
||||
height: level1.height / 2
|
||||
sourceItem: effect1
|
||||
hideSource: rootItem.visible
|
||||
visible: false
|
||||
smooth: true
|
||||
}
|
||||
|
||||
ShaderEffect {
|
||||
id: effect2
|
||||
property variant source: level2
|
||||
property real yStep: 1/height
|
||||
property real xStep: 1/width
|
||||
anchors.fill: level3
|
||||
visible: false
|
||||
smooth: true
|
||||
vertexShader: __internalBlurVertexShader
|
||||
fragmentShader: __internalBlurFragmentShader
|
||||
}
|
||||
|
||||
ShaderEffectSource {
|
||||
id: level3
|
||||
width: level2.width / 2
|
||||
height: level2.height / 2
|
||||
sourceItem: effect2
|
||||
hideSource: rootItem.visible
|
||||
visible: false
|
||||
smooth: true
|
||||
}
|
||||
|
||||
ShaderEffect {
|
||||
id: effect3
|
||||
property variant source: level3
|
||||
property real yStep: 1/height
|
||||
property real xStep: 1/width
|
||||
anchors.fill: level4
|
||||
visible: false
|
||||
smooth: true
|
||||
vertexShader: __internalBlurVertexShader
|
||||
fragmentShader: __internalBlurFragmentShader
|
||||
}
|
||||
|
||||
ShaderEffectSource {
|
||||
id: level4
|
||||
width: level3.width / 2
|
||||
height: level3.height / 2
|
||||
sourceItem: effect3
|
||||
hideSource: rootItem.visible
|
||||
visible: false
|
||||
smooth: true
|
||||
}
|
||||
|
||||
ShaderEffect {
|
||||
id: effect4
|
||||
property variant source: level4
|
||||
property real yStep: 1/height
|
||||
property real xStep: 1/width
|
||||
anchors.fill: level5
|
||||
visible: false
|
||||
smooth: true
|
||||
vertexShader: __internalBlurVertexShader
|
||||
fragmentShader: __internalBlurFragmentShader
|
||||
}
|
||||
|
||||
ShaderEffectSource {
|
||||
id: level5
|
||||
width: level4.width / 2
|
||||
height: level4.height / 2
|
||||
sourceItem: effect4
|
||||
hideSource: rootItem.visible
|
||||
visible: false
|
||||
smooth: true
|
||||
}
|
||||
|
||||
ShaderEffect {
|
||||
id: effect5
|
||||
property variant source: level5
|
||||
property real yStep: 1/height
|
||||
property real xStep: 1/width
|
||||
anchors.fill: level6
|
||||
visible: false
|
||||
smooth: true
|
||||
vertexShader: __internalBlurVertexShader
|
||||
fragmentShader: __internalBlurFragmentShader
|
||||
}
|
||||
|
||||
ShaderEffectSource {
|
||||
id: level6
|
||||
width: level5.width / 2
|
||||
height: level5.height / 2
|
||||
sourceItem: effect5
|
||||
hideSource: rootItem.visible
|
||||
visible: false
|
||||
smooth: true
|
||||
}
|
||||
|
||||
Item {
|
||||
id: dummysource
|
||||
width: 1
|
||||
height: 1
|
||||
visible: false
|
||||
}
|
||||
|
||||
ShaderEffectSource {
|
||||
id: dummy
|
||||
width: 1
|
||||
height: 1
|
||||
sourceItem: dummysource
|
||||
visible: false
|
||||
smooth: false
|
||||
live: false
|
||||
}
|
||||
|
||||
ShaderEffect {
|
||||
id: shaderItem
|
||||
x: transparentBorder ? -64 : 0
|
||||
y: transparentBorder ? -64 : 0
|
||||
width: transparentBorder ? parent.width + 128 : parent.width
|
||||
height: transparentBorder ? parent.height + 128 : parent.height
|
||||
|
||||
property variant source1: level1
|
||||
property variant source2: level2
|
||||
property variant source3: level3
|
||||
property variant source4: level4
|
||||
property variant source5: level5
|
||||
property variant source6: level6
|
||||
property real lod: rootItem.blur
|
||||
|
||||
property real weight1;
|
||||
property real weight2;
|
||||
property real weight3;
|
||||
property real weight4;
|
||||
property real weight5;
|
||||
property real weight6;
|
||||
|
||||
property real spread: 1.0 - (rootItem.spread * 0.98)
|
||||
property alias color: rootItem.color
|
||||
|
||||
function weight(v) {
|
||||
if (v <= 0.0)
|
||||
return 1
|
||||
if (v >= 0.5)
|
||||
return 0
|
||||
|
||||
return 1.0 - v / 0.5
|
||||
}
|
||||
|
||||
function calculateWeights() {
|
||||
|
||||
var w1 = weight(Math.abs(lod - 0.100))
|
||||
var w2 = weight(Math.abs(lod - 0.300))
|
||||
var w3 = weight(Math.abs(lod - 0.500))
|
||||
var w4 = weight(Math.abs(lod - 0.700))
|
||||
var w5 = weight(Math.abs(lod - 0.900))
|
||||
var w6 = weight(Math.abs(lod - 1.100))
|
||||
|
||||
var sum = w1 + w2 + w3 + w4 + w5 + w6;
|
||||
weight1 = w1 / sum;
|
||||
weight2 = w2 / sum;
|
||||
weight3 = w3 / sum;
|
||||
weight4 = w4 / sum;
|
||||
weight5 = w5 / sum;
|
||||
weight6 = w6 / sum;
|
||||
|
||||
upateSources()
|
||||
}
|
||||
|
||||
function upateSources() {
|
||||
var sources = new Array();
|
||||
var weights = new Array();
|
||||
|
||||
if (weight1 > 0) {
|
||||
sources.push(level1)
|
||||
weights.push(weight1)
|
||||
}
|
||||
|
||||
if (weight2 > 0) {
|
||||
sources.push(level2)
|
||||
weights.push(weight2)
|
||||
}
|
||||
|
||||
if (weight3 > 0) {
|
||||
sources.push(level3)
|
||||
weights.push(weight3)
|
||||
}
|
||||
|
||||
if (weight4 > 0) {
|
||||
sources.push(level4)
|
||||
weights.push(weight4)
|
||||
}
|
||||
|
||||
if (weight5 > 0) {
|
||||
sources.push(level5)
|
||||
weights.push(weight5)
|
||||
}
|
||||
|
||||
if (weight6 > 0) {
|
||||
sources.push(level6)
|
||||
weights.push(weight6)
|
||||
}
|
||||
|
||||
for (var j = sources.length; j < 6; j++) {
|
||||
sources.push(dummy)
|
||||
weights.push(0.0)
|
||||
}
|
||||
|
||||
source1 = sources[0]
|
||||
source2 = sources[1]
|
||||
source3 = sources[2]
|
||||
source4 = sources[3]
|
||||
source5 = sources[4]
|
||||
source6 = sources[5]
|
||||
|
||||
weight1 = weights[0]
|
||||
weight2 = weights[1]
|
||||
weight3 = weights[2]
|
||||
weight4 = weights[3]
|
||||
weight5 = weights[4]
|
||||
weight6 = weights[5]
|
||||
}
|
||||
|
||||
Component.onCompleted: calculateWeights()
|
||||
|
||||
onLodChanged: calculateWeights()
|
||||
|
||||
fragmentShader: "qrc:/QtQuick/Controls/Shaders/glow.frag"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype FocusFrame
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
Item {
|
||||
id: root
|
||||
activeFocusOnTab: false
|
||||
Accessible.role: Accessible.StatusBar
|
||||
|
||||
anchors.topMargin: focusMargin
|
||||
anchors.leftMargin: focusMargin
|
||||
anchors.rightMargin: focusMargin
|
||||
anchors.bottomMargin: focusMargin
|
||||
|
||||
property int focusMargin: loader.item ? loader.item.margin : -3
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
z: 2
|
||||
anchors.fill: parent
|
||||
sourceComponent: Settings.styleComponent(Settings.style, "FocusFrameStyle.qml", root)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
Item {
|
||||
id: button
|
||||
property alias source: image.source
|
||||
signal clicked
|
||||
|
||||
Rectangle {
|
||||
id: fillRect
|
||||
anchors.fill: parent
|
||||
color: "black"
|
||||
opacity: mouse.pressed ? 0.07 : mouse.containsMouse ? 0.02 : 0.0
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
border.color: gridColor
|
||||
anchors.fill: parent
|
||||
anchors.margins: -1
|
||||
color: "transparent"
|
||||
opacity: fillRect.opacity * 10
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image
|
||||
width: Math.min(implicitWidth, parent.width * 0.4)
|
||||
height: Math.min(implicitHeight, parent.height * 0.4)
|
||||
anchors.centerIn: parent
|
||||
fillMode: Image.PreserveAspectFit
|
||||
opacity: 0.6
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouse
|
||||
anchors.fill: parent
|
||||
onClicked: button.clicked()
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQml 2.14 as Qml
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
Loader {
|
||||
id: menuFrameLoader
|
||||
|
||||
property var __menu
|
||||
|
||||
Accessible.role: Accessible.PopupMenu
|
||||
|
||||
visible: status === Loader.Ready
|
||||
width: content.width + (d.style ? d.style.padding.left + d.style.padding.right : 0)
|
||||
height: content.height + (d.style ? d.style.padding.top + d.style.padding.bottom : 0)
|
||||
|
||||
Loader {
|
||||
id: styleLoader
|
||||
active: !__menu.isNative
|
||||
sourceComponent: __menu.style
|
||||
property alias __control: menuFrameLoader
|
||||
onStatusChanged: {
|
||||
if (status === Loader.Error)
|
||||
console.error("Failed to load Style for", __menu)
|
||||
}
|
||||
}
|
||||
sourceComponent: d.style ? d.style.frame : undefined
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property var mnemonicsMap: ({})
|
||||
readonly property Style style: styleLoader.item
|
||||
readonly property Component menuItemPanel: style ? style.menuItemPanel : null
|
||||
|
||||
function canBeHovered(index) {
|
||||
var item = content.menuItemAt(index)
|
||||
if (item && item.visible && item.styleData.type !== MenuItemType.Separator && item.styleData.enabled) {
|
||||
__menu.__currentIndex = index
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function triggerCurrent() {
|
||||
var item = content.menuItemAt(__menu.__currentIndex)
|
||||
if (item)
|
||||
triggerAndDismiss(item)
|
||||
}
|
||||
|
||||
function triggerAndDismiss(item) {
|
||||
if (!item)
|
||||
return;
|
||||
if (item.styleData.type === MenuItemType.Separator)
|
||||
__menu.__dismissAndDestroy()
|
||||
else if (item.styleData.type === MenuItemType.Item)
|
||||
item.__menuItem.trigger()
|
||||
}
|
||||
}
|
||||
|
||||
focus: true
|
||||
|
||||
Keys.onPressed: {
|
||||
var item = null
|
||||
if (!(event.modifiers & Qt.AltModifier)
|
||||
&& (item = d.mnemonicsMap[event.text.toUpperCase()])) {
|
||||
if (item.styleData.type === MenuItemType.Menu) {
|
||||
__menu.__currentIndex = item.__menuItemIndex
|
||||
item.__showSubMenu(true)
|
||||
item.__menuItem.__currentIndex = 0
|
||||
} else {
|
||||
d.triggerAndDismiss(item)
|
||||
}
|
||||
event.accepted = true
|
||||
} else {
|
||||
event.accepted = false
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onEscapePressed: __menu.__dismissAndDestroy()
|
||||
|
||||
Keys.onDownPressed: {
|
||||
if (__menu.__currentIndex < 0)
|
||||
__menu.__currentIndex = -1
|
||||
|
||||
for (var i = __menu.__currentIndex + 1;
|
||||
i < __menu.items.length && !d.canBeHovered(i); i++)
|
||||
;
|
||||
event.accepted = true
|
||||
}
|
||||
|
||||
Keys.onUpPressed: {
|
||||
for (var i = __menu.__currentIndex - 1;
|
||||
i >= 0 && !d.canBeHovered(i); i--)
|
||||
;
|
||||
event.accepted = true
|
||||
}
|
||||
|
||||
Keys.onLeftPressed: {
|
||||
if ((event.accepted = __menu.__parentMenu.hasOwnProperty("title")))
|
||||
__menu.__closeAndDestroy()
|
||||
}
|
||||
|
||||
Keys.onRightPressed: {
|
||||
var item = content.menuItemAt(__menu.__currentIndex)
|
||||
if (item && item.styleData.type === MenuItemType.Menu
|
||||
&& !item.__menuItem.__popupVisible) {
|
||||
item.__showSubMenu(true)
|
||||
item.__menuItem.__currentIndex = 0
|
||||
event.accepted = true
|
||||
} else {
|
||||
event.accepted = false
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onSpacePressed: d.triggerCurrent()
|
||||
Keys.onReturnPressed: d.triggerCurrent()
|
||||
Keys.onEnterPressed: d.triggerCurrent()
|
||||
|
||||
Qml.Binding {
|
||||
// Make sure the styled frame is in the background
|
||||
target: item
|
||||
property: "z"
|
||||
value: content.z - 1
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
ColumnMenuContent {
|
||||
id: content
|
||||
x: d.style ? d.style.padding.left : 0
|
||||
y: d.style ? d.style.padding.top : 0
|
||||
menuItemDelegate: menuItemComponent
|
||||
scrollIndicatorStyle: d.style && d.style.scrollIndicator || null
|
||||
scrollerStyle: d.style && d.style.__scrollerStyle
|
||||
itemsModel: __menu.items
|
||||
minWidth: __menu.__minimumWidth
|
||||
maxHeight: d.style ? d.style.__maxPopupHeight : 0
|
||||
onTriggered: d.triggerAndDismiss(item)
|
||||
}
|
||||
|
||||
Component {
|
||||
id: menuItemComponent
|
||||
Loader {
|
||||
id: menuItemLoader
|
||||
|
||||
Accessible.role: opts.type === MenuItemType.Item || opts.type === MenuItemType.Menu ?
|
||||
Accessible.MenuItem : Accessible.NoRole
|
||||
Accessible.name: StyleHelpers.removeMnemonics(opts.text)
|
||||
Accessible.checkable: opts.checkable
|
||||
Accessible.checked: opts.checked
|
||||
Accessible.onPressAction: {
|
||||
if (opts.type === MenuItemType.Item) {
|
||||
d.triggerAndDismiss(menuItemLoader)
|
||||
} else if (opts.type === MenuItemType.Menu) {
|
||||
__showSubMenu(true /*immediately*/)
|
||||
}
|
||||
}
|
||||
|
||||
property QtObject styleData: QtObject {
|
||||
id: opts
|
||||
readonly property int index: __menuItemIndex
|
||||
readonly property int type: __menuItem ? __menuItem.type : -1
|
||||
readonly property bool selected: type !== MenuItemType.Separator && __menu.__currentIndex === index
|
||||
readonly property bool pressed: type !== MenuItemType.Separator && __menu.__currentIndex === index
|
||||
&& content.mousePressed // TODO Add key pressed condition once we get delayed menu closing
|
||||
readonly property string text: type === MenuItemType.Menu ? __menuItem.title :
|
||||
type !== MenuItemType.Separator ? __menuItem.text : ""
|
||||
readonly property bool underlineMnemonic: __menu.__contentItem.altPressed
|
||||
readonly property string shortcut: !!__menuItem && __menuItem["shortcut"] || ""
|
||||
readonly property var iconSource: !!__menuItem && __menuItem["iconSource"] || undefined
|
||||
readonly property bool enabled: type !== MenuItemType.Separator && !!__menuItem && __menuItem.enabled
|
||||
readonly property bool checked: !!__menuItem && !!__menuItem["checked"]
|
||||
readonly property bool checkable: !!__menuItem && !!__menuItem["checkable"]
|
||||
readonly property bool exclusive: !!__menuItem && !!__menuItem["exclusiveGroup"]
|
||||
readonly property int scrollerDirection: Qt.NoArrow
|
||||
}
|
||||
|
||||
readonly property var __menuItem: modelData
|
||||
readonly property int __menuItemIndex: index
|
||||
|
||||
sourceComponent: d.menuItemPanel
|
||||
enabled: visible && opts.enabled
|
||||
visible: !!__menuItem && __menuItem.visible
|
||||
active: visible
|
||||
|
||||
function __showSubMenu(immediately) {
|
||||
if (!__menuItem.enabled)
|
||||
return;
|
||||
if (immediately) {
|
||||
if (__menu.__currentIndex === __menuItemIndex) {
|
||||
if (__menuItem.__usingDefaultStyle)
|
||||
__menuItem.style = __menu.style
|
||||
__menuItem.__popup(Qt.rect(menuFrameLoader.width - (d.style.submenuOverlap + d.style.padding.right), -d.style.padding.top, 0, 0), -1)
|
||||
}
|
||||
} else {
|
||||
openMenuTimer.start()
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: openMenuTimer
|
||||
interval: d.style.submenuPopupDelay
|
||||
onTriggered: menuItemLoader.__showSubMenu(true)
|
||||
}
|
||||
|
||||
function __closeSubMenu() {
|
||||
if (openMenuTimer.running)
|
||||
openMenuTimer.stop()
|
||||
else if (__menuItem.__popupVisible)
|
||||
closeMenuTimer.start()
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: closeMenuTimer
|
||||
interval: 1
|
||||
onTriggered: {
|
||||
if (__menu.__currentIndex !== __menuItemIndex)
|
||||
__menuItem.__closeAndDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
onLoaded: {
|
||||
__menuItem.__visualItem = menuItemLoader
|
||||
|
||||
if (content.width < item.implicitWidth)
|
||||
content.width = item.implicitWidth
|
||||
|
||||
var title = opts.text
|
||||
var ampersandPos = title.indexOf("&")
|
||||
if (ampersandPos !== -1)
|
||||
d.mnemonicsMap[title[ampersandPos + 1].toUpperCase()] = menuItemLoader
|
||||
}
|
||||
|
||||
Qml.Binding {
|
||||
target: menuItemLoader.item
|
||||
property: "width"
|
||||
property alias menuItem: menuItemLoader.item
|
||||
value: menuItem ? Math.max(__menu.__minimumWidth, content.width) - 2 * menuItem.x : 0
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
MouseArea {
|
||||
id: scrollIndicator
|
||||
property int direction: 0
|
||||
|
||||
anchors {
|
||||
top: direction === Qt.UpArrow ? parent.top : undefined
|
||||
bottom: direction === Qt.DownArrow ? parent.bottom : undefined
|
||||
}
|
||||
|
||||
hoverEnabled: visible && Settings.hoverEnabled
|
||||
height: scrollerLoader.height
|
||||
width: parent.width
|
||||
|
||||
Loader {
|
||||
id: scrollerLoader
|
||||
|
||||
width: parent.width
|
||||
sourceComponent: scrollIndicatorStyle
|
||||
// Extra property values for desktop style
|
||||
property var __menuItem: null
|
||||
property var styleData: {
|
||||
"index": -1,
|
||||
"type": MenuItemType.ScrollIndicator,
|
||||
"text": "",
|
||||
"selected": scrollIndicator.containsMouse,
|
||||
"scrollerDirection": scrollIndicator.direction,
|
||||
"checkable": false,
|
||||
"checked": false,
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 100
|
||||
repeat: true
|
||||
triggeredOnStart: true
|
||||
running: parent.containsMouse
|
||||
onTriggered: scrollABit()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
QtObject {
|
||||
property Component background: null
|
||||
property Component label: null
|
||||
property Component submenuIndicator: null
|
||||
property Component shortcut: null
|
||||
property Component checkmarkIndicator: null
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
// KNOWN ISSUES
|
||||
// none
|
||||
|
||||
/*!
|
||||
\qmltype ModalPopupBehavior
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
Item {
|
||||
id: popupBehavior
|
||||
|
||||
property bool showing: false
|
||||
property bool whenAlso: true // modifier to the "showing" property
|
||||
property bool consumeCancelClick: true
|
||||
property int delay: 0 // delay before popout becomes visible
|
||||
property int deallocationDelay: 3000 // 3 seconds
|
||||
|
||||
property Component popupComponent
|
||||
|
||||
property alias popup: popupLoader.item // read-only
|
||||
property alias window: popupBehavior.root // read-only
|
||||
|
||||
signal prepareToShow
|
||||
signal prepareToHide
|
||||
signal cancelledByClick
|
||||
|
||||
// implementation
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
onShowingChanged: notifyChange()
|
||||
onWhenAlsoChanged: notifyChange()
|
||||
function notifyChange() {
|
||||
if(showing && whenAlso) {
|
||||
if(popupLoader.sourceComponent == undefined) {
|
||||
popupLoader.sourceComponent = popupComponent;
|
||||
}
|
||||
} else {
|
||||
mouseArea.enabled = false; // disable before opacity is changed in case it has fading behavior
|
||||
if(Qt.isQtObject(popupLoader.item)) {
|
||||
popupBehavior.prepareToHide();
|
||||
popupLoader.item.opacity = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property Item root: findRoot()
|
||||
function findRoot() {
|
||||
var p = parent;
|
||||
while(p.parent != undefined)
|
||||
p = p.parent;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
enabled: false // enabled only when popout is showing
|
||||
onPressed: {
|
||||
popupBehavior.showing = false;
|
||||
mouse.accepted = consumeCancelClick;
|
||||
cancelledByClick();
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: popupLoader
|
||||
}
|
||||
|
||||
Timer { // visibility timer
|
||||
running: Qt.isQtObject(popupLoader.item) && showing && whenAlso
|
||||
interval: delay
|
||||
onTriggered: {
|
||||
popupBehavior.prepareToShow();
|
||||
mouseArea.enabled = true;
|
||||
popup.opacity = 1;
|
||||
}
|
||||
}
|
||||
|
||||
Timer { // deallocation timer
|
||||
running: Qt.isQtObject(popupLoader.item) && popupLoader.item.opacity == 0
|
||||
interval: deallocationDelay
|
||||
onTriggered: popupLoader.sourceComponent = undefined
|
||||
}
|
||||
|
||||
states: State {
|
||||
name: "active"
|
||||
when: Qt.isQtObject(popupLoader.item) && popupLoader.item.opacity > 0
|
||||
ParentChange { target: popupBehavior; parent: root }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype ScrollBar
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
Item {
|
||||
id: scrollbar
|
||||
|
||||
property bool isTransient: false
|
||||
property bool active: false
|
||||
property int orientation: Qt.Horizontal
|
||||
property alias minimumValue: slider.minimumValue
|
||||
property alias maximumValue: slider.maximumValue
|
||||
property alias value: slider.value
|
||||
property int singleStep: 20
|
||||
|
||||
activeFocusOnTab: false
|
||||
|
||||
Accessible.role: Accessible.ScrollBar
|
||||
implicitWidth: panelLoader.implicitWidth
|
||||
implicitHeight: panelLoader.implicitHeight
|
||||
|
||||
property bool upPressed
|
||||
property bool downPressed
|
||||
property bool pageUpPressed
|
||||
property bool pageDownPressed
|
||||
property bool handlePressed
|
||||
|
||||
|
||||
property Item __panel: panelLoader.item
|
||||
Loader {
|
||||
id: panelLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: __style ? __style.__scrollbar : null
|
||||
onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", root)
|
||||
property alias __control: scrollbar
|
||||
property QtObject __styleData: QtObject {
|
||||
readonly property alias horizontal: internal.horizontal
|
||||
readonly property alias upPressed: scrollbar.upPressed
|
||||
readonly property alias downPressed: scrollbar.downPressed
|
||||
readonly property alias handlePressed: scrollbar.handlePressed
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: internal
|
||||
property bool horizontal: orientation === Qt.Horizontal
|
||||
property int pageStep: internal.horizontal ? width : height
|
||||
property bool scrollToClickposition: internal.scrollToClickPosition
|
||||
anchors.fill: parent
|
||||
cursorShape: __panel && __panel.visible ? Qt.ArrowCursor : Qt.IBeamCursor // forces a cursor change
|
||||
|
||||
property bool autoincrement: false
|
||||
property bool scrollToClickPosition: __style ? __style.scrollToClickedPosition : 0
|
||||
|
||||
// Update hover item
|
||||
onEntered: if (!pressed) __panel.activeControl = __panel.hitTest(mouseX, mouseY)
|
||||
onExited: if (!pressed) __panel.activeControl = "none"
|
||||
onMouseXChanged: if (!pressed) __panel.activeControl = __panel.hitTest(mouseX, mouseY)
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
preventStealing: true
|
||||
property var pressedX
|
||||
property var pressedY
|
||||
property int oldPosition
|
||||
property int grooveSize
|
||||
|
||||
Timer {
|
||||
running: upPressed || downPressed || pageUpPressed || pageDownPressed
|
||||
interval: 350
|
||||
onTriggered: internal.autoincrement = true
|
||||
}
|
||||
|
||||
Timer {
|
||||
running: internal.autoincrement
|
||||
interval: 60
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
if (upPressed && internal.containsMouse)
|
||||
internal.decrement();
|
||||
else if (downPressed && internal.containsMouse)
|
||||
internal.increment();
|
||||
else if (pageUpPressed)
|
||||
internal.decrementPage();
|
||||
else if (pageDownPressed)
|
||||
internal.incrementPage();
|
||||
}
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
if (handlePressed) {
|
||||
if (!horizontal)
|
||||
slider.position = oldPosition + (mouseY - pressedY)
|
||||
else
|
||||
slider.position = oldPosition + (mouseX - pressedX)
|
||||
}
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
if (mouse.source !== Qt.MouseEventNotSynthesized) {
|
||||
mouse.accepted = false
|
||||
return
|
||||
}
|
||||
__panel.activeControl = __panel.hitTest(mouseX, mouseY)
|
||||
scrollToClickposition = scrollToClickPosition
|
||||
var handleRect = __panel.subControlRect("handle")
|
||||
var grooveRect = __panel.subControlRect("groove")
|
||||
grooveSize = horizontal ? grooveRect.width - handleRect.width:
|
||||
grooveRect.height - handleRect.height;
|
||||
if (__panel.activeControl === "handle") {
|
||||
pressedX = mouseX;
|
||||
pressedY = mouseY;
|
||||
handlePressed = true;
|
||||
oldPosition = slider.position;
|
||||
} else if (__panel.activeControl === "up") {
|
||||
decrement();
|
||||
upPressed = Qt.binding(function() {return containsMouse});
|
||||
} else if (__panel.activeControl === "down") {
|
||||
increment();
|
||||
downPressed = Qt.binding(function() {return containsMouse});
|
||||
} else if (!scrollToClickposition){
|
||||
if (__panel.activeControl === "upPage") {
|
||||
decrementPage();
|
||||
pageUpPressed = true;
|
||||
} else if (__panel.activeControl === "downPage") {
|
||||
incrementPage();
|
||||
pageDownPressed = true;
|
||||
}
|
||||
} else { // scroll to click position
|
||||
slider.position = horizontal ? mouseX - handleRect.width/2 - grooveRect.x
|
||||
: mouseY - handleRect.height/2 - grooveRect.y
|
||||
pressedX = mouseX;
|
||||
pressedY = mouseY;
|
||||
handlePressed = true;
|
||||
oldPosition = slider.position;
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
__panel.activeControl = __panel.hitTest(mouseX, mouseY);
|
||||
autoincrement = false;
|
||||
upPressed = false;
|
||||
downPressed = false;
|
||||
handlePressed = false;
|
||||
pageUpPressed = false;
|
||||
pageDownPressed = false;
|
||||
}
|
||||
|
||||
onWheel: {
|
||||
var stepCount = -(wheel.angleDelta.x ? wheel.angleDelta.x : wheel.angleDelta.y) / 120
|
||||
if (stepCount != 0) {
|
||||
if (wheel.modifiers & Qt.ControlModifier || wheel.modifiers & Qt.ShiftModifier)
|
||||
incrementPage(stepCount)
|
||||
else
|
||||
increment(stepCount)
|
||||
}
|
||||
}
|
||||
|
||||
function incrementPage(stepCount) {
|
||||
value = boundValue(value + getSteps(pageStep, stepCount))
|
||||
}
|
||||
|
||||
function decrementPage(stepCount) {
|
||||
value = boundValue(value - getSteps(pageStep, stepCount))
|
||||
}
|
||||
|
||||
function increment(stepCount) {
|
||||
value = boundValue(value + getSteps(singleStep, stepCount))
|
||||
}
|
||||
|
||||
function decrement(stepCount) {
|
||||
value = boundValue(value - getSteps(singleStep, stepCount))
|
||||
}
|
||||
|
||||
function boundValue(val) {
|
||||
return Math.min(Math.max(val, minimumValue), maximumValue)
|
||||
}
|
||||
|
||||
function getSteps(step, count) {
|
||||
if (count)
|
||||
step *= count
|
||||
return step
|
||||
}
|
||||
|
||||
RangeModel {
|
||||
id: slider
|
||||
minimumValue: 0.0
|
||||
maximumValue: 1.0
|
||||
value: 0
|
||||
stepSize: 0.0
|
||||
inverted: false
|
||||
positionAtMaximum: internal.grooveSize
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQml 2.14 as Qml
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype ScrollViewHeader
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
Item {
|
||||
id: scrollHelper
|
||||
|
||||
property alias horizontalScrollBar: hscrollbar
|
||||
property alias verticalScrollBar: vscrollbar
|
||||
property bool blockUpdates: false
|
||||
property int availableHeight
|
||||
property int availableWidth
|
||||
property int contentHeight
|
||||
property int contentWidth
|
||||
property bool active
|
||||
property int horizontalScrollBarPolicy: Qt.ScrollBarAsNeeded
|
||||
property int verticalScrollBarPolicy: Qt.ScrollBarAsNeeded
|
||||
|
||||
|
||||
property int leftMargin: outerFrame && root.__style ? root.__style.padding.left : 0
|
||||
property int rightMargin: outerFrame && root.__style ? root.__style.padding.right : 0
|
||||
property int topMargin: outerFrame && root.__style ? root.__style.padding.top : 0
|
||||
property int bottomMargin: outerFrame && root.__style ? root.__style.padding.bottom : 0
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
Timer {
|
||||
id: layoutTimer
|
||||
interval: 0;
|
||||
onTriggered: {
|
||||
blockUpdates = true;
|
||||
scrollHelper.contentWidth = flickableItem !== null ? flickableItem.contentWidth : 0
|
||||
scrollHelper.contentHeight = flickableItem !== null ? flickableItem.contentHeight : 0
|
||||
scrollHelper.availableWidth = viewport.width
|
||||
scrollHelper.availableHeight = viewport.height
|
||||
blockUpdates = false;
|
||||
hscrollbar.valueChanged();
|
||||
vscrollbar.valueChanged();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: viewport
|
||||
function onWidthChanged() { layoutTimer.running = true }
|
||||
function onHeightChanged() { layoutTimer.running = true }
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: flickableItem
|
||||
function onContentWidthChanged() { layoutTimer.running = true }
|
||||
function onContentHeightChanged() { layoutTimer.running = true }
|
||||
function onContentXChanged() {
|
||||
hscrollbar.flash()
|
||||
vscrollbar.flash()
|
||||
}
|
||||
function onContentYChanged() {
|
||||
hscrollbar.flash()
|
||||
vscrollbar.flash()
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: cornerFill
|
||||
z: 1
|
||||
sourceComponent: __style ? __style.corner : null
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: bottomMargin
|
||||
anchors.rightMargin: rightMargin
|
||||
width: visible ? vscrollbar.width : 0
|
||||
height: visible ? hscrollbar.height : 0
|
||||
visible: hscrollbar.visible && !hscrollbar.isTransient && vscrollbar.visible && !vscrollbar.isTransient
|
||||
}
|
||||
|
||||
ScrollBar {
|
||||
id: hscrollbar
|
||||
readonly property int scrollAmount: contentWidth - availableWidth
|
||||
readonly property bool scrollable: scrollAmount > 0
|
||||
isTransient: !!__panel && !!__panel.isTransient
|
||||
active: !!__panel && (__panel.sunken || __panel.activeControl !== "none")
|
||||
enabled: !isTransient || __panel.visible
|
||||
orientation: Qt.Horizontal
|
||||
visible: horizontalScrollBarPolicy == Qt.ScrollBarAsNeeded ? scrollable : horizontalScrollBarPolicy == Qt.ScrollBarAlwaysOn
|
||||
height: visible ? implicitHeight : 0
|
||||
z: 1
|
||||
maximumValue: scrollable ? scrollAmount : 0
|
||||
minimumValue: 0
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: cornerFill.left
|
||||
anchors.leftMargin: leftMargin
|
||||
anchors.bottomMargin: bottomMargin
|
||||
onScrollAmountChanged: {
|
||||
var scrollableAmount = scrollable ? scrollAmount : 0
|
||||
if (flickableItem && (flickableItem.atXBeginning || flickableItem.atXEnd)) {
|
||||
value = Math.min(scrollableAmount, flickableItem.contentX - flickableItem.originX);
|
||||
} else if (value > scrollableAmount) {
|
||||
value = scrollableAmount;
|
||||
}
|
||||
}
|
||||
onValueChanged: {
|
||||
if (flickableItem && !blockUpdates) {
|
||||
flickableItem.contentX = value + flickableItem.originX
|
||||
}
|
||||
}
|
||||
Qml.Binding {
|
||||
target: hscrollbar.__panel
|
||||
property: "raised"
|
||||
value: vscrollbar.active || scrollHelper.active
|
||||
when: hscrollbar.isTransient
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
Qml.Binding {
|
||||
target: hscrollbar.__panel
|
||||
property: "visible"
|
||||
value: true
|
||||
when: !hscrollbar.isTransient || scrollHelper.active
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
function flash() {
|
||||
if (hscrollbar.isTransient) {
|
||||
hscrollbar.__panel.on = true
|
||||
hscrollbar.__panel.visible = true
|
||||
hFlasher.start()
|
||||
}
|
||||
}
|
||||
Timer {
|
||||
id: hFlasher
|
||||
interval: 10
|
||||
onTriggered: hscrollbar.__panel.on = false
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar {
|
||||
id: vscrollbar
|
||||
readonly property int scrollAmount: contentHeight - availableHeight
|
||||
readonly property bool scrollable: scrollAmount > 0
|
||||
isTransient: !!__panel && !!__panel.isTransient
|
||||
active: !!__panel && (__panel.sunken || __panel.activeControl !== "none")
|
||||
enabled: !isTransient || __panel.visible
|
||||
orientation: Qt.Vertical
|
||||
visible: verticalScrollBarPolicy === Qt.ScrollBarAsNeeded ? scrollable : verticalScrollBarPolicy === Qt.ScrollBarAlwaysOn
|
||||
width: visible ? implicitWidth : 0
|
||||
z: 1
|
||||
anchors.bottom: cornerFill.top
|
||||
maximumValue: scrollable ? scrollAmount + __viewTopMargin : 0
|
||||
minimumValue: 0
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: __scrollBarTopMargin + topMargin
|
||||
anchors.rightMargin: rightMargin
|
||||
onScrollAmountChanged: {
|
||||
if (flickableItem && (flickableItem.atYBeginning || flickableItem.atYEnd)) {
|
||||
value = flickableItem.contentY - flickableItem.originY
|
||||
}
|
||||
}
|
||||
onValueChanged: {
|
||||
if (flickableItem && !blockUpdates && enabled) {
|
||||
flickableItem.contentY = value + flickableItem.originY
|
||||
}
|
||||
}
|
||||
Qml.Binding {
|
||||
target: vscrollbar.__panel
|
||||
property: "raised"
|
||||
value: hscrollbar.active || scrollHelper.active
|
||||
when: vscrollbar.isTransient
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
Qml.Binding {
|
||||
target: vscrollbar.__panel
|
||||
property: "visible"
|
||||
value: true
|
||||
when: !vscrollbar.isTransient || scrollHelper.active
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
function flash() {
|
||||
if (vscrollbar.isTransient) {
|
||||
vscrollbar.__panel.on = true
|
||||
vscrollbar.__panel.visible = true
|
||||
vFlasher.start()
|
||||
}
|
||||
}
|
||||
Timer {
|
||||
id: vFlasher
|
||||
interval: 10
|
||||
onTriggered: vscrollbar.__panel.on = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
Item {
|
||||
id: rootItem
|
||||
property variant input
|
||||
property variant output
|
||||
property variant sourceRect
|
||||
visible: false
|
||||
|
||||
Component.onCompleted: evaluateInput()
|
||||
|
||||
onInputChanged: evaluateInput()
|
||||
|
||||
onSourceRectChanged: evaluateInput()
|
||||
|
||||
function evaluateInput() {
|
||||
if (input == undefined) {
|
||||
output = input
|
||||
}
|
||||
else if (sourceRect != undefined && sourceRect != Qt.rect(0, 0, 0, 0) && !isQQuickShaderEffectSource(input)) {
|
||||
proxySource.sourceItem = input
|
||||
output = proxySource
|
||||
proxySource.sourceRect = sourceRect
|
||||
}
|
||||
else if (isQQuickItemLayerEnabled(input)) {
|
||||
output = input
|
||||
}
|
||||
else if ((isQQuickImage(input) && !hasTileMode(input) && !hasChildren(input))) {
|
||||
output = input
|
||||
}
|
||||
else if (isQQuickShaderEffectSource(input)) {
|
||||
output = input
|
||||
}
|
||||
else {
|
||||
proxySource.sourceItem = input
|
||||
output = proxySource
|
||||
proxySource.sourceRect = Qt.rect(0, 0, 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
function isQQuickItemLayerEnabled(item) {
|
||||
if (item.hasOwnProperty("layer")) {
|
||||
var l = item["layer"]
|
||||
if (l.hasOwnProperty("enabled") && l["enabled"].toString() == "true")
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function isQQuickImage(item) {
|
||||
var imageProperties = [ "fillMode", "progress", "asynchronous", "sourceSize", "status", "smooth" ]
|
||||
return hasProperties(item, imageProperties)
|
||||
}
|
||||
|
||||
function isQQuickShaderEffectSource(item) {
|
||||
var shaderEffectSourceProperties = [ "hideSource", "format", "sourceItem", "mipmap", "wrapMode", "live", "recursive", "sourceRect" ]
|
||||
return hasProperties(item, shaderEffectSourceProperties)
|
||||
}
|
||||
|
||||
function hasProperties(item, properties) {
|
||||
var counter = 0
|
||||
for (var j = 0; j < properties.length; j++) {
|
||||
if (item.hasOwnProperty(properties [j]))
|
||||
counter++
|
||||
}
|
||||
return properties.length == counter
|
||||
}
|
||||
|
||||
function hasChildren(item) {
|
||||
if (item.hasOwnProperty("childrenRect")) {
|
||||
if (item["childrenRect"].toString() != "QRectF(0, 0, 0, 0)")
|
||||
return true
|
||||
else
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function hasTileMode(item) {
|
||||
if (item.hasOwnProperty("fillMode")) {
|
||||
if (item["fillMode"].toString() != "0")
|
||||
return true
|
||||
else
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
ShaderEffectSource {
|
||||
id: proxySource
|
||||
live: rootItem.input != rootItem.output
|
||||
hideSource: false
|
||||
smooth: true
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
var stackView = [];
|
||||
|
||||
function push(p)
|
||||
{
|
||||
if (!p)
|
||||
return
|
||||
stackView.push(p)
|
||||
__depth++
|
||||
return p
|
||||
}
|
||||
|
||||
function pop()
|
||||
{
|
||||
if (stackView.length === 0)
|
||||
return null
|
||||
var p = stackView.pop()
|
||||
__depth--
|
||||
return p
|
||||
}
|
||||
|
||||
function current()
|
||||
{
|
||||
if (stackView.length === 0)
|
||||
return null
|
||||
return stackView[stackView.length-1]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
|
||||
/*!
|
||||
\qmltype StackViewSlideTransition
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
StackViewDelegate {
|
||||
id: root
|
||||
|
||||
property bool horizontal: true
|
||||
|
||||
function getTransition(properties)
|
||||
{
|
||||
return root[horizontal ? "horizontalSlide" : "verticalSlide"][properties.name]
|
||||
}
|
||||
|
||||
function transitionFinished(properties)
|
||||
{
|
||||
properties.exitItem.x = 0
|
||||
properties.exitItem.y = 0
|
||||
}
|
||||
|
||||
property QtObject horizontalSlide: QtObject {
|
||||
property Component pushTransition: StackViewTransition {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "x"
|
||||
from: target.width
|
||||
to: 0
|
||||
duration: 400
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "x"
|
||||
from: 0
|
||||
to: -target.width
|
||||
duration: 400
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
property Component popTransition: StackViewTransition {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "x"
|
||||
from: -target.width
|
||||
to: 0
|
||||
duration: 400
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "x"
|
||||
from: 0
|
||||
to: target.width
|
||||
duration: 400
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
property Component replaceTransition: pushTransition
|
||||
}
|
||||
|
||||
property QtObject verticalSlide: QtObject {
|
||||
property Component pushTransition: StackViewTransition {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "y"
|
||||
from: target.height
|
||||
to: 0
|
||||
duration: 300
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "y"
|
||||
from: 0
|
||||
to: -target.height
|
||||
duration: 300
|
||||
}
|
||||
}
|
||||
|
||||
property Component popTransition: StackViewTransition {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "y"
|
||||
from: -target.height
|
||||
to: 0
|
||||
duration: 300
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "y"
|
||||
from: 0
|
||||
to: target.height
|
||||
duration: 300
|
||||
}
|
||||
}
|
||||
property Component replaceTransition: pushTransition
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype Style
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
|
||||
AbstractStyle {
|
||||
/*! The control this style is attached to. */
|
||||
readonly property Item control: __control
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
pragma Singleton
|
||||
import QtQuick 2.2
|
||||
|
||||
QtObject {
|
||||
property SystemPalette active: SystemPalette { colorGroup: SystemPalette.Active }
|
||||
property SystemPalette disabled: SystemPalette { colorGroup: SystemPalette.Disabled }
|
||||
|
||||
function alternateBase(enabled) { return enabled ? active.alternateBase : disabled.alternateBase }
|
||||
function base(enabled) { return enabled ? active.base : disabled.base }
|
||||
function button(enabled) { return enabled ? active.button : disabled.button }
|
||||
function buttonText(enabled) { return enabled ? active.buttonText : disabled.buttonText }
|
||||
function dark(enabled) { return enabled ? active.dark : disabled.dark }
|
||||
function highlight(enabled) { return enabled ? active.highlight : disabled.highlight }
|
||||
function highlightedText(enabled) { return enabled ? active.highlightedText : disabled.highlightedText }
|
||||
function light(enabled) { return enabled ? active.light : disabled.light }
|
||||
function mid(enabled) { return enabled ? active.mid : disabled.mid }
|
||||
function midlight(enabled) { return enabled ? active.midlight : disabled.midlight }
|
||||
function shadow(enabled) { return enabled ? active.shadow : disabled.shadow }
|
||||
function text(enabled) { return enabled ? active.text : disabled.text }
|
||||
function window(enabled) { return enabled ? active.window : disabled.window }
|
||||
function windowText(enabled) { return enabled ? active.windowText : disabled.windowText }
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQml 2.14 as Qml
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype TabBar
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
FocusScope {
|
||||
id: tabbar
|
||||
height: Math.max(tabrow.height, Math.max(leftCorner.height, rightCorner.height))
|
||||
width: tabView.width
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
Keys.onRightPressed: {
|
||||
if (tabView && tabView.currentIndex < tabView.count - 1)
|
||||
tabView.currentIndex = tabView.currentIndex + 1
|
||||
}
|
||||
Keys.onLeftPressed: {
|
||||
if (tabView && tabView.currentIndex > 0)
|
||||
tabView.currentIndex = tabView.currentIndex - 1
|
||||
}
|
||||
|
||||
onTabViewChanged: parent = tabView
|
||||
visible: tabView ? tabView.tabsVisible : true
|
||||
|
||||
property var tabView
|
||||
property var style
|
||||
property var styleItem: tabView.__styleItem ? tabView.__styleItem : null
|
||||
|
||||
property bool tabsMovable: styleItem ? styleItem.tabsMovable : false
|
||||
|
||||
property int tabsAlignment: styleItem ? styleItem.tabsAlignment : Qt.AlignLeft
|
||||
|
||||
property int tabOverlap: styleItem ? styleItem.tabOverlap : 0
|
||||
|
||||
property int elide: Text.ElideRight
|
||||
|
||||
property real availableWidth: tabbar.width - leftCorner.width - rightCorner.width
|
||||
|
||||
property var __selectedTabRect
|
||||
|
||||
function tab(index) {
|
||||
for (var i = 0; i < tabrow.children.length; ++i) {
|
||||
if (tabrow.children[i].tabindex == index) {
|
||||
return tabrow.children[i]
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __isAncestorOf(item, child) {
|
||||
//TODO: maybe removed from 5.2 if the function was merged in qtdeclarative
|
||||
if (child === item)
|
||||
return false;
|
||||
|
||||
while (child) {
|
||||
child = child.parent;
|
||||
if (child === item)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Loader {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
sourceComponent: styleItem ? styleItem.tabBar : undefined
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: tabrow
|
||||
objectName: "tabrow"
|
||||
Accessible.role: Accessible.PageTabList
|
||||
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
|
||||
spacing: -tabOverlap
|
||||
orientation: Qt.Horizontal
|
||||
interactive: false
|
||||
focus: true
|
||||
clip: true
|
||||
|
||||
// Note this will silence the binding loop warnings caused by QTBUG-35038
|
||||
// and should be removed when this issue is resolved.
|
||||
property int contentWidthWorkaround: contentWidth > 0 ? contentWidth: 0
|
||||
width: Math.min(availableWidth, count ? contentWidthWorkaround : availableWidth)
|
||||
height: currentItem ? currentItem.height : 0
|
||||
|
||||
highlightMoveDuration: 0
|
||||
|
||||
// We cannot bind directly to the currentIndex because the actual model is
|
||||
// populated after the listview is completed, resulting in an invalid contentItem
|
||||
currentIndex: tabView.currentIndex < model.count ? tabView.currentIndex : -1
|
||||
onCurrentIndexChanged: tabrow.positionViewAtIndex(currentIndex, ListView.Contain)
|
||||
|
||||
moveDisplaced: Transition {
|
||||
NumberAnimation {
|
||||
property: "x"
|
||||
duration: 125
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "left"
|
||||
when: tabsAlignment === Qt.AlignLeft
|
||||
AnchorChanges { target:tabrow ; anchors.left: parent.left }
|
||||
PropertyChanges { target:tabrow ; anchors.leftMargin: leftCorner.width }
|
||||
},
|
||||
State {
|
||||
name: "center"
|
||||
when: tabsAlignment === Qt.AlignHCenter
|
||||
AnchorChanges { target:tabrow ; anchors.horizontalCenter: tabbar.horizontalCenter }
|
||||
},
|
||||
State {
|
||||
name: "right"
|
||||
when: tabsAlignment === Qt.AlignRight
|
||||
AnchorChanges { target:tabrow ; anchors.right: parent.right }
|
||||
PropertyChanges { target:tabrow ; anchors.rightMargin: rightCorner.width }
|
||||
}
|
||||
]
|
||||
|
||||
model: tabView.__tabs
|
||||
|
||||
delegate: MouseArea {
|
||||
id: tabitem
|
||||
objectName: "mousearea"
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
focus: true
|
||||
enabled: modelData.enabled
|
||||
|
||||
Qml.Binding {
|
||||
target: tabbar
|
||||
when: selected
|
||||
property: "__selectedTabRect"
|
||||
value: Qt.rect(x, y, width, height)
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
drag.target: tabsMovable ? tabloader : null
|
||||
drag.axis: Drag.XAxis
|
||||
drag.minimumX: drag.active ? 0 : -Number.MAX_VALUE
|
||||
drag.maximumX: tabrow.width - tabitem.width
|
||||
|
||||
property int tabindex: index
|
||||
property bool selected : tabView.currentIndex === index
|
||||
property string title: modelData.title
|
||||
property bool nextSelected: tabView.currentIndex === index + 1
|
||||
property bool previousSelected: tabView.currentIndex === index - 1
|
||||
|
||||
property bool keyPressed: false
|
||||
property bool effectivePressed: pressed && containsMouse || keyPressed
|
||||
|
||||
z: selected ? 1 : -index
|
||||
implicitWidth: tabloader.implicitWidth
|
||||
implicitHeight: tabloader.implicitHeight
|
||||
|
||||
function changeTab() {
|
||||
tabView.currentIndex = index;
|
||||
var next = tabbar.nextItemInFocusChain(true);
|
||||
if (__isAncestorOf(tabView.getTab(currentIndex), next))
|
||||
next.forceActiveFocus();
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
if (tabrow.interactive) {
|
||||
changeTab()
|
||||
}
|
||||
}
|
||||
onPressed: {
|
||||
if (!tabrow.interactive) {
|
||||
changeTab()
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
if (event.key === Qt.Key_Space && !event.isAutoRepeat && !tabitem.pressed)
|
||||
tabitem.keyPressed = true
|
||||
}
|
||||
Keys.onReleased: {
|
||||
if (event.key === Qt.Key_Space && !event.isAutoRepeat && tabitem.keyPressed)
|
||||
tabitem.keyPressed = false
|
||||
}
|
||||
onFocusChanged: if (!focus) tabitem.keyPressed = false
|
||||
|
||||
Loader {
|
||||
id: tabloader
|
||||
|
||||
property Item control: tabView
|
||||
property int index: tabindex
|
||||
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias index: tabitem.tabindex
|
||||
readonly property alias selected: tabitem.selected
|
||||
readonly property alias title: tabitem.title
|
||||
readonly property alias nextSelected: tabitem.nextSelected
|
||||
readonly property alias previousSelected: tabitem.previousSelected
|
||||
readonly property alias pressed: tabitem.effectivePressed
|
||||
readonly property alias hovered: tabitem.containsMouse
|
||||
readonly property alias enabled: tabitem.enabled
|
||||
readonly property bool activeFocus: tabitem.activeFocus
|
||||
readonly property real availableWidth: tabbar.availableWidth
|
||||
readonly property real totalWidth: tabrow.contentWidth
|
||||
}
|
||||
|
||||
sourceComponent: loader.item ? loader.item.tab : null
|
||||
|
||||
Drag.keys: "application/x-tabbartab"
|
||||
Drag.active: tabitem.drag.active
|
||||
Drag.source: tabitem
|
||||
|
||||
property real __prevX: 0
|
||||
property real __dragX: 0
|
||||
onXChanged: {
|
||||
if (Drag.active) {
|
||||
// keep track for the snap back animation
|
||||
__dragX = tabitem.mapFromItem(tabrow, tabloader.x, 0).x
|
||||
|
||||
// when moving to the left, the hot spot is the left edge and vice versa
|
||||
Drag.hotSpot.x = x < __prevX ? 0 : width
|
||||
__prevX = x
|
||||
}
|
||||
}
|
||||
|
||||
width: tabitem.width
|
||||
state: Drag.active ? "drag" : ""
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
to: "drag"
|
||||
PropertyAction { target: tabloader; property: "parent"; value: tabrow }
|
||||
},
|
||||
Transition {
|
||||
from: "drag"
|
||||
SequentialAnimation {
|
||||
PropertyAction { target: tabloader; property: "parent"; value: tabitem }
|
||||
NumberAnimation {
|
||||
target: tabloader
|
||||
duration: 50
|
||||
easing.type: Easing.OutQuad
|
||||
property: "x"
|
||||
from: tabloader.__dragX
|
||||
to: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Accessible.role: Accessible.PageTab
|
||||
Accessible.name: modelData.title
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: leftCorner
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
sourceComponent: styleItem ? styleItem.leftCorner : undefined
|
||||
width: item ? item.implicitWidth : 0
|
||||
height: item ? item.implicitHeight : 0
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: rightCorner
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
sourceComponent: styleItem ? styleItem.rightCorner : undefined
|
||||
width: item ? item.implicitWidth : 0
|
||||
height: item ? item.implicitHeight : 0
|
||||
}
|
||||
|
||||
DropArea {
|
||||
anchors.fill: tabrow
|
||||
keys: "application/x-tabbartab"
|
||||
onPositionChanged: {
|
||||
var source = drag.source
|
||||
var target = tabrow.itemAt(drag.x, drag.y)
|
||||
if (source && target && source !== target) {
|
||||
source = source.drag.target
|
||||
target = target.drag.target
|
||||
var center = target.parent.x + target.width / 2
|
||||
if ((source.index > target.index && source.x < center)
|
||||
|| (source.index < target.index && source.x + source.width > center))
|
||||
tabView.moveTab(source.index, target.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
|
||||
/*!
|
||||
\qmltype TableViewItemDelegateLoader
|
||||
\internal
|
||||
\qmlabstract
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
|
||||
Loader {
|
||||
id: itemDelegateLoader
|
||||
|
||||
width: __column ? __column.width : 0
|
||||
height: parent ? parent.height : 0
|
||||
visible: __column ? __column.visible : false
|
||||
|
||||
property bool isValid: false
|
||||
sourceComponent: (__model === undefined || !isValid) ? null
|
||||
: __column && __column.delegate ? __column.delegate : __itemDelegate
|
||||
|
||||
// All these properties are internal
|
||||
property int __index: index
|
||||
property Item __rowItem: null
|
||||
property var __model: __rowItem ? __rowItem.itemModel : undefined
|
||||
property var __modelData: __rowItem ? __rowItem.itemModelData : undefined
|
||||
property TableViewColumn __column: null
|
||||
property Component __itemDelegate: null
|
||||
property var __mouseArea: null
|
||||
property var __style: null
|
||||
|
||||
// These properties are exposed to the item delegate
|
||||
readonly property var model: __model
|
||||
readonly property var modelData: __modelData
|
||||
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property int row: __rowItem ? __rowItem.rowIndex : -1
|
||||
readonly property int column: __index
|
||||
readonly property int elideMode: __column ? __column.elideMode : Text.ElideLeft
|
||||
readonly property int textAlignment: __column ? __column.horizontalAlignment : Text.AlignLeft
|
||||
readonly property bool selected: __rowItem ? __rowItem.itemSelected : false
|
||||
readonly property bool hasActiveFocus: __rowItem ? __rowItem.activeFocus : false
|
||||
readonly property bool pressed: __mouseArea && row === __mouseArea.pressedRow && column === __mouseArea.pressedColumn
|
||||
readonly property color textColor: __rowItem ? __rowItem.itemTextColor : "black"
|
||||
readonly property string role: __column ? __column.role : ""
|
||||
readonly property var value: model && model.hasOwnProperty(role) ? model[role] // Qml ListModel and QAbstractItemModel
|
||||
: modelData && modelData.hasOwnProperty(role) ? modelData[role] // QObjectList / QObject
|
||||
: modelData != undefined ? modelData : "" // Models without role
|
||||
onRowChanged: if (row !== -1) itemDelegateLoader.isValid = true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
QtObject {
|
||||
|
||||
property int count: 0
|
||||
signal selectionChanged
|
||||
|
||||
property bool __dirty: false
|
||||
property var __ranges: []
|
||||
|
||||
function forEach (callback) {
|
||||
if (!(callback instanceof Function)) {
|
||||
console.warn("TableViewSelection.forEach: argument is not a function")
|
||||
return;
|
||||
}
|
||||
__forEach(callback, -1)
|
||||
}
|
||||
|
||||
function contains(index) {
|
||||
for (var i = 0 ; i < __ranges.length ; ++i) {
|
||||
if (__ranges[i][0] <= index && index <= __ranges[i][1])
|
||||
return true;
|
||||
else if (__ranges[i][0] > index)
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function clear() {
|
||||
__ranges = []
|
||||
__dirty = true
|
||||
count = 0
|
||||
selectionChanged()
|
||||
}
|
||||
|
||||
function selectAll() { select(0, rowCount - 1) }
|
||||
function select(first, last) { __select(true, first, last) }
|
||||
function deselect(first, last) { __select(false, first, last) }
|
||||
|
||||
// --- private section ---
|
||||
|
||||
function __printRanges() {
|
||||
var out = ""
|
||||
for (var i = 0 ; i < __ranges.length ; ++ i)
|
||||
out += ("{" + __ranges[i][0] + "," + __ranges[i][1] + "} ")
|
||||
print(out)
|
||||
}
|
||||
|
||||
function __count() {
|
||||
var sum = 0
|
||||
for (var i = 0 ; i < __ranges.length ; ++i) {
|
||||
sum += (1 + __ranges[i][1] - __ranges[i][0])
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
function __forEach (callback, startIndex) {
|
||||
__dirty = false
|
||||
var i, j
|
||||
|
||||
for (i = 0 ; i < __ranges.length && !__dirty ; ++i) {
|
||||
for (j = __ranges[i][0] ; !__dirty && j <= __ranges[i][1] ; ++j) {
|
||||
if (j >= startIndex)
|
||||
callback.call(this, j)
|
||||
}
|
||||
}
|
||||
|
||||
// Restart iteration at last index if selection changed
|
||||
if (__dirty)
|
||||
return __forEach(callback, j)
|
||||
}
|
||||
|
||||
function __selectOne(index) {
|
||||
__ranges = [[index, index]]
|
||||
__dirty = true
|
||||
count = 1
|
||||
selectionChanged();
|
||||
}
|
||||
|
||||
function __select(select, first, last) {
|
||||
|
||||
var i, range
|
||||
var start = first
|
||||
var stop = first
|
||||
var startRangeIndex = -1
|
||||
var stopRangeIndex = -1
|
||||
var newRangePos = 0
|
||||
|
||||
if (first < 0 || last < 0 || first >= rowCount || last >=rowCount) {
|
||||
console.warn("TableViewSelection: index out of range")
|
||||
return
|
||||
}
|
||||
|
||||
if (last !== undefined) {
|
||||
start = first <= last ? first : last
|
||||
stop = first <= last ? last : first
|
||||
}
|
||||
|
||||
if (select) {
|
||||
|
||||
// Find beginning and end ranges
|
||||
for (i = 0 ; i < __ranges.length; ++ i) {
|
||||
range = __ranges[i]
|
||||
if (range[0] > stop + 1) continue; // above range
|
||||
if (range[1] < start - 1) { // below range
|
||||
newRangePos = i + 1
|
||||
continue;
|
||||
}
|
||||
if (startRangeIndex === -1)
|
||||
startRangeIndex = i
|
||||
stopRangeIndex = i
|
||||
}
|
||||
|
||||
if (startRangeIndex !== -1)
|
||||
start = Math.min(__ranges[startRangeIndex][0], start)
|
||||
if (stopRangeIndex !== -1)
|
||||
stop = Math.max(__ranges[stopRangeIndex][1], stop)
|
||||
|
||||
if (startRangeIndex === -1)
|
||||
startRangeIndex = newRangePos
|
||||
|
||||
__ranges.splice(Math.max(0, startRangeIndex),
|
||||
1 + stopRangeIndex - startRangeIndex, [start, stop])
|
||||
|
||||
} else {
|
||||
|
||||
// Find beginning and end ranges
|
||||
for (i = 0 ; i < __ranges.length; ++ i) {
|
||||
range = __ranges[i]
|
||||
if (range[1] < start) continue; // below range
|
||||
if (range[0] > stop) continue; // above range
|
||||
if (startRangeIndex === -1)
|
||||
startRangeIndex = i
|
||||
stopRangeIndex = i
|
||||
}
|
||||
|
||||
// Slice ranges accordingly
|
||||
if (startRangeIndex >= 0 && stopRangeIndex >= 0) {
|
||||
var startRange = __ranges[startRangeIndex]
|
||||
var stopRange = __ranges[stopRangeIndex]
|
||||
var length = 1 + stopRangeIndex - startRangeIndex
|
||||
if (start <= startRange[0] && stop >= stopRange[1]) { //remove
|
||||
__ranges.splice(startRangeIndex, length)
|
||||
} else if (start - 1 < startRange[0] && stop <= stopRange[1]) { //cut front
|
||||
__ranges.splice(startRangeIndex, length, [stop + 1, stopRange[1]])
|
||||
} else if (start - 1 < startRange[1] && stop >= stopRange[1]) { // cut back
|
||||
__ranges.splice(startRangeIndex, length, [startRange[0], start - 1])
|
||||
} else { //split
|
||||
__ranges.splice(startRangeIndex, length, [startRange[0], start - 1], [stop + 1, stopRange[1]])
|
||||
}
|
||||
}
|
||||
}
|
||||
__dirty = true
|
||||
count = __count() // forces a re-evaluation of indexes in the delegates
|
||||
selectionChanged()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
Loader {
|
||||
id: handle
|
||||
|
||||
property Item editor
|
||||
property int minimum: -1
|
||||
property int maximum: -1
|
||||
property int position: -1
|
||||
property alias delegate: handle.sourceComponent
|
||||
|
||||
readonly property alias pressed: mouse.pressed
|
||||
|
||||
readonly property real handleX: x + (item ? item.x : 0)
|
||||
readonly property real handleY: y + (item ? item.y : 0)
|
||||
readonly property real handleWidth: item ? item.width : 0
|
||||
readonly property real handleHeight: item ? item.height : 0
|
||||
|
||||
property Item control
|
||||
property QtObject styleData: QtObject {
|
||||
id: styleData
|
||||
signal activated()
|
||||
readonly property alias pressed: mouse.pressed
|
||||
readonly property alias position: handle.position
|
||||
readonly property bool hasSelection: editor.selectionStart !== editor.selectionEnd
|
||||
readonly property real lineHeight: position !== -1 ? editor.positionToRectangle(position).height
|
||||
: editor.cursorRectangle.height
|
||||
}
|
||||
|
||||
function activate() {
|
||||
styleData.activated()
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouse
|
||||
anchors.fill: item
|
||||
enabled: item && item.visible
|
||||
preventStealing: true
|
||||
property real pressX
|
||||
property point offset
|
||||
property bool handleDragged: false
|
||||
|
||||
onPressed: {
|
||||
Qt.inputMethod.commit()
|
||||
handleDragged = false
|
||||
pressX = mouse.x
|
||||
var handleRect = editor.positionToRectangle(handle.position)
|
||||
var centerX = handleRect.x + (handleRect.width / 2)
|
||||
var centerY = handleRect.y + (handleRect.height / 2)
|
||||
var center = mapFromItem(editor, centerX, centerY)
|
||||
offset = Qt.point(mouseX - center.x, mouseY - center.y)
|
||||
}
|
||||
onReleased: {
|
||||
if (!handleDragged) {
|
||||
// The user just clicked on the handle. In that
|
||||
// case clear the selection.
|
||||
var mousePos = editor.mapFromItem(item, mouse.x, mouse.y)
|
||||
var editorPos = editor.positionAt(mousePos.x, mousePos.y)
|
||||
editor.select(editorPos, editorPos)
|
||||
}
|
||||
}
|
||||
onPositionChanged: {
|
||||
handleDragged = true
|
||||
var pt = mapToItem(editor, mouse.x - offset.x, mouse.y - offset.y)
|
||||
|
||||
// limit vertically within mix/max coordinates or content bounds
|
||||
var min = (minimum !== -1) ? minimum : 0
|
||||
var max = (maximum !== -1) ? maximum : editor.length
|
||||
pt.y = Math.max(pt.y, editor.positionToRectangle(min).y)
|
||||
pt.y = Math.min(pt.y, editor.positionToRectangle(max).y)
|
||||
|
||||
var pos = editor.positionAt(pt.x, pt.y)
|
||||
|
||||
// limit horizontally within min/max character positions
|
||||
if (minimum !== -1)
|
||||
pos = Math.max(pos, minimum)
|
||||
pos = Math.max(pos, 0)
|
||||
if (maximum !== -1)
|
||||
pos = Math.min(pos, maximum)
|
||||
pos = Math.min(pos, editor.length)
|
||||
|
||||
handle.position = pos
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Window 2.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
TextInput {
|
||||
id: input
|
||||
|
||||
property Item control
|
||||
property alias cursorHandle: cursorHandle.delegate
|
||||
property alias selectionHandle: selectionHandle.delegate
|
||||
|
||||
property bool blockRecursion: false
|
||||
property bool hasSelection: selectionStart !== selectionEnd
|
||||
readonly property int selectionPosition: selectionStart !== cursorPosition ? selectionStart : selectionEnd
|
||||
readonly property alias containsMouse: mouseArea.containsMouse
|
||||
property alias editMenu: editMenu
|
||||
cursorDelegate: __style && __style.__cursorDelegate ? __style.__cursorDelegate : null
|
||||
|
||||
selectByMouse: control.selectByMouse && (!Settings.isMobile || !cursorHandle.delegate || !selectionHandle.delegate)
|
||||
|
||||
// force re-evaluation when selection moves:
|
||||
// - cursorRectangle changes => content scrolled
|
||||
// - contentWidth changes => text layout changed
|
||||
property rect selectionRectangle: cursorRectangle.x && contentWidth ? positionToRectangle(selectionPosition)
|
||||
: positionToRectangle(selectionPosition)
|
||||
|
||||
onSelectionStartChanged: syncHandlesWithSelection()
|
||||
onCursorPositionChanged: syncHandlesWithSelection()
|
||||
|
||||
function syncHandlesWithSelection()
|
||||
{
|
||||
if (!blockRecursion && selectionHandle.delegate) {
|
||||
blockRecursion = true
|
||||
// We cannot use property selectionPosition since it gets updated after onSelectionStartChanged
|
||||
cursorHandle.position = cursorPosition
|
||||
selectionHandle.position = (selectionStart !== cursorPosition) ? selectionStart : selectionEnd
|
||||
blockRecursion = false
|
||||
}
|
||||
}
|
||||
|
||||
function activate() {
|
||||
if (activeFocusOnPress) {
|
||||
forceActiveFocus()
|
||||
if (!readOnly)
|
||||
Qt.inputMethod.show()
|
||||
}
|
||||
cursorHandle.activate()
|
||||
selectionHandle.activate()
|
||||
}
|
||||
|
||||
function moveHandles(cursor, selection) {
|
||||
blockRecursion = true
|
||||
cursorPosition = cursor
|
||||
if (selection === -1) {
|
||||
selectWord()
|
||||
selection = selectionStart
|
||||
}
|
||||
selectionHandle.position = selection
|
||||
cursorHandle.position = cursorPosition
|
||||
blockRecursion = false
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
cursorShape: Qt.IBeamCursor
|
||||
acceptedButtons: (input.selectByMouse ? Qt.NoButton : Qt.LeftButton) | (control.menu ? Qt.RightButton : Qt.NoButton)
|
||||
onClicked: {
|
||||
if (editMenu.item)
|
||||
return;
|
||||
var pos = input.positionAt(mouse.x, mouse.y)
|
||||
input.moveHandles(pos, pos)
|
||||
input.activate()
|
||||
}
|
||||
onPressAndHold: {
|
||||
if (editMenu.item)
|
||||
return;
|
||||
var pos = input.positionAt(mouse.x, mouse.y)
|
||||
input.moveHandles(pos, control.selectByMouse ? -1 : pos)
|
||||
input.activate()
|
||||
}
|
||||
}
|
||||
|
||||
EditMenu {
|
||||
id: editMenu
|
||||
input: parent
|
||||
mouseArea: mouseArea
|
||||
control: parent.control
|
||||
cursorHandle: cursorHandle
|
||||
selectionHandle: selectionHandle
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
ScenePosListener {
|
||||
id: listener
|
||||
item: input
|
||||
enabled: input.activeFocus && Qt.platform.os !== "ios" && Settings.isMobile
|
||||
}
|
||||
|
||||
TextHandle {
|
||||
id: selectionHandle
|
||||
|
||||
editor: input
|
||||
z: 1000001 // DefaultWindowDecoration+1
|
||||
parent: !input.activeFocus || Qt.platform.os === "ios" ? control : Window.contentItem // float (QTBUG-42538)
|
||||
control: input.control
|
||||
active: control.selectByMouse && Settings.isMobile
|
||||
maximum: cursorHandle.position - 1
|
||||
|
||||
readonly property var mappedOrigin: editor.mapToItem(parent, 0,0)
|
||||
|
||||
// Mention scenePos in the mappedPos binding to force re-evaluation if it changes
|
||||
readonly property var mappedPos: listener.scenePos.x !== listener.scenePos.y !== Number.MAX_VALUE ?
|
||||
editor.mapToItem(parent, editor.selectionRectangle.x, editor.selectionRectangle.y) : -1
|
||||
x: mappedPos.x
|
||||
y: mappedPos.y
|
||||
|
||||
visible: pressed || (input.hasSelection && handleX + handleWidth >= -1 && handleX - mappedOrigin.x <= control.width + 1)
|
||||
|
||||
onPositionChanged: {
|
||||
if (!input.blockRecursion) {
|
||||
input.blockRecursion = true
|
||||
input.select(selectionHandle.position, cursorHandle.position)
|
||||
if (pressed)
|
||||
input.ensureVisible(position)
|
||||
input.blockRecursion = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextHandle {
|
||||
id: cursorHandle
|
||||
|
||||
editor: input
|
||||
z: 1000001 // DefaultWindowDecoration+1
|
||||
parent: !input.activeFocus || Qt.platform.os === "ios" ? control : Window.contentItem // float (QTBUG-42538)
|
||||
control: input.control
|
||||
active: control.selectByMouse && Settings.isMobile
|
||||
minimum: input.hasSelection ? selectionHandle.position + 1 : -1
|
||||
|
||||
readonly property var mappedOrigin: editor.mapToItem(parent, 0,0)
|
||||
|
||||
// Mention scenePos in the mappedPos binding to force re-evaluation if it changes
|
||||
readonly property var mappedPos: listener.scenePos.x !== listener.scenePos.y !== Number.MAX_VALUE ?
|
||||
editor.mapToItem(parent, editor.cursorRectangle.x, editor.cursorRectangle.y) : -1
|
||||
x: mappedPos.x
|
||||
y: mappedPos.y
|
||||
|
||||
visible: pressed || ((input.cursorVisible || input.hasSelection) && handleX + handleWidth >= -1 && handleX - mappedOrigin.x <= control.width + 1)
|
||||
|
||||
onPositionChanged: {
|
||||
if (!input.blockRecursion) {
|
||||
input.blockRecursion = true
|
||||
if (!input.hasSelection)
|
||||
selectionHandle.position = cursorHandle.position
|
||||
input.select(selectionHandle.position, cursorHandle.position)
|
||||
input.blockRecursion = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
pragma Singleton
|
||||
import QtQuick 2.2
|
||||
Text {
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQml 2.14 as Qml
|
||||
import QtQuick 2.4
|
||||
import QtQuick.Controls 1.3
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
FocusScope {
|
||||
id: button
|
||||
|
||||
property Menu menu
|
||||
readonly property bool pressed: behavior.containsPress || behavior.keyPressed
|
||||
readonly property alias hovered: behavior.containsMouse
|
||||
|
||||
property alias panel: loader.sourceComponent
|
||||
property alias __panel: loader.item
|
||||
|
||||
activeFocusOnTab: true
|
||||
Accessible.role: Accessible.Button
|
||||
implicitWidth: __panel ? __panel.implicitWidth : 0
|
||||
implicitHeight: __panel ? __panel.implicitHeight : 0
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
anchors.fill: parent
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias pressed: button.pressed
|
||||
readonly property alias hovered: button.hovered
|
||||
readonly property alias activeFocus: button.activeFocus
|
||||
}
|
||||
onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", button)
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
if (event.key === Qt.Key_Space && !event.isAutoRepeat && !behavior.keyPressed)
|
||||
behavior.keyPressed = true
|
||||
}
|
||||
Keys.onReleased: {
|
||||
if (event.key === Qt.Key_Space && !event.isAutoRepeat && behavior.keyPressed)
|
||||
behavior.keyPressed = false
|
||||
}
|
||||
onFocusChanged: {
|
||||
if (!focus)
|
||||
behavior.keyPressed = false
|
||||
}
|
||||
onPressedChanged: {
|
||||
if (!Settings.hasTouchScreen && !pressed && menu)
|
||||
popupMenuTimer.start()
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: behavior
|
||||
property bool keyPressed: false
|
||||
|
||||
anchors.fill: parent
|
||||
enabled: !keyPressed
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
|
||||
onReleased: {
|
||||
if (Settings.hasTouchScreen && containsMouse && menu)
|
||||
popupMenuTimer.start()
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: popupMenuTimer
|
||||
interval: 10
|
||||
onTriggered: {
|
||||
behavior.keyPressed = false
|
||||
if (Qt.application.layoutDirection === Qt.RightToLeft)
|
||||
menu.__popup(Qt.rect(button.width, button.height, 0, 0), 0)
|
||||
else
|
||||
menu.__popup(Qt.rect(0, 0, button.width, button.height), 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Qml.Binding {
|
||||
target: menu
|
||||
property: "__minimumWidth"
|
||||
value: button.width
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
Qml.Binding {
|
||||
target: menu
|
||||
property: "__visualItem"
|
||||
value: button
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype TreeViewItemDelegateLoader
|
||||
\internal
|
||||
\qmlabstract
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
|
||||
TableViewItemDelegateLoader {
|
||||
id: itemDelegateLoader
|
||||
|
||||
/* \internal */
|
||||
readonly property int __itemIndentation: __style && __index === 0
|
||||
? __style.__indentation * (styleData.depth + 1) : 0
|
||||
/* \internal */
|
||||
property TreeModelAdaptor __treeModel: null
|
||||
|
||||
// Exposed to the item delegate
|
||||
styleData: QtObject {
|
||||
readonly property int row: __rowItem ? __rowItem.rowIndex : -1
|
||||
readonly property int column: __index
|
||||
readonly property int elideMode: __column ? __column.elideMode : Text.ElideLeft
|
||||
readonly property int textAlignment: __column ? __column.horizontalAlignment : Text.AlignLeft
|
||||
readonly property bool selected: __rowItem ? __rowItem.itemSelected : false
|
||||
readonly property bool hasActiveFocus: __rowItem ? __rowItem.activeFocus : false
|
||||
readonly property bool pressed: __mouseArea && row === __mouseArea.pressedRow && column === __mouseArea.pressedColumn
|
||||
readonly property color textColor: __rowItem ? __rowItem.itemTextColor : "black"
|
||||
readonly property string role: __column ? __column.role : ""
|
||||
readonly property var value: model && model.hasOwnProperty(role) ? model[role] : ""
|
||||
readonly property var index: model ? model["_q_TreeView_ModelIndex"] : __treeModel.index(-1,-1)
|
||||
readonly property int depth: model && column === 0 ? model["_q_TreeView_ItemDepth"] : 0
|
||||
readonly property bool hasChildren: model ? model["_q_TreeView_HasChildren"] : false
|
||||
readonly property bool hasSibling: model ? model["_q_TreeView_HasSibling"] : false
|
||||
readonly property bool isExpanded: model ? model["_q_TreeView_ItemExpanded"] : false
|
||||
}
|
||||
|
||||
onLoaded: {
|
||||
item.x = Qt.binding(function() { return __itemIndentation})
|
||||
item.width = Qt.binding(function() { return width - __itemIndentation })
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: branchDelegateLoader
|
||||
active: __model !== undefined
|
||||
&& __index === 0
|
||||
&& styleData.hasChildren
|
||||
visible: itemDelegateLoader.width > __itemIndentation
|
||||
sourceComponent: __style && __style.__branchDelegate || null
|
||||
anchors.right: parent.item ? parent.item.left : undefined
|
||||
anchors.rightMargin: __style.__indentation > width ? (__style.__indentation - width) / 2 : 0
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
property QtObject styleData: itemDelegateLoader.styleData
|
||||
onLoaded: if (__rowItem) __rowItem.branchDecoration = item
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
module QtQuick.Controls.Private
|
||||
AbstractCheckable 1.0 AbstractCheckable.qml
|
||||
CalendarHeaderModel 1.0 CalendarHeaderModel.qml
|
||||
Control 1.0 Control.qml
|
||||
CalendarUtils 1.0 CalendarUtils.js
|
||||
FocusFrame 1.0 FocusFrame.qml
|
||||
Margins 1.0 Margins.qml
|
||||
BasicButton 1.0 BasicButton.qml
|
||||
ScrollBar 1.0 ScrollBar.qml
|
||||
ScrollViewHelper 1.0 ScrollViewHelper.qml
|
||||
Style 1.0 Style.qml
|
||||
MenuItemSubControls 1.0 MenuItemSubControls.qml
|
||||
TabBar 1.0 TabBar.qml
|
||||
StackViewSlideDelegate 1.0 StackViewSlideDelegate.qml
|
||||
StyleHelpers 1.0 style.js
|
||||
JSArray 1.0 StackView.js
|
||||
TableViewSelection 1.0 TableViewSelection.qml
|
||||
FastGlow 1.0 FastGlow.qml
|
||||
SourceProxy 1.0 SourceProxy.qml
|
||||
GroupBoxStyle 1.0 ../Styles/Base/GroupBoxStyle.qml
|
||||
FocusFrameStyle 1.0 ../Styles/Base/FocusFrameStyle.qml
|
||||
ToolButtonStyle 1.0 ../Styles/Base/ToolButtonStyle.qml
|
||||
MenuContentItem 1.0 MenuContentItem.qml
|
||||
MenuContentScroller 1.0 MenuContentScroller.qml
|
||||
ColumnMenuContent 1.0 ColumnMenuContent.qml
|
||||
ContentItem 1.0 ContentItem.qml
|
||||
HoverButton 1.0 HoverButton.qml
|
||||
singleton SystemPaletteSingleton 1.0 SystemPaletteSingleton.qml
|
||||
singleton TextSingleton 1.0 TextSingleton.qml
|
||||
TextHandle 1.0 TextHandle.qml
|
||||
TextInputWithHandles 1.0 TextInputWithHandles.qml
|
||||
EditMenu 1.0 EditMenu.qml
|
||||
EditMenu_base 1.0 EditMenu_base.qml
|
||||
ToolMenuButton 1.0 ToolMenuButton.qml
|
||||
BasicTableView 1.0 BasicTableView.qml
|
||||
TableViewItemDelegateLoader 1.0 TableViewItemDelegateLoader.qml
|
||||
TreeViewItemDelegateLoader 1.0 TreeViewItemDelegateLoader.qml
|
||||
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
.pragma library
|
||||
|
||||
function underlineAmpersands(match, p1, p2, p3) {
|
||||
if (p2 === "&")
|
||||
return p1.concat(p2, p3)
|
||||
return p1.concat("<u>", p2, "</u>", p3)
|
||||
}
|
||||
|
||||
function removeAmpersands(match, p1, p2, p3) {
|
||||
return p1.concat(p2, p3)
|
||||
}
|
||||
|
||||
function replaceAmpersands(text, replaceFunction) {
|
||||
return text.replace(/([^&]*)&(.)([^&]*)/g, replaceFunction)
|
||||
}
|
||||
|
||||
function stylizeMnemonics(text) {
|
||||
return replaceAmpersands(text, underlineAmpersands)
|
||||
}
|
||||
|
||||
function removeMnemonics(text) {
|
||||
return replaceAmpersands(text, removeAmpersands)
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype ProgressBar
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup controls
|
||||
\brief A progress indicator.
|
||||
|
||||
\image progressbar.png
|
||||
|
||||
The ProgressBar is used to give an indication of the progress of an operation.
|
||||
\l value is updated regularly and must be between \l minimumValue and \l maximumValue.
|
||||
|
||||
\code
|
||||
Column {
|
||||
ProgressBar {
|
||||
value: 0.5
|
||||
}
|
||||
ProgressBar {
|
||||
indeterminate: true
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
You can create a custom appearance for a ProgressBar by
|
||||
assigning a \l {ProgressBarStyle}.
|
||||
*/
|
||||
|
||||
Control {
|
||||
id: progressbar
|
||||
|
||||
/*! This property holds the progress bar's current value.
|
||||
Attempting to change the current value to one outside the minimum-maximum
|
||||
range has no effect on the current value.
|
||||
|
||||
The default value is \c{0}.
|
||||
*/
|
||||
property real value: 0
|
||||
|
||||
/*! This property is the progress bar's minimum value.
|
||||
The \l value is clamped to this value.
|
||||
The default value is \c{0}.
|
||||
*/
|
||||
property real minimumValue: 0
|
||||
|
||||
/*! This property is the progress bar's maximum value.
|
||||
The \l value is clamped to this value.
|
||||
If maximumValue is smaller than \l minimumValue, \l minimumValue will be enforced.
|
||||
The default value is \c{1}.
|
||||
*/
|
||||
property real maximumValue: 1
|
||||
|
||||
/*! This property toggles indeterminate mode.
|
||||
When the actual progress is unknown, use this option.
|
||||
The progress bar will be animated as a busy indicator instead.
|
||||
The default value is \c false.
|
||||
*/
|
||||
property bool indeterminate: false
|
||||
|
||||
/*! \qmlproperty enumeration orientation
|
||||
|
||||
This property holds the orientation of the progress bar.
|
||||
|
||||
\list
|
||||
\li Qt.Horizontal - Horizontal orientation. (Default)
|
||||
\li Qt.Vertical - Vertical orientation.
|
||||
\endlist
|
||||
*/
|
||||
property int orientation: Qt.Horizontal
|
||||
|
||||
/*! \qmlproperty bool ProgressBar::hovered
|
||||
|
||||
This property indicates whether the control is being hovered.
|
||||
*/
|
||||
readonly property alias hovered: hoverArea.containsMouse
|
||||
|
||||
/*! \internal */
|
||||
style: Settings.styleComponent(Settings.style, "ProgressBarStyle.qml", progressbar)
|
||||
|
||||
/*! \internal */
|
||||
property bool __initialized: false
|
||||
/*! \internal */
|
||||
onMaximumValueChanged: setValue(value)
|
||||
/*! \internal */
|
||||
onMinimumValueChanged: setValue(value)
|
||||
/*! \internal */
|
||||
onValueChanged: if (__initialized) setValue(value)
|
||||
/*! \internal */
|
||||
Component.onCompleted: {
|
||||
__initialized = true;
|
||||
setValue(value)
|
||||
}
|
||||
|
||||
activeFocusOnTab: false
|
||||
|
||||
Accessible.role: Accessible.ProgressBar
|
||||
Accessible.name: value
|
||||
|
||||
implicitWidth:(__panel ? __panel.implicitWidth : 0)
|
||||
implicitHeight: (__panel ? __panel.implicitHeight: 0)
|
||||
|
||||
MouseArea {
|
||||
id: hoverArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function setValue(v) {
|
||||
var newval = parseFloat(v)
|
||||
if (!isNaN(newval)) {
|
||||
// we give minimumValue priority over maximum if they are inconsistent
|
||||
if (newval > maximumValue) {
|
||||
if (maximumValue >= minimumValue)
|
||||
newval = maximumValue;
|
||||
else
|
||||
newval = minimumValue
|
||||
} else if (v < minimumValue) {
|
||||
newval = minimumValue
|
||||
}
|
||||
if (value !== newval)
|
||||
value = newval
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype RadioButton
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup controls
|
||||
\brief A radio button with a text label.
|
||||
|
||||
\image radiobutton.png
|
||||
|
||||
A RadioButton is an option button that can be switched on (checked) or off
|
||||
(unchecked). Radio buttons typically present the user with a "one of many"
|
||||
choices. In a group of radio buttons, only one radio button can be
|
||||
checked at a time; if the user selects another button, the previously
|
||||
selected button is switched off.
|
||||
|
||||
\qml
|
||||
GroupBox {
|
||||
title: "Tab Position"
|
||||
|
||||
RowLayout {
|
||||
ExclusiveGroup { id: tabPositionGroup }
|
||||
RadioButton {
|
||||
text: "Top"
|
||||
checked: true
|
||||
exclusiveGroup: tabPositionGroup
|
||||
}
|
||||
RadioButton {
|
||||
text: "Bottom"
|
||||
exclusiveGroup: tabPositionGroup
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
You can create a custom appearance for a RadioButton by
|
||||
assigning a \l {RadioButtonStyle}.
|
||||
*/
|
||||
|
||||
AbstractCheckable {
|
||||
id: radioButton
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
Accessible.name: text
|
||||
Accessible.role: Accessible.RadioButton
|
||||
|
||||
/*!
|
||||
The style that should be applied to the radio button. Custom style
|
||||
components can be created with:
|
||||
|
||||
\codeline Qt.createComponent("path/to/style.qml", radioButtonId);
|
||||
*/
|
||||
style: Settings.styleComponent(Settings.style, "RadioButtonStyle.qml", radioButton)
|
||||
|
||||
__cycleStatesHandler: function() { checked = !checked; }
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQml 2.14 as Qml
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
|
||||
/*!
|
||||
\qmltype ScrollView
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup views
|
||||
\ingroup controls
|
||||
\brief Provides a scrolling view within another Item.
|
||||
|
||||
\image scrollview.png
|
||||
|
||||
A ScrollView can be used either to replace a \l Flickable or decorate an
|
||||
existing \l Flickable. Depending on the platform, it will add scroll bars and
|
||||
a content frame.
|
||||
|
||||
Only one Item can be a direct child of the ScrollView and the child is implicitly anchored
|
||||
to fill the scroll view.
|
||||
|
||||
Example:
|
||||
\code
|
||||
ScrollView {
|
||||
Image { source: "largeImage.png" }
|
||||
}
|
||||
\endcode
|
||||
|
||||
In the previous example the Image item will implicitly get scroll behavior as if it was
|
||||
used within a \l Flickable. The width and height of the child item will be used to
|
||||
define the size of the content area.
|
||||
|
||||
Example:
|
||||
\code
|
||||
ScrollView {
|
||||
ListView {
|
||||
...
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
In this case the content size of the ScrollView will simply mirror that of its contained
|
||||
\l flickableItem.
|
||||
|
||||
You can create a custom appearance for a ScrollView by
|
||||
assigning a \l {ScrollViewStyle}.
|
||||
*/
|
||||
|
||||
FocusScope {
|
||||
id: root
|
||||
|
||||
implicitWidth: 240
|
||||
implicitHeight: 150
|
||||
|
||||
/*!
|
||||
This property tells the ScrollView if it should render
|
||||
a frame around its content.
|
||||
|
||||
The default value is \c false.
|
||||
*/
|
||||
property bool frameVisible: false
|
||||
|
||||
/*! \qmlproperty enumeration ScrollView::horizontalScrollBarPolicy
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
This property holds the policy for showing the horizontal scrollbar.
|
||||
It can be any of the following values:
|
||||
\list
|
||||
\li Qt.ScrollBarAsNeeded
|
||||
\li Qt.ScrollBarAlwaysOff
|
||||
\li Qt.ScrollBarAlwaysOn
|
||||
\endlist
|
||||
|
||||
The default policy is \c Qt.ScrollBarAsNeeded.
|
||||
*/
|
||||
property alias horizontalScrollBarPolicy: scroller.horizontalScrollBarPolicy
|
||||
|
||||
/*! \qmlproperty enumeration ScrollView::verticalScrollBarPolicy
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
This property holds the policy for showing the vertical scrollbar.
|
||||
It can be any of the following values:
|
||||
\list
|
||||
\li Qt.ScrollBarAsNeeded
|
||||
\li Qt.ScrollBarAlwaysOff
|
||||
\li Qt.ScrollBarAlwaysOn
|
||||
\endlist
|
||||
|
||||
The default policy is \c Qt.ScrollBarAsNeeded.
|
||||
*/
|
||||
property alias verticalScrollBarPolicy: scroller.verticalScrollBarPolicy
|
||||
|
||||
/*!
|
||||
This property controls if there should be a highlight
|
||||
around the frame when the ScrollView has input focus.
|
||||
|
||||
The default value is \c false.
|
||||
|
||||
\note This property is only applicable on some platforms, such
|
||||
as Mac OS.
|
||||
*/
|
||||
property bool highlightOnFocus: false
|
||||
|
||||
/*!
|
||||
\qmlproperty Item ScrollView::viewport
|
||||
|
||||
The viewport determines the current "window" on the contentItem.
|
||||
In other words, it clips it and the size of the viewport tells you
|
||||
how much of the content area is visible.
|
||||
*/
|
||||
property alias viewport: viewportItem
|
||||
|
||||
/*!
|
||||
\qmlproperty Item ScrollView::flickableItem
|
||||
|
||||
The flickableItem of the ScrollView. If the contentItem provided
|
||||
to the ScrollView is a Flickable, it will be the \l contentItem.
|
||||
*/
|
||||
readonly property alias flickableItem: internal.flickableItem
|
||||
|
||||
/*!
|
||||
The contentItem of the ScrollView. This is set by the user.
|
||||
|
||||
Note that the definition of contentItem is somewhat different to that
|
||||
of a Flickable, where the contentItem is implicitly created.
|
||||
*/
|
||||
default property Item contentItem
|
||||
|
||||
/*! \internal */
|
||||
property alias __scroller: scroller
|
||||
/*! \internal */
|
||||
property alias __verticalScrollbarOffset: scroller.verticalScrollbarOffset
|
||||
/*! \internal */
|
||||
property alias __wheelAreaScrollSpeed: wheelArea.scrollSpeed
|
||||
/*! \internal */
|
||||
property int __scrollBarTopMargin: 0
|
||||
/*! \internal */
|
||||
property int __viewTopMargin: 0
|
||||
/*! \internal */
|
||||
property alias __horizontalScrollBar: scroller.horizontalScrollBar
|
||||
/*! \internal */
|
||||
property alias __verticalScrollBar: scroller.verticalScrollBar
|
||||
/*! \qmlproperty Component ScrollView::style
|
||||
|
||||
The style Component for this control.
|
||||
\sa {Qt Quick Controls 1 Styles QML Types}
|
||||
|
||||
*/
|
||||
property Component style: Settings.styleComponent(Settings.style, "ScrollViewStyle.qml", root)
|
||||
|
||||
/*! \internal */
|
||||
property Style __style: styleLoader.item
|
||||
|
||||
activeFocusOnTab: false
|
||||
|
||||
onContentItemChanged: {
|
||||
|
||||
if (contentItem.hasOwnProperty("contentY") && // Check if flickable
|
||||
contentItem.hasOwnProperty("contentHeight")) {
|
||||
internal.flickableItem = contentItem // "Use content if it is a flickable
|
||||
internal.flickableItem.parent = viewportItem
|
||||
} else {
|
||||
internal.flickableItem = flickableComponent.createObject(viewportItem)
|
||||
contentItem.parent = internal.flickableItem.contentItem
|
||||
}
|
||||
internal.flickableItem.anchors.fill = viewportItem
|
||||
if (!Settings.hasTouchScreen)
|
||||
internal.flickableItem.interactive = false
|
||||
}
|
||||
|
||||
|
||||
children: Item {
|
||||
id: internal
|
||||
|
||||
property Flickable flickableItem
|
||||
|
||||
Loader {
|
||||
id: styleLoader
|
||||
sourceComponent: style
|
||||
onStatusChanged: {
|
||||
if (status === Loader.Error)
|
||||
console.error("Failed to load Style for", root)
|
||||
}
|
||||
property alias __control: root
|
||||
}
|
||||
|
||||
Qml.Binding {
|
||||
target: flickableItem
|
||||
property: "contentHeight"
|
||||
when: contentItem !== flickableItem
|
||||
value: contentItem ? contentItem.height : 0
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
Qml.Binding {
|
||||
target: flickableItem
|
||||
when: contentItem !== flickableItem
|
||||
property: "contentWidth"
|
||||
value: contentItem ? contentItem.width : 0
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: flickableItem
|
||||
|
||||
function onContentYChanged() {
|
||||
scroller.blockUpdates = true
|
||||
scroller.verticalScrollBar.value = flickableItem.contentY - flickableItem.originY
|
||||
scroller.blockUpdates = false
|
||||
}
|
||||
|
||||
function onContentXChanged() {
|
||||
scroller.blockUpdates = true
|
||||
scroller.horizontalScrollBar.value = flickableItem.contentX - flickableItem.originX
|
||||
scroller.blockUpdates = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
Component {
|
||||
id: flickableComponent
|
||||
Flickable {}
|
||||
}
|
||||
|
||||
WheelArea {
|
||||
id: wheelArea
|
||||
parent: flickableItem
|
||||
z: -1
|
||||
// ### Note this is needed due to broken mousewheel behavior in Flickable.
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
property int acceleration: 40
|
||||
property int flickThreshold: Settings.dragThreshold
|
||||
property real speedThreshold: 3
|
||||
property real ignored: 0.001 // ## flick() does not work with 0 yVelocity
|
||||
property int maxFlick: 400
|
||||
|
||||
property bool horizontalRecursionGuard: false
|
||||
property bool verticalRecursionGuard: false
|
||||
|
||||
horizontalMinimumValue: 0
|
||||
horizontalMaximumValue: flickableItem ? flickableItem.contentWidth - viewport.width : 0
|
||||
onHorizontalMaximumValueChanged: {
|
||||
wheelArea.horizontalRecursionGuard = true
|
||||
//if horizontalMaximumValue changed, horizontalValue may be actually synced with
|
||||
wheelArea.horizontalValue = flickableItem.contentX - flickableItem.originX;
|
||||
wheelArea.horizontalRecursionGuard = false
|
||||
}
|
||||
|
||||
verticalMinimumValue: 0
|
||||
verticalMaximumValue: flickableItem ? flickableItem.contentHeight - viewport.height + __viewTopMargin : 0
|
||||
onVerticalMaximumValueChanged: {
|
||||
wheelArea.verticalRecursionGuard = true
|
||||
//if verticalMaximumValue changed, verticalValue may be actually synced with
|
||||
wheelArea.verticalValue = flickableItem.contentY - flickableItem.originY;
|
||||
wheelArea.verticalRecursionGuard = false
|
||||
}
|
||||
|
||||
// The default scroll speed for typical angle-based mouse wheels. The value
|
||||
// comes originally from QTextEdit, which sets 20px steps by default, as well as
|
||||
// QQuickWheelArea.
|
||||
// TODO: centralize somewhere, QPlatformTheme?
|
||||
scrollSpeed: 20 * (__style && __style.__wheelScrollLines || 1)
|
||||
|
||||
Connections {
|
||||
target: flickableItem
|
||||
|
||||
function onContentYChanged() {
|
||||
wheelArea.verticalRecursionGuard = true
|
||||
wheelArea.verticalValue = flickableItem.contentY - flickableItem.originY
|
||||
wheelArea.verticalRecursionGuard = false
|
||||
}
|
||||
function onContentXChanged() {
|
||||
wheelArea.horizontalRecursionGuard = true
|
||||
wheelArea.horizontalValue = flickableItem.contentX - flickableItem.originX
|
||||
wheelArea.horizontalRecursionGuard = false
|
||||
}
|
||||
}
|
||||
|
||||
onVerticalValueChanged: {
|
||||
if (!verticalRecursionGuard) {
|
||||
var effectiveContentY = flickableItem.contentY - flickableItem.originY
|
||||
if (effectiveContentY < flickThreshold && verticalDelta > speedThreshold) {
|
||||
flickableItem.flick(ignored, Math.min(maxFlick, acceleration * verticalDelta))
|
||||
} else if (effectiveContentY > flickableItem.contentHeight - flickThreshold - viewport.height
|
||||
&& verticalDelta < -speedThreshold) {
|
||||
flickableItem.flick(ignored, Math.max(-maxFlick, acceleration * verticalDelta))
|
||||
} else {
|
||||
flickableItem.contentY = verticalValue + flickableItem.originY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onHorizontalValueChanged: {
|
||||
if (!horizontalRecursionGuard)
|
||||
flickableItem.contentX = horizontalValue + flickableItem.originX
|
||||
}
|
||||
}
|
||||
|
||||
ScrollViewHelper {
|
||||
id: scroller
|
||||
anchors.fill: parent
|
||||
active: wheelArea.active
|
||||
property bool outerFrame: !frameVisible || !(__style ? __style.__externalScrollBars : 0)
|
||||
property int scrollBarSpacing: outerFrame ? 0 : (__style ? __style.__scrollBarSpacing : 0)
|
||||
property int verticalScrollbarOffset: verticalScrollBar.visible && !verticalScrollBar.isTransient ?
|
||||
verticalScrollBar.width + scrollBarSpacing : 0
|
||||
property int horizontalScrollbarOffset: horizontalScrollBar.visible && !horizontalScrollBar.isTransient ?
|
||||
horizontalScrollBar.height + scrollBarSpacing : 0
|
||||
Loader {
|
||||
id: frameLoader
|
||||
sourceComponent: __style ? __style.frame : null
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: scroller.outerFrame ? 0 : scroller.verticalScrollbarOffset
|
||||
anchors.bottomMargin: scroller.outerFrame ? 0 : scroller.horizontalScrollbarOffset
|
||||
}
|
||||
|
||||
Item {
|
||||
id: viewportItem
|
||||
anchors.fill: frameLoader
|
||||
anchors.topMargin: frameVisible ? __style.padding.top : 0
|
||||
anchors.leftMargin: frameVisible ? __style.padding.left : 0
|
||||
anchors.rightMargin: (frameVisible ? __style.padding.right : 0) + (scroller.outerFrame ? scroller.verticalScrollbarOffset : 0)
|
||||
anchors.bottomMargin: (frameVisible ? __style.padding.bottom : 0) + (scroller.outerFrame ? scroller.horizontalScrollbarOffset : 0)
|
||||
clip: true
|
||||
}
|
||||
}
|
||||
FocusFrame { visible: highlightOnFocus && root.activeFocus }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQml 2.14 as Qml
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype Slider
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup controls
|
||||
\brief Provides a vertical or horizontal slider control.
|
||||
|
||||
\image slider.png
|
||||
|
||||
The slider is the classic control for providing a bounded value. It lets
|
||||
the user move a slider handle along a horizontal or vertical groove
|
||||
and translates the handle's position into a value within the legal range.
|
||||
|
||||
\code
|
||||
Slider {
|
||||
value: 0.5
|
||||
}
|
||||
\endcode
|
||||
|
||||
The slider value is by default in the range [0, 1]. If integer values are
|
||||
needed, you can set the \l stepSize.
|
||||
|
||||
You can create a custom appearance for a Slider by
|
||||
assigning a \l {SliderStyle}.
|
||||
*/
|
||||
|
||||
Control {
|
||||
id: slider
|
||||
|
||||
/*!
|
||||
\qmlproperty enumeration Slider::orientation
|
||||
|
||||
This property holds the layout orientation of the slider.
|
||||
The default value is \c Qt.Horizontal.
|
||||
*/
|
||||
property int orientation: Qt.Horizontal
|
||||
|
||||
/*!
|
||||
\qmlproperty real Slider::minimumValue
|
||||
|
||||
This property holds the minimum value of the slider.
|
||||
The default value is \c{0.0}.
|
||||
*/
|
||||
property alias minimumValue: range.minimumValue
|
||||
|
||||
/*!
|
||||
\qmlproperty real Slider::maximumValue
|
||||
|
||||
This property holds the maximum value of the slider.
|
||||
The default value is \c{1.0}.
|
||||
*/
|
||||
property alias maximumValue: range.maximumValue
|
||||
|
||||
/*!
|
||||
\qmlproperty bool Slider::updateValueWhileDragging
|
||||
|
||||
This property indicates whether the current \l value should be updated while
|
||||
the user is moving the slider handle, or only when the button has been released.
|
||||
This property could for instance be modified if changing the slider value would turn
|
||||
out to be too time consuming.
|
||||
|
||||
The default value is \c true.
|
||||
*/
|
||||
property bool updateValueWhileDragging: true
|
||||
|
||||
/*!
|
||||
\qmlproperty bool Slider::pressed
|
||||
|
||||
This property indicates whether the slider handle is being pressed.
|
||||
*/
|
||||
readonly property alias pressed: mouseArea.pressed
|
||||
|
||||
/*!
|
||||
\qmlproperty bool Slider::hovered
|
||||
|
||||
This property indicates whether the slider handle is being hovered.
|
||||
*/
|
||||
readonly property alias hovered: mouseArea.handleHovered
|
||||
|
||||
/*!
|
||||
\qmlproperty real Slider::stepSize
|
||||
|
||||
This property indicates the slider step size.
|
||||
|
||||
A value of 0 indicates that the value of the slider operates in a
|
||||
continuous range between \l minimumValue and \l maximumValue.
|
||||
|
||||
Any non 0 value indicates a discrete stepSize. The following example
|
||||
will generate a slider with integer values in the range [0-5].
|
||||
|
||||
\qml
|
||||
Slider {
|
||||
maximumValue: 5.0
|
||||
stepSize: 1.0
|
||||
}
|
||||
\endqml
|
||||
|
||||
The default value is \c{0.0}.
|
||||
*/
|
||||
property alias stepSize: range.stepSize
|
||||
|
||||
/*!
|
||||
\qmlproperty real Slider::value
|
||||
|
||||
This property holds the current value of the slider.
|
||||
The default value is \c{0.0}.
|
||||
*/
|
||||
property alias value: range.value
|
||||
|
||||
/*!
|
||||
\qmlproperty bool Slider::activeFocusOnPress
|
||||
|
||||
This property indicates whether the slider should receive active focus when
|
||||
pressed.
|
||||
*/
|
||||
property bool activeFocusOnPress: false
|
||||
|
||||
/*!
|
||||
\qmlproperty bool Slider::tickmarksEnabled
|
||||
|
||||
This property indicates whether the slider should display tickmarks
|
||||
at step intervals. Tick mark spacing is calculated based on the
|
||||
\l stepSize property.
|
||||
|
||||
The default value is \c false.
|
||||
|
||||
\note This property may be ignored on some platforms when using the native style (e.g. Android).
|
||||
*/
|
||||
property bool tickmarksEnabled: false
|
||||
|
||||
/*!
|
||||
\qmlproperty bool Slider::wheelEnabled
|
||||
|
||||
This property determines whether the control handles wheel events.
|
||||
The default value is \c true.
|
||||
|
||||
\since QtQuick.Controls 1.6
|
||||
*/
|
||||
property alias wheelEnabled: wheelarea.enabled
|
||||
|
||||
/*! \internal */
|
||||
property bool __horizontal: orientation === Qt.Horizontal
|
||||
|
||||
/*! \internal
|
||||
The extra arguments positionAtMinimum and positionAtMaximum are there to force
|
||||
re-evaluation of the handle position when the constraints change (QTBUG-41255),
|
||||
and the same for range.minimumValue (QTBUG-51765) and range.maximumValue (QTBUG-63354).
|
||||
*/
|
||||
property real __handlePos: range.valueForPosition(__horizontal ? fakeHandle.x : fakeHandle.y,
|
||||
range.positionAtMinimum, range.positionAtMaximum, range.minimumValue, range.maximumValue)
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
Accessible.role: Accessible.Slider
|
||||
/*! \internal */
|
||||
function accessibleIncreaseAction() {
|
||||
range.increaseSingleStep()
|
||||
}
|
||||
/*! \internal */
|
||||
function accessibleDecreaseAction() {
|
||||
range.decreaseSingleStep()
|
||||
}
|
||||
|
||||
style: Settings.styleComponent(Settings.style, "SliderStyle.qml", slider)
|
||||
|
||||
Keys.onRightPressed: if (__horizontal) range.increaseSingleStep()
|
||||
Keys.onLeftPressed: if (__horizontal) range.decreaseSingleStep()
|
||||
Keys.onUpPressed: if (!__horizontal) range.increaseSingleStep()
|
||||
Keys.onDownPressed: if (!__horizontal) range.decreaseSingleStep()
|
||||
|
||||
RangeModel {
|
||||
id: range
|
||||
minimumValue: 0.0
|
||||
maximumValue: 1.0
|
||||
value: 0
|
||||
stepSize: 0.0
|
||||
inverted: __horizontal ? false : true
|
||||
|
||||
positionAtMinimum: 0
|
||||
positionAtMaximum: __horizontal ? slider.width - fakeHandle.width : slider.height - fakeHandle.height
|
||||
}
|
||||
|
||||
Item {
|
||||
id: fakeHandle
|
||||
anchors.verticalCenter: __horizontal ? parent.verticalCenter : undefined
|
||||
anchors.horizontalCenter: !__horizontal ? parent.horizontalCenter : undefined
|
||||
width: __panel.handleWidth
|
||||
height: __panel.handleHeight
|
||||
|
||||
function updatePos() {
|
||||
if (updateValueWhileDragging && !mouseArea.drag.active)
|
||||
range.position = __horizontal ? x : y
|
||||
}
|
||||
|
||||
onXChanged: updatePos();
|
||||
onYChanged: updatePos();
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
property int clickOffset: 0
|
||||
property real pressX: 0
|
||||
property real pressY: 0
|
||||
property bool handleHovered: false
|
||||
|
||||
function clamp ( val ) {
|
||||
return Math.max(range.positionAtMinimum, Math.min(range.positionAtMaximum, val))
|
||||
}
|
||||
|
||||
function updateHandlePosition(mouse, force) {
|
||||
var pos, overThreshold
|
||||
if (__horizontal) {
|
||||
pos = clamp (mouse.x + clickOffset - fakeHandle.width/2)
|
||||
overThreshold = Math.abs(mouse.x - pressX) >= Settings.dragThreshold
|
||||
if (overThreshold)
|
||||
preventStealing = true
|
||||
if (overThreshold || force)
|
||||
fakeHandle.x = pos
|
||||
} else if (!__horizontal) {
|
||||
pos = clamp (mouse.y + clickOffset- fakeHandle.height/2)
|
||||
overThreshold = Math.abs(mouse.y - pressY) >= Settings.dragThreshold
|
||||
if (overThreshold)
|
||||
preventStealing = true
|
||||
if (overThreshold || force)
|
||||
fakeHandle.y = pos
|
||||
}
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
if (pressed)
|
||||
updateHandlePosition(mouse, !Settings.hasTouchScreen || preventStealing)
|
||||
|
||||
var point = mouseArea.mapToItem(fakeHandle, mouse.x, mouse.y)
|
||||
handleHovered = fakeHandle.contains(Qt.point(point.x, point.y))
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
if (slider.activeFocusOnPress)
|
||||
slider.forceActiveFocus();
|
||||
|
||||
if (handleHovered) {
|
||||
var point = mouseArea.mapToItem(fakeHandle, mouse.x, mouse.y)
|
||||
clickOffset = __horizontal ? fakeHandle.width/2 - point.x : fakeHandle.height/2 - point.y
|
||||
}
|
||||
pressX = mouse.x
|
||||
pressY = mouse.y
|
||||
updateHandlePosition(mouse, !Settings.hasTouchScreen)
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
updateHandlePosition(mouse, Settings.hasTouchScreen)
|
||||
// If we don't update while dragging, this is the only
|
||||
// moment that the range is updated.
|
||||
if (!slider.updateValueWhileDragging)
|
||||
range.position = __horizontal ? fakeHandle.x : fakeHandle.y;
|
||||
clickOffset = 0
|
||||
preventStealing = false
|
||||
}
|
||||
|
||||
onExited: handleHovered = false
|
||||
}
|
||||
|
||||
|
||||
// During the drag, we simply ignore the position set from the range, this
|
||||
// means that setting a value while dragging will not "interrupt" the
|
||||
// dragging activity.
|
||||
Qml.Binding {
|
||||
when: !mouseArea.drag.active
|
||||
target: fakeHandle
|
||||
property: __horizontal ? "x" : "y"
|
||||
value: range.position
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
|
||||
WheelArea {
|
||||
id: wheelarea
|
||||
anchors.fill: parent
|
||||
verticalValue: slider.value
|
||||
horizontalValue: slider.value
|
||||
horizontalMinimumValue: slider.minimumValue
|
||||
horizontalMaximumValue: slider.maximumValue
|
||||
verticalMinimumValue: slider.minimumValue
|
||||
verticalMaximumValue: slider.maximumValue
|
||||
property real step: (slider.maximumValue - slider.minimumValue)/(range.positionAtMaximum - range.positionAtMinimum)
|
||||
|
||||
onVerticalWheelMoved: {
|
||||
if (verticalDelta !== 0) {
|
||||
var delta = Math.abs(verticalDelta)*step > stepSize ? verticalDelta*step : verticalDelta/Math.abs(verticalDelta)*stepSize
|
||||
range.position = range.positionForValue(value - delta * (inverted ? 1 : -1))
|
||||
}
|
||||
}
|
||||
|
||||
onHorizontalWheelMoved: {
|
||||
if (horizontalDelta !== 0) {
|
||||
var delta = Math.abs(horizontalDelta)*step > stepSize ? horizontalDelta*step : horizontalDelta/Math.abs(horizontalDelta)*stepSize
|
||||
range.position = range.positionForValue(value + delta * (inverted ? 1 : -1))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,397 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype SpinBox
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup controls
|
||||
\brief Provides a spin box control.
|
||||
|
||||
\image spinbox.png
|
||||
|
||||
SpinBox allows the user to choose a value by clicking the up or down buttons, or by
|
||||
pressing up or down on the keyboard. The user can also type the value in manually.
|
||||
|
||||
By default the SpinBox provides discrete values in the range [0-99] with a \l stepSize of 1 and 0 \l decimals.
|
||||
|
||||
\code
|
||||
SpinBox {
|
||||
id: spinbox
|
||||
}
|
||||
\endcode
|
||||
|
||||
Note that if you require decimal values you will need to set the \l decimals to a non 0 value.
|
||||
|
||||
\code
|
||||
SpinBox {
|
||||
id: spinbox
|
||||
decimals: 2
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
|
||||
Control {
|
||||
id: spinbox
|
||||
|
||||
/*!
|
||||
\qmlproperty real SpinBox::value
|
||||
|
||||
The value of this SpinBox, clamped to \l minimumValue and \l maximumValue.
|
||||
|
||||
The default value is \c{0.0}.
|
||||
*/
|
||||
property alias value: validator.value
|
||||
|
||||
/*!
|
||||
\qmlproperty real SpinBox::minimumValue
|
||||
|
||||
The minimum value of the SpinBox range.
|
||||
The \l value is clamped to this value.
|
||||
|
||||
The default value is \c{0.0}.
|
||||
*/
|
||||
property alias minimumValue: validator.minimumValue
|
||||
|
||||
/*!
|
||||
\qmlproperty real SpinBox::maximumValue
|
||||
|
||||
The maximum value of the SpinBox range.
|
||||
The \l value is clamped to this value. If maximumValue is smaller than
|
||||
\l minimumValue, \l minimumValue will be enforced.
|
||||
|
||||
The default value is \c{99}.
|
||||
*/
|
||||
property alias maximumValue: validator.maximumValue
|
||||
|
||||
/*! \qmlproperty real SpinBox::stepSize
|
||||
The amount by which the \l value is incremented/decremented when a
|
||||
spin button is pressed.
|
||||
|
||||
The default value is \c{1.0}.
|
||||
*/
|
||||
property alias stepSize: validator.stepSize
|
||||
|
||||
/*! \qmlproperty string SpinBox::suffix
|
||||
The suffix for the value. I.e "cm" */
|
||||
property alias suffix: validator.suffix
|
||||
|
||||
/*! \qmlproperty string SpinBox::prefix
|
||||
The prefix for the value. I.e "$" */
|
||||
property alias prefix: validator.prefix
|
||||
|
||||
/*! \qmlproperty int SpinBox::decimals
|
||||
This property indicates the amount of decimals.
|
||||
Note that if you enter more decimals than specified, they will
|
||||
be truncated to the specified amount of decimal places.
|
||||
The default value is \c{0}.
|
||||
*/
|
||||
property alias decimals: validator.decimals
|
||||
|
||||
/*! \qmlproperty font SpinBox::font
|
||||
|
||||
This property indicates the current font used by the SpinBox.
|
||||
*/
|
||||
property alias font: input.font
|
||||
|
||||
/*!
|
||||
\qmlproperty int SpinBox::cursorPosition
|
||||
\since QtQuick.Controls 1.5
|
||||
|
||||
This property holds the position of the cursor in the SpinBox.
|
||||
*/
|
||||
property alias cursorPosition: input.cursorPosition
|
||||
|
||||
|
||||
/*! This property indicates whether the Spinbox should get active
|
||||
focus when pressed.
|
||||
The default value is \c true.
|
||||
*/
|
||||
property bool activeFocusOnPress: true
|
||||
|
||||
/*! \qmlproperty enumeration horizontalAlignment
|
||||
\since QtQuick.Controls 1.1
|
||||
|
||||
This property indicates how the content is horizontally aligned
|
||||
within the text field.
|
||||
|
||||
The supported values are:
|
||||
\list
|
||||
\li Qt.AlignLeft
|
||||
\li Qt.AlignHCenter
|
||||
\li Qt.AlignRight
|
||||
\endlist
|
||||
|
||||
The default value is style dependent.
|
||||
*/
|
||||
property int horizontalAlignment: __panel ? __panel.horizontalAlignment : Qt.AlignLeft
|
||||
|
||||
/*!
|
||||
\qmlproperty bool SpinBox::hovered
|
||||
|
||||
This property indicates whether the control is being hovered.
|
||||
*/
|
||||
readonly property bool hovered: mouseArea.containsMouse || input.containsMouse
|
||||
|| mouseUp.containsMouse || mouseDown.containsMouse
|
||||
|
||||
/*!
|
||||
\qmlsignal SpinBox::editingFinished()
|
||||
\since QtQuick.Controls 1.1
|
||||
|
||||
This signal is emitted when the Return or Enter key is pressed or
|
||||
the control loses focus.
|
||||
|
||||
The corresponding handler is \c onEditingFinished.
|
||||
*/
|
||||
signal editingFinished()
|
||||
|
||||
/*!
|
||||
\qmlproperty bool SpinBox::selectByMouse
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
This property determines if the user can select the text with the
|
||||
mouse.
|
||||
|
||||
The default value is \c true.
|
||||
*/
|
||||
property bool selectByMouse: true
|
||||
|
||||
/*!
|
||||
\qmlproperty bool SpinBox::inputMethodComposing
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
This property holds whether the SpinBox has partial text input from an input method.
|
||||
|
||||
While it is composing an input method may rely on mouse or key events from the SpinBox
|
||||
to edit or commit the partial text. This property can be used to determine when to disable
|
||||
events handlers that may interfere with the correct operation of an input method.
|
||||
*/
|
||||
readonly property bool inputMethodComposing: !!input.inputMethodComposing
|
||||
|
||||
/*!
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
This property contains the edit \l Menu for working
|
||||
with text selection. Set it to \c null if no menu
|
||||
is wanted.
|
||||
*/
|
||||
property Component menu: input.editMenu.defaultMenu
|
||||
|
||||
style: Settings.styleComponent(Settings.style, "SpinBoxStyle.qml", spinbox)
|
||||
|
||||
/*! \internal */
|
||||
function __increment() {
|
||||
validator.increment()
|
||||
if (activeFocus)
|
||||
input.selectValue()
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __decrement() {
|
||||
validator.decrement()
|
||||
if (activeFocus)
|
||||
input.selectValue()
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property alias __text: input.text
|
||||
|
||||
/*! \internal */
|
||||
property alias __baselineOffset: input.baselineOffset
|
||||
|
||||
__styleData: QtObject {
|
||||
readonly property bool upEnabled: value != maximumValue;
|
||||
readonly property alias upHovered: mouseUp.containsMouse
|
||||
readonly property alias upPressed: mouseUp.pressed
|
||||
|
||||
readonly property bool downEnabled: value != minimumValue;
|
||||
readonly property alias downPressed: mouseDown.pressed
|
||||
readonly property alias downHovered: mouseDown.containsMouse
|
||||
|
||||
readonly property int contentHeight: Math.max(input.implicitHeight, 16)
|
||||
readonly property int contentWidth: Math.max(maxSizeHint.implicitWidth, minSizeHint.implicitWidth)
|
||||
}
|
||||
|
||||
Text {
|
||||
id: maxSizeHint
|
||||
text: prefix + maximumValue.toFixed(decimals) + suffix
|
||||
font: input.font
|
||||
visible: false
|
||||
}
|
||||
|
||||
Text {
|
||||
id: minSizeHint
|
||||
text: prefix + minimumValue.toFixed(decimals) + suffix
|
||||
font: input.font
|
||||
visible: false
|
||||
}
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
onActiveFocusChanged: if (activeFocus) input.selectValue()
|
||||
|
||||
Accessible.name: input.text
|
||||
Accessible.role: Accessible.SpinBox
|
||||
Accessible.editable: true
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
onPressed: if (activeFocusOnPress) input.forceActiveFocus()
|
||||
onWheel: {
|
||||
if (wheel.angleDelta.y > 0)
|
||||
__increment();
|
||||
else
|
||||
__decrement();
|
||||
}
|
||||
}
|
||||
|
||||
TextInputWithHandles {
|
||||
id: input
|
||||
clip: contentWidth > width
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: __style ? __style.padding.left : 0
|
||||
anchors.topMargin: __style ? __style.padding.top : 0
|
||||
anchors.rightMargin: __style ? __style.padding.right: 0
|
||||
anchors.bottomMargin: __style ? __style.padding.bottom: 0
|
||||
|
||||
control: spinbox
|
||||
cursorHandle: __style ? __style.__cursorHandle : undefined
|
||||
selectionHandle: __style ? __style.__selectionHandle : undefined
|
||||
|
||||
focus: true
|
||||
activeFocusOnPress: spinbox.activeFocusOnPress
|
||||
|
||||
horizontalAlignment: spinbox.horizontalAlignment
|
||||
verticalAlignment: __panel ? __panel.verticalAlignment : Qt.AlignVCenter
|
||||
inputMethodHints: Qt.ImhFormattedNumbersOnly
|
||||
|
||||
validator: SpinBoxValidator {
|
||||
id: validator
|
||||
property bool ready: false // Delay validation until all properties are ready
|
||||
onTextChanged: if (ready) input.text = validator.text
|
||||
Component.onCompleted: {input.text = validator.text ; ready = true}
|
||||
}
|
||||
onAccepted: {
|
||||
input.text = validator.text
|
||||
selectValue()
|
||||
}
|
||||
|
||||
Keys.forwardTo: spinbox
|
||||
|
||||
onEditingFinished: spinbox.editingFinished()
|
||||
|
||||
font: __panel ? __panel.font : TextSingleton.font
|
||||
color: __panel ? __panel.foregroundColor : "black"
|
||||
selectionColor: __panel ? __panel.selectionColor : "black"
|
||||
selectedTextColor: __panel ? __panel.selectedTextColor : "black"
|
||||
|
||||
opacity: parent.enabled ? 1 : 0.5
|
||||
renderType: __style ? __style.renderType : Text.NativeRendering
|
||||
|
||||
function selectValue() {
|
||||
select(prefix.length, text.length - suffix.length)
|
||||
}
|
||||
}
|
||||
|
||||
// Spinbox increment button
|
||||
|
||||
MouseArea {
|
||||
id: mouseUp
|
||||
objectName: "mouseUp"
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
|
||||
property var upRect: __panel ? __panel.upRect : null
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
|
||||
anchors.leftMargin: upRect ? upRect.x : 0
|
||||
anchors.topMargin: upRect ? upRect.y : 0
|
||||
|
||||
width: upRect ? upRect.width : 0
|
||||
height: upRect ? upRect.height : 0
|
||||
|
||||
onClicked: __increment()
|
||||
onPressed: if (!Settings.hasTouchScreen && activeFocusOnPress) input.forceActiveFocus()
|
||||
|
||||
property bool autoincrement: false;
|
||||
onReleased: autoincrement = false
|
||||
onExited: autoincrement = false
|
||||
Timer { running: mouseUp.pressed; interval: 350 ; onTriggered: mouseUp.autoincrement = true }
|
||||
Timer { running: mouseUp.autoincrement && mouseUp.containsMouse; interval: 60 ; repeat: true ; onTriggered: __increment() }
|
||||
}
|
||||
|
||||
// Spinbox decrement button
|
||||
|
||||
MouseArea {
|
||||
id: mouseDown
|
||||
objectName: "mouseDown"
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
|
||||
onClicked: __decrement()
|
||||
onPressed: if (!Settings.hasTouchScreen && activeFocusOnPress) input.forceActiveFocus()
|
||||
|
||||
property var downRect: __panel ? __panel.downRect : null
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
|
||||
anchors.leftMargin: downRect ? downRect.x : 0
|
||||
anchors.topMargin: downRect ? downRect.y : 0
|
||||
|
||||
width: downRect ? downRect.width : 0
|
||||
height: downRect ? downRect.height : 0
|
||||
|
||||
property bool autoincrement: false;
|
||||
onReleased: autoincrement = false
|
||||
onExited: autoincrement = false
|
||||
Timer { running: mouseDown.pressed; interval: 350 ; onTriggered: mouseDown.autoincrement = true }
|
||||
Timer { running: mouseDown.autoincrement && mouseDown.containsMouse; interval: 60 ; repeat: true ; onTriggered: __decrement() }
|
||||
}
|
||||
|
||||
Keys.onUpPressed: __increment()
|
||||
Keys.onDownPressed: __decrement()
|
||||
}
|
||||
@@ -0,0 +1,633 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Controls.Private 1.0 as Private
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
/*!
|
||||
\qmltype SplitView
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup views
|
||||
\ingroup controls
|
||||
\brief Lays out items with a draggable splitter between each item.
|
||||
|
||||
\image splitview.png
|
||||
|
||||
SplitView is a control that lays out items horizontally or
|
||||
vertically with a draggable splitter between each item.
|
||||
|
||||
There will always be one (and only one) item in the SplitView that has \l{Layout::fillWidth}{Layout.fillWidth}
|
||||
set to \c true (or \l{Layout::fillHeight}{Layout.fillHeight}, if orientation is Qt.Vertical). This means that the
|
||||
item will get all leftover space when other items have been laid out.
|
||||
By default, the last visible child of the SplitView will have this set, but
|
||||
it can be changed by explicitly setting fillWidth to \c true on another item.
|
||||
|
||||
As the fillWidth item will automatically be resized to fit the extra space, explicit assignments
|
||||
to its width and height properties will be ignored (but \l{Layout::minimumWidth}{Layout.minimumWidth} and
|
||||
\l{Layout::maximumWidth}{Layout.maximumWidth} will still be respected).
|
||||
The initial sizes of other items should be set via their width and height properties.
|
||||
Any binding assignment to an item's width or height will be broken as soon as the user
|
||||
drags that item's splitter handle.
|
||||
|
||||
A handle can belong to the item either on the left or top side, or on the right or bottom side:
|
||||
\list
|
||||
\li If the fillWidth item is to the right: the handle belongs to the left item.
|
||||
\li if the fillWidth item is on the left: the handle belongs to the right item.
|
||||
\endlist
|
||||
|
||||
This will again control which item gets resized when the user drags a handle,
|
||||
and which handle gets hidden when an item is told to hide.
|
||||
|
||||
SplitView supports setting attached Layout properties on child items, which
|
||||
means that you can set the following attached properties for each child:
|
||||
\list
|
||||
\li \l{Layout::minimumWidth}{Layout.minimumWidth}
|
||||
\li \l{Layout::minimumHeight}{Layout.minimumHeight}
|
||||
\li \l{Layout::maximumWidth}{Layout.maximumWidth}
|
||||
\li \l{Layout::maximumHeight}{Layout.maximumHeight}
|
||||
\li \l{Layout::fillWidth}{Layout.fillWidth} (\c true for only one child)
|
||||
\li \l{Layout::fillHeight}{Layout.fillHeight} (\c true for only one child)
|
||||
\endlist
|
||||
|
||||
\note import QtQuick.Layouts 1.0 in your QML file in order to use the Layout
|
||||
attached properties inside SplitView.
|
||||
|
||||
Example:
|
||||
|
||||
To create a SplitView with three items, and let the center item get superfluous space, one
|
||||
could do the following:
|
||||
|
||||
\qml
|
||||
SplitView {
|
||||
anchors.fill: parent
|
||||
orientation: Qt.Horizontal
|
||||
|
||||
Rectangle {
|
||||
width: 200
|
||||
Layout.maximumWidth: 400
|
||||
color: "lightblue"
|
||||
Text {
|
||||
text: "View 1"
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: centerItem
|
||||
Layout.minimumWidth: 50
|
||||
Layout.fillWidth: true
|
||||
color: "lightgray"
|
||||
Text {
|
||||
text: "View 2"
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
width: 200
|
||||
color: "lightgreen"
|
||||
Text {
|
||||
text: "View 3"
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\endqml
|
||||
*/
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
/*!
|
||||
\qmlproperty enumeration SplitView::orientation
|
||||
|
||||
This property holds the orientation of the SplitView.
|
||||
The value can be either \c Qt.Horizontal or \c Qt.Vertical.
|
||||
The default value is \c Qt.Horizontal.
|
||||
*/
|
||||
property int orientation: Qt.Horizontal
|
||||
|
||||
/*!
|
||||
This property holds the delegate that will be instantiated between each
|
||||
child item. Inside the delegate the following properties are available:
|
||||
|
||||
\table
|
||||
\row \li readonly property bool styleData.index \li Specifies the index of the splitter handle. The handle
|
||||
between the first and the second item will get index 0,
|
||||
the next handle index 1 etc.
|
||||
\row \li readonly property bool styleData.hovered \li The handle is being hovered.
|
||||
\row \li readonly property bool styleData.pressed \li The handle is being pressed.
|
||||
\row \li readonly property bool styleData.resizing \li The handle is being dragged.
|
||||
\endtable
|
||||
|
||||
*/
|
||||
property Component handleDelegate: Rectangle {
|
||||
width: 1
|
||||
height: 1
|
||||
color: Qt.darker(pal.window, 1.5)
|
||||
}
|
||||
|
||||
/*!
|
||||
This propery is \c true when the user is resizing any of the items by
|
||||
dragging on the splitter handles.
|
||||
*/
|
||||
property bool resizing: false
|
||||
|
||||
/*! \internal */
|
||||
default property alias __contents: contents.data
|
||||
/*! \internal */
|
||||
property alias __items: splitterItems.children
|
||||
/*! \internal */
|
||||
property alias __handles: splitterHandles.children
|
||||
|
||||
clip: true
|
||||
Component.onCompleted: d.init()
|
||||
onWidthChanged: d.updateLayout()
|
||||
onHeightChanged: d.updateLayout()
|
||||
onOrientationChanged: d.changeOrientation()
|
||||
|
||||
/*! \qmlmethod void SplitView::addItem(Item item)
|
||||
Add an \a item to the end of the view.
|
||||
\since QtQuick.Controls 1.3 */
|
||||
function addItem(item) {
|
||||
d.updateLayoutGuard = true
|
||||
d.addItem_impl(item)
|
||||
d.calculateImplicitSize()
|
||||
d.updateLayoutGuard = false
|
||||
d.updateFillIndex()
|
||||
}
|
||||
|
||||
/*! \qmlmethod void SplitView::removeItem(Item item)
|
||||
Remove \a item from the view.
|
||||
\since QtQuick.Controls 1.4 */
|
||||
function removeItem(item) {
|
||||
d.updateLayoutGuard = true
|
||||
var result = d.removeItem_impl(item)
|
||||
if (result !== null) {
|
||||
d.calculateImplicitSize()
|
||||
d.updateLayoutGuard = false
|
||||
d.updateFillIndex()
|
||||
}
|
||||
else {
|
||||
d.updateLayoutGuard = false
|
||||
}
|
||||
}
|
||||
|
||||
SystemPalette { id: pal }
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
readonly property string leftMargin: horizontal ? "leftMargin" : "topMargin"
|
||||
readonly property string topMargin: horizontal ? "topMargin" : "leftMargin"
|
||||
readonly property string rightMargin: horizontal ? "rightMargin" : "bottomMargin"
|
||||
|
||||
property bool horizontal: orientation == Qt.Horizontal
|
||||
readonly property string minimum: horizontal ? "minimumWidth" : "minimumHeight"
|
||||
readonly property string maximum: horizontal ? "maximumWidth" : "maximumHeight"
|
||||
readonly property string otherMinimum: horizontal ? "minimumHeight" : "minimumWidth"
|
||||
readonly property string otherMaximum: horizontal ? "maximumHeight" : "maximumWidth"
|
||||
readonly property string offset: horizontal ? "x" : "y"
|
||||
readonly property string otherOffset: horizontal ? "y" : "x"
|
||||
readonly property string size: horizontal ? "width" : "height"
|
||||
readonly property string otherSize: horizontal ? "height" : "width"
|
||||
readonly property string implicitSize: horizontal ? "implicitWidth" : "implicitHeight"
|
||||
readonly property string implicitOtherSize: horizontal ? "implicitHeight" : "implicitWidth"
|
||||
|
||||
property int fillIndex: -1
|
||||
property bool updateLayoutGuard: true
|
||||
|
||||
function extraMarginSize(item, other) {
|
||||
if (typeof(other) === 'undefined')
|
||||
other = false;
|
||||
if (other === horizontal)
|
||||
// vertical
|
||||
return item.Layout.topMargin + item.Layout.bottomMargin
|
||||
return item.Layout.leftMargin + item.Layout.rightMargin
|
||||
}
|
||||
|
||||
function addItem_impl(item)
|
||||
{
|
||||
// temporarily set fillIndex to new item
|
||||
fillIndex = __items.length
|
||||
if (splitterItems.children.length > 0)
|
||||
handleLoader.createObject(splitterHandles, {"__handleIndex":splitterItems.children.length - 1})
|
||||
|
||||
item.parent = splitterItems
|
||||
d.initItemConnections(item)
|
||||
}
|
||||
|
||||
function initItemConnections(item)
|
||||
{
|
||||
// should match disconnections in terminateItemConnections
|
||||
item.widthChanged.connect(d.updateLayout)
|
||||
item.heightChanged.connect(d.updateLayout)
|
||||
item.Layout.maximumWidthChanged.connect(d.updateLayout)
|
||||
item.Layout.minimumWidthChanged.connect(d.updateLayout)
|
||||
item.Layout.maximumHeightChanged.connect(d.updateLayout)
|
||||
item.Layout.minimumHeightChanged.connect(d.updateLayout)
|
||||
item.Layout.leftMarginChanged.connect(d.updateLayout)
|
||||
item.Layout.topMarginChanged.connect(d.updateLayout)
|
||||
item.Layout.rightMarginChanged.connect(d.updateLayout)
|
||||
item.Layout.bottomMarginChanged.connect(d.updateLayout)
|
||||
item.visibleChanged.connect(d.updateFillIndex)
|
||||
item.Layout.fillWidthChanged.connect(d.updateFillIndex)
|
||||
item.Layout.fillHeightChanged.connect(d.updateFillIndex)
|
||||
}
|
||||
|
||||
function terminateItemConnections(item)
|
||||
{
|
||||
// should match connections in initItemConnections
|
||||
item.widthChanged.disconnect(d.updateLayout)
|
||||
item.heightChanged.disconnect(d.updateLayout)
|
||||
item.Layout.maximumWidthChanged.disconnect(d.updateLayout)
|
||||
item.Layout.minimumWidthChanged.disconnect(d.updateLayout)
|
||||
item.Layout.maximumHeightChanged.disconnect(d.updateLayout)
|
||||
item.Layout.minimumHeightChanged.disconnect(d.updateLayout)
|
||||
item.visibleChanged.disconnect(d.updateFillIndex)
|
||||
item.Layout.fillWidthChanged.disconnect(d.updateFillIndex)
|
||||
item.Layout.fillHeightChanged.disconnect(d.updateFillIndex)
|
||||
}
|
||||
|
||||
function removeItem_impl(item)
|
||||
{
|
||||
var pos = itemPos(item)
|
||||
|
||||
// Check pos range
|
||||
if (pos < 0 || pos >= __items.length)
|
||||
return null
|
||||
|
||||
// Temporary unset the fillIndex
|
||||
fillIndex = __items.length - 1
|
||||
|
||||
// Remove the handle at the left/right of the item that
|
||||
// is going to be removed
|
||||
var handlePos = -1
|
||||
var hasPrevious = pos > 0
|
||||
var hasNext = (pos + 1) < __items.length
|
||||
|
||||
if (hasPrevious)
|
||||
handlePos = pos-1
|
||||
else if (hasNext)
|
||||
handlePos = pos
|
||||
if (handlePos >= 0) {
|
||||
var handle = __handles[handlePos]
|
||||
handle.visible = false
|
||||
handle.parent = null
|
||||
handle.destroy()
|
||||
for (var i = handlePos; i < __handles.length; ++i)
|
||||
__handles[i].__handleIndex = i
|
||||
}
|
||||
|
||||
// Remove the item.
|
||||
// Disconnect the item to be removed
|
||||
terminateItemConnections(item)
|
||||
item.parent = null
|
||||
|
||||
return item
|
||||
}
|
||||
|
||||
function itemPos(item)
|
||||
{
|
||||
for (var i = 0; i < __items.length; ++i)
|
||||
if (item === __items[i])
|
||||
return i
|
||||
return -1
|
||||
}
|
||||
|
||||
function init()
|
||||
{
|
||||
for (var i=0; i<__contents.length; ++i) {
|
||||
var item = __contents[i];
|
||||
if (!item.hasOwnProperty("x"))
|
||||
continue
|
||||
addItem_impl(item)
|
||||
i-- // item was removed from list
|
||||
}
|
||||
|
||||
d.calculateImplicitSize()
|
||||
d.updateLayoutGuard = false
|
||||
d.updateFillIndex()
|
||||
}
|
||||
|
||||
function updateFillIndex()
|
||||
{
|
||||
if (lastItem.visible !== root.visible)
|
||||
return
|
||||
var policy = (root.orientation === Qt.Horizontal) ? "fillWidth" : "fillHeight"
|
||||
for (var i=0; i<__items.length-1; ++i) {
|
||||
if (__items[i].Layout[policy] === true)
|
||||
break;
|
||||
}
|
||||
|
||||
d.fillIndex = i
|
||||
d.updateLayout()
|
||||
}
|
||||
|
||||
function changeOrientation()
|
||||
{
|
||||
if (__items.length == 0)
|
||||
return;
|
||||
d.updateLayoutGuard = true
|
||||
|
||||
// Swap width/height for items and handles:
|
||||
for (var i=0; i<__items.length; ++i) {
|
||||
var item = __items[i]
|
||||
var tmp = item.x
|
||||
item.x = item.y
|
||||
item.y = tmp
|
||||
tmp = item.width
|
||||
item.width = item.height
|
||||
item.height = tmp
|
||||
|
||||
var handle = __handles[i]
|
||||
if (handle) {
|
||||
tmp = handle.x
|
||||
handle.x = handle.y
|
||||
handle.y = handle.x
|
||||
tmp = handle.width
|
||||
handle.width = handle.height
|
||||
handle.height = tmp
|
||||
}
|
||||
}
|
||||
|
||||
// Change d.horizontal explicit, since the binding will change too late:
|
||||
d.horizontal = orientation == Qt.Horizontal
|
||||
d.updateLayoutGuard = false
|
||||
d.updateFillIndex()
|
||||
}
|
||||
|
||||
function calculateImplicitSize()
|
||||
{
|
||||
var implicitSize = 0
|
||||
var implicitOtherSize = 0
|
||||
|
||||
for (var i=0; i<__items.length; ++i) {
|
||||
var item = __items[i];
|
||||
implicitSize += clampedMinMax(item[d.size], item.Layout[minimum], item.Layout[maximum]) + extraMarginSize(item)
|
||||
var os = clampedMinMax(item[otherSize], item.Layout[otherMinimum], item.Layout[otherMaximum]) + extraMarginSize(item, true)
|
||||
implicitOtherSize = Math.max(implicitOtherSize, os)
|
||||
|
||||
var handle = __handles[i]
|
||||
if (handle)
|
||||
implicitSize += handle[d.size] //### Can handles have margins??
|
||||
}
|
||||
|
||||
root[d.implicitSize] = implicitSize
|
||||
root[d.implicitOtherSize] = implicitOtherSize
|
||||
}
|
||||
|
||||
function clampedMinMax(value, minimum, maximum)
|
||||
{
|
||||
if (value < minimum)
|
||||
value = minimum
|
||||
if (value > maximum)
|
||||
value = maximum
|
||||
return value
|
||||
}
|
||||
|
||||
function accumulatedSize(firstIndex, lastIndex, includeFillItemMinimum)
|
||||
{
|
||||
// Go through items and handles, and
|
||||
// calculate their accummulated width.
|
||||
var w = 0
|
||||
for (var i=firstIndex; i<lastIndex; ++i) {
|
||||
|
||||
var item = __items[i]
|
||||
if (item.visible || i == d.fillIndex) {
|
||||
if (i !== d.fillIndex)
|
||||
w += item[d.size] + extraMarginSize(item)
|
||||
else if (includeFillItemMinimum && item.Layout[minimum] !== undefined)
|
||||
w += item.Layout[minimum] + extraMarginSize(item)
|
||||
}
|
||||
|
||||
var handle = __handles[i]
|
||||
if (handle && handle.visible)
|
||||
w += handle[d.size]
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
function updateLayout()
|
||||
{
|
||||
// This function will reposition both handles and
|
||||
// items according to the their width/height:
|
||||
if (__items.length === 0)
|
||||
return;
|
||||
if (!lastItem.visible)
|
||||
return;
|
||||
if (d.updateLayoutGuard === true)
|
||||
return
|
||||
d.updateLayoutGuard = true
|
||||
|
||||
// Ensure all items within their min/max:
|
||||
for (var i=0; i<__items.length; ++i) {
|
||||
if (i !== d.fillIndex) {
|
||||
var item = __items[i];
|
||||
var clampedSize = clampedMinMax(item[d.size], item.Layout[d.minimum], item.Layout[d.maximum])
|
||||
if (clampedSize != item[d.size])
|
||||
item[d.size] = clampedSize
|
||||
}
|
||||
}
|
||||
|
||||
// Set size of fillItem to remaining available space.
|
||||
// Special case: If SplitView size is zero, we leave fillItem with the size
|
||||
// it already got, and assume that SplitView ends up with implicit size as size:
|
||||
if (root[d.size] != 0) {
|
||||
var fillItem = __items[fillIndex]
|
||||
var superfluous = root[d.size] - d.accumulatedSize(0, __items.length, false)
|
||||
fillItem[d.size] = clampedMinMax(superfluous - extraMarginSize(fillItem), fillItem.Layout[minimum], fillItem.Layout[maximum]);
|
||||
}
|
||||
|
||||
// Position items and handles according to their width:
|
||||
var lastVisibleItem, lastVisibleHandle, handle
|
||||
var pos = 0;
|
||||
for (i=0; i<__items.length; ++i) {
|
||||
// Position item to the right of the previous visible handle:
|
||||
item = __items[i];
|
||||
if (item.visible || i == d.fillIndex) {
|
||||
pos += item.Layout[leftMargin]
|
||||
item[d.offset] = pos
|
||||
item[d.otherOffset] = item.Layout[topMargin]
|
||||
item[d.otherSize] = clampedMinMax(root[otherSize], item.Layout[otherMinimum], item.Layout[otherMaximum]) - extraMarginSize(item, true)
|
||||
lastVisibleItem = item
|
||||
pos += Math.max(0, item[d.size]) + item.Layout[rightMargin]
|
||||
}
|
||||
|
||||
handle = __handles[i]
|
||||
if (handle && handle.visible) {
|
||||
handle[d.offset] = pos
|
||||
handle[d.otherOffset] = 0 //### can handles have margins?
|
||||
handle[d.otherSize] = root[d.otherSize]
|
||||
lastVisibleHandle = handle
|
||||
pos += handle[d.size]
|
||||
}
|
||||
}
|
||||
|
||||
d.updateLayoutGuard = false
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: handleLoader
|
||||
Loader {
|
||||
id: itemHandle
|
||||
|
||||
property int __handleIndex: -1
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property int index: __handleIndex
|
||||
readonly property alias hovered: mouseArea.containsMouse
|
||||
readonly property alias pressed: mouseArea.pressed
|
||||
readonly property bool resizing: mouseArea.drag.active
|
||||
onResizingChanged: root.resizing = resizing
|
||||
}
|
||||
property bool resizeLeftItem: (d.fillIndex > __handleIndex)
|
||||
visible: __items[__handleIndex + (resizeLeftItem ? 0 : 1)].visible
|
||||
sourceComponent: handleDelegate
|
||||
onWidthChanged: d.updateLayout()
|
||||
onHeightChanged: d.updateLayout()
|
||||
onXChanged: moveHandle()
|
||||
onYChanged: moveHandle()
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
property real defaultMargin: Private.Settings.hasTouchScreen ? Screen.pixelDensity * 3.5 : 2
|
||||
anchors.leftMargin: (parent.width <= 1) ? -defaultMargin : 0
|
||||
anchors.rightMargin: (parent.width <= 1) ? -defaultMargin : 0
|
||||
anchors.topMargin: (parent.height <= 1) ? -defaultMargin : 0
|
||||
anchors.bottomMargin: (parent.height <= 1) ? -defaultMargin : 0
|
||||
hoverEnabled: Private.Settings.hoverEnabled
|
||||
drag.threshold: 0
|
||||
drag.target: parent
|
||||
drag.axis: root.orientation === Qt.Horizontal ? Drag.XAxis : Drag.YAxis
|
||||
cursorShape: root.orientation === Qt.Horizontal ? Qt.SplitHCursor : Qt.SplitVCursor
|
||||
}
|
||||
|
||||
function moveHandle() {
|
||||
// Moving the handle means resizing an item. Which one,
|
||||
// left or right, depends on where the fillItem is.
|
||||
// 'updateLayout' will be overridden in case new width violates max/min.
|
||||
// 'updateLayout' will be triggered when an item changes width.
|
||||
if (d.updateLayoutGuard)
|
||||
return
|
||||
|
||||
var leftHandle, leftItem, rightItem, rightHandle
|
||||
var leftEdge, rightEdge, newWidth, leftStopX, rightStopX
|
||||
var i
|
||||
|
||||
if (resizeLeftItem) {
|
||||
// Ensure that the handle is not crossing other handles. So
|
||||
// find the first visible handle to the left to determine the left edge:
|
||||
leftEdge = 0
|
||||
for (i=__handleIndex-1; i>=0; --i) {
|
||||
leftHandle = __handles[i]
|
||||
if (leftHandle.visible) {
|
||||
leftEdge = leftHandle[d.offset] + leftHandle[d.size]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure: leftStopX >= itemHandle[d.offset] >= rightStopX
|
||||
var min = d.accumulatedSize(__handleIndex+1, __items.length, true)
|
||||
rightStopX = root[d.size] - min - itemHandle[d.size]
|
||||
leftStopX = Math.max(leftEdge, itemHandle[d.offset])
|
||||
itemHandle[d.offset] = Math.min(rightStopX, Math.max(leftStopX, itemHandle[d.offset]))
|
||||
|
||||
newWidth = itemHandle[d.offset] - leftEdge
|
||||
leftItem = __items[__handleIndex]
|
||||
// The next line will trigger 'updateLayout':
|
||||
leftItem[d.size] = newWidth
|
||||
} else {
|
||||
// Resize item to the right.
|
||||
// Ensure that the handle is not crossing other handles. So
|
||||
// find the first visible handle to the right to determine the right edge:
|
||||
rightEdge = root[d.size]
|
||||
for (i=__handleIndex+1; i<__handles.length; ++i) {
|
||||
rightHandle = __handles[i]
|
||||
if (rightHandle.visible) {
|
||||
rightEdge = rightHandle[d.offset]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure: leftStopX <= itemHandle[d.offset] <= rightStopX
|
||||
min = d.accumulatedSize(0, __handleIndex+1, true)
|
||||
leftStopX = min - itemHandle[d.size]
|
||||
rightStopX = Math.min((rightEdge - itemHandle[d.size]), itemHandle[d.offset])
|
||||
itemHandle[d.offset] = Math.max(leftStopX, Math.min(itemHandle[d.offset], rightStopX))
|
||||
|
||||
newWidth = rightEdge - (itemHandle[d.offset] + itemHandle[d.size])
|
||||
rightItem = __items[__handleIndex+1]
|
||||
// The next line will trigger 'updateLayout':
|
||||
rightItem[d.size] = newWidth
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contents
|
||||
visible: false
|
||||
anchors.fill: parent
|
||||
}
|
||||
Item {
|
||||
id: splitterItems
|
||||
anchors.fill: parent
|
||||
}
|
||||
Item {
|
||||
id: splitterHandles
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Item {
|
||||
id: lastItem
|
||||
onVisibleChanged: d.updateFillIndex()
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
for (var i=0; i<splitterItems.children.length; ++i) {
|
||||
var item = splitterItems.children[i];
|
||||
d.terminateItemConnections(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,996 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype StackView
|
||||
\inherits Item
|
||||
\ingroup views
|
||||
\ingroup controls
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
|
||||
\brief Provides a stack-based navigation model.
|
||||
|
||||
\image stackview.png
|
||||
|
||||
StackView implements a stack-based navigation model, which can be used
|
||||
with a set of interlinked information pages. Items are pushed onto the stack
|
||||
as the user navigates deeper into the material, and popped off again when he
|
||||
chooses to go back.
|
||||
|
||||
The \l{Qt Quick Controls 1 - Touch Gallery}{touch gallery} example is a good
|
||||
starting point to understand how StackView works. The following snippet
|
||||
from the example shows how it can be used:
|
||||
|
||||
\qml
|
||||
StackView {
|
||||
id: stack
|
||||
initialItem: view
|
||||
|
||||
Component {
|
||||
id: view
|
||||
|
||||
MouseArea {
|
||||
Text {
|
||||
text: stack.depth
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
onClicked: stack.push(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
\section1 Using StackView in an Application
|
||||
Using StackView in an application is typically a simple matter of adding
|
||||
the StackView as a child of a Window. The stack is usually anchored to the
|
||||
edges of the window, except at the top or bottom where it might be anchored
|
||||
to a status bar, or some other similar UI component. The stack can then be
|
||||
used by invoking its navigation methods. The first item to show in the StackView
|
||||
is the one that was assigned to \l initialItem.
|
||||
|
||||
\note Items pushed onto the stack view have \l{Supported Attached Properties}{Stack attached properties}.
|
||||
|
||||
\section1 Basic Navigation
|
||||
There are three primary navigation operations in StackView: push(), pop(), and
|
||||
replace (replace by specifying argument \c replace to push()).
|
||||
These correspond to classic stack operations where "push" adds an item to the
|
||||
top of a stack, "pop" removes the top item from the stack, and "replace" is like a
|
||||
pop followed by a push, in that it replaces the topmost item on the stack with
|
||||
a new item (but the applied transtition might be different). The topmost item
|
||||
in the stack corresponds to the one that is \l{StackView::currentItem} {currently}
|
||||
visible on the screen. That means that "push" is the logical equivalent of navigating
|
||||
forward or deeper into the application, "pop" is the equivalent of navigating back,
|
||||
and "replace" is the equivalent of replacing the current item.
|
||||
|
||||
Sometimes it is necessary to go back more than a single step in the stack, for
|
||||
example, to return to a "main" item or some kind of section item in the application.
|
||||
For this use case, it is possible to specify an item as a parameter for pop().
|
||||
This is called an "unwind" operation as the stack gets unwound to the specified item.
|
||||
If the item is not found, then the stack unwinds until there is only a single item in
|
||||
the stack, which then becomes the current item. To explicitly unwind to the bottom
|
||||
of the stack, it is recommended to use \l{pop()} {pop(null)}, though technically any
|
||||
non-existent item will do.
|
||||
|
||||
Given the stack [A, B, C]:
|
||||
|
||||
\list
|
||||
\li \l{push()}{push(D)} => [A, B, C, D] - "push" transition animation between C and D
|
||||
\li pop() => [A, B] - "pop" transition animation between C and B
|
||||
\li \l{push()}{push(D, replace)} => [A, B, D] - "replace" transition between C and D
|
||||
\li \l{pop()}{pop(A)} => [A] - "pop" transition between C and A
|
||||
\endlist
|
||||
|
||||
\note When the stack is empty, a push() will not perform a
|
||||
transition animation because there is nothing to transition from (typically during
|
||||
application start-up). A pop() on a stack with depth 1 or 0 is a no-operation.
|
||||
If all items need to be removed from the stack, a separate function clear() is
|
||||
available.
|
||||
|
||||
Calling push() returns the item that was pushed onto the stack.
|
||||
Calling pop() returns the item that was popped off the stack. When pop() is
|
||||
called in an unwind operation, the top-most item (the first item that was
|
||||
popped, which will also be the one transitioning out) is returned.
|
||||
|
||||
\section1 Deep Linking
|
||||
\e{Deep linking} means launching an application into a particular state. For example,
|
||||
a newspaper application could be launched into showing a particular article,
|
||||
bypassing the front item (and possibly a section item) that would normally have
|
||||
to be navigated through to get to the article concerned. In terms of StackView, deep
|
||||
linking means the ability to modify the state of the stack, so much so that it is
|
||||
possible to push a set of items to the top of the stack, or to completely reset
|
||||
the stack to a given state.
|
||||
|
||||
The API for deep linking in StackView is the same as for basic navigation. Pushing
|
||||
an array instead of a single item, will involve that all the items in that array will
|
||||
be pushed onto the stack. The transition animation, however, will be conducted as
|
||||
if only the last item in the array was pushed onto the stack. The normal semantics
|
||||
of push() apply for deep linking, meaning that push() adds whatever is pushed onto
|
||||
the stack. Note also that only the last item of the array will be loaded.
|
||||
The rest will be lazy-loaded as needed when entering the screen upon subsequent
|
||||
calls to pop (or when requesting the item by using \a get).
|
||||
|
||||
This gives us the following result, given the stack [A, B, C]:
|
||||
|
||||
\list
|
||||
\li \l{push()}{push([D, E, F])} => [A, B, C, D, E, F] - "push" transition animation between C and F
|
||||
\li \l{push()}{push([D, E, F], replace)} => [A, B, D, E, F] - "replace" transition animation between C and F
|
||||
\li clear(); \l{push()}{push([D, E, F])} => [D, E, F] - no transition animation (since the stack was empty)
|
||||
\endlist
|
||||
|
||||
\section1 Pushing items
|
||||
|
||||
An item pushed onto the StackView can be either an Item, a URL, a string
|
||||
containing a URL, or a Component. To push it, assign it to a property "item"
|
||||
inside a property list, and pass it as an argument to \l{StackView::push}{push}:
|
||||
|
||||
\code
|
||||
stackView.push({item: yourItem})
|
||||
\endcode
|
||||
|
||||
The list can contain several properties that control how the item should be pushed:
|
||||
\list
|
||||
\li \c item: this property is required, and holds the item to be pushed.
|
||||
\li \c properties: a list of QML properties to be assigned to the item upon push. These
|
||||
properties will be copied into the item at load time, or when the item will become
|
||||
the current item (normally upon push).
|
||||
\li \c immediate: set this property to \c true to skip transition effects. When pushing
|
||||
an array, this property only needs to be set on the first element to make the
|
||||
whole operation immediate.
|
||||
\li \c replace: set this property to replace the current item on the stack. When pushing
|
||||
an array, you only need to set this property on the first element to replace
|
||||
as many elements on the stack as inside the array.
|
||||
\li \c destroyOnPop: set this boolean to \c true if StackView needs to destroy the item when
|
||||
it is popped off the stack. By default (if \a destroyOnPop is not specified), StackView
|
||||
will destroy items pushed as components or URLs. Items not destroyed will be re-parented
|
||||
back to the original parents they had before being pushed onto the stack and hidden.
|
||||
If you need to set this property, do it with care, so that items are not leaked.
|
||||
\endlist
|
||||
|
||||
If the only argument needed is "item", the following short-hand notation can be applied:
|
||||
|
||||
\code
|
||||
stackView.push(yourItem)
|
||||
\endcode
|
||||
|
||||
You can push several items in one go by using an array of property lists. This is
|
||||
more efficient than pushing items one by one, as StackView can then load only the
|
||||
last item in the list. The rest will be loaded as they are about to become
|
||||
the current item (which happens when the stack is popped). The following example shows how
|
||||
to push an array of items:
|
||||
|
||||
\code
|
||||
stackView.push([{item: yourItem1}, {item: yourItem2}])
|
||||
\endcode
|
||||
|
||||
If an inline item is pushed, the item is temporarily re-parented into the StackView. When the item
|
||||
is later popped off, it gets re-parented back to its original owner again.
|
||||
If, however, an item is pushed as a component or a URL, the actual item will be created as an
|
||||
item from that component. This happens automatically when the item is about to become the current
|
||||
item in the stack. Ownership of the item will then normally be taken by the StackView, which will
|
||||
automatically destroy the item when it is later popped off. The component that declared the item, by
|
||||
contrast, remains in the ownership of the application and is not destroyed by the stack.
|
||||
This can be overridden by explicitly setting \c{destroyOnPop} in the list of arguments given to push.
|
||||
|
||||
If the \c properties to be pushed are specified, they will be copied into the item at loading time
|
||||
(in case of a component or URL), or when the item becomes the current item (in case of an inline
|
||||
item). The following example shows how this can be done:
|
||||
|
||||
\code
|
||||
stackView.push({item: someItem, properties: {fgcolor: "red", bgcolor: "blue"}})
|
||||
\endcode
|
||||
|
||||
|
||||
\note If an item is declared inside another item, and that parent gets destroyed,
|
||||
(even if a component was used), that child item will also be destroyed.
|
||||
This follows normal Qt parent-child destruction rules, but sometimes comes as a surprise
|
||||
for developers.
|
||||
|
||||
\section1 Lifecycle
|
||||
An item's lifecycle in the StackView can have the following transitions:
|
||||
\list 1
|
||||
\li instantiation
|
||||
\li inactive
|
||||
\li activating
|
||||
\li active
|
||||
\li deactivating
|
||||
\li inactive
|
||||
\li destruction
|
||||
\endlist
|
||||
|
||||
It can move any number of times between inactive and active. When an item is activated,
|
||||
it's visible on the screen and is considered to be the current item. An item
|
||||
in a StackView that is not visible is not activated, even if the item is currently the
|
||||
top-most item in the stack. When the stack becomes visible, the item that is top-most gets
|
||||
activated. Likewise if the stack is then hidden, the topmost item would be deactivated.
|
||||
Popping the item off the top of the stack at this point would not result in further
|
||||
deactivation since the item is not active.
|
||||
|
||||
There is an attached \l{Stack::status}{Stack.status} property that tracks the lifecycle. This
|
||||
property is an enumeration with the following values: \c Stack.Inactive, \c Stack.Activating,
|
||||
\c Stack.Active and \c Stack.Deactivating. Combined with the normal \c Component.onComplete and
|
||||
\c Component.onDestruction signals, the entire lifecycle is thus:
|
||||
|
||||
\list
|
||||
\li Created: Component.onCompleted()
|
||||
\li Activating: Stack.onStatusChanged (Stack.status is Stack.Activating)
|
||||
\li Acivated: Stack.onStatusChanged (Stack.status is Stack.Active)
|
||||
\li Deactivating: Stack.onStatusChanged (Stack.status is Stack.Deactivating)
|
||||
\li Deactivated: Stack.onStatusChanged (Stack.status is Stack.Inactive)
|
||||
\li Destruction: Component.onDestruction()
|
||||
\endlist
|
||||
|
||||
\section1 Finding items
|
||||
Sometimes it is necessary to search for an item, for example, in order to unwind the stack to
|
||||
an item to which the application does not have a reference. This is facilitated using a
|
||||
function find() in StackView. The find() function takes a callback function as its
|
||||
only argument. The callback gets invoked for each item in the stack (starting at the top).
|
||||
If the callback returns true, then it signals that a match has been found and the find()
|
||||
function returns that item. If the callback fails to return true (no match is found),
|
||||
then find() returns \c null.
|
||||
|
||||
The code below searches for an item in the stack that has a name "order_id" and then unwinds to
|
||||
that item. Note that since find() returns \c {null} if no item is found, and since pop unwinds to
|
||||
the bottom of the stack if null is given as the target item, the code works well even in
|
||||
case no matching item is found.
|
||||
|
||||
\code
|
||||
stackView.pop(stackView.find(function(item) {
|
||||
return item.name == "order_id";
|
||||
}));
|
||||
\endcode
|
||||
|
||||
You can also get to an item in the stack using \l {get()}{get(index)}. You should use
|
||||
this function if your item depends on another item in the stack, as the function will
|
||||
ensure that the item at the given index gets loaded before it is returned.
|
||||
|
||||
\code
|
||||
previousItem = stackView.get(myItem.Stack.index - 1));
|
||||
\endcode
|
||||
|
||||
\section1 Transitions
|
||||
|
||||
A transition is performed whenever a item is pushed or popped, and consists of
|
||||
two items: enterItem and exitItem. The StackView itself will never move items
|
||||
around, but instead delegates the job to an external animation set provided
|
||||
by the style or the application developer. How items should visually enter and leave the stack
|
||||
(and the geometry they should end up with) is therefore completely controlled from the outside.
|
||||
|
||||
When the transition starts, the StackView will search for a transition that
|
||||
matches the operation executed. There are three transitions to choose
|
||||
from: \l {StackViewDelegate::}{pushTransition}, \l {StackViewDelegate::}{popTransition},
|
||||
and \l {StackViewDelegate::}{replaceTransition}. Each implements how
|
||||
\c enterItem should animate in, and \c exitItem out. The transitions are
|
||||
collected inside a StackViewDelegate object assigned to
|
||||
\l {StackView::delegate}{delegate}. By default, popTransition and
|
||||
replaceTransition will be the same as pushTransition, unless you set them
|
||||
to something else.
|
||||
|
||||
A simple fade transition could be implemented as:
|
||||
|
||||
\qml
|
||||
StackView {
|
||||
delegate: StackViewDelegate {
|
||||
function transitionFinished(properties)
|
||||
{
|
||||
properties.exitItem.opacity = 1
|
||||
}
|
||||
|
||||
pushTransition: StackViewTransition {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "opacity"
|
||||
from: 0
|
||||
to: 1
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "opacity"
|
||||
from: 1
|
||||
to: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
PushTransition needs to inherit from StackViewTransition, which is a ParallelAnimation that
|
||||
contains the properties \c enterItem and \c exitItem. These items should be assigned to the
|
||||
\c target property of animations within the transition. Since the same items instance can
|
||||
be pushed several times to a StackView, you should always override
|
||||
\l {StackViewDelegate::transitionFinished()}{StackViewDelegate.transitionFinished()}.
|
||||
Implement this function to reset any properties animated on the exitItem so that later
|
||||
transitions can expect the items to be in a default state.
|
||||
|
||||
A more complex example could look like the following. Here, the items are lying on the side before
|
||||
being rotated to an upright position:
|
||||
|
||||
\qml
|
||||
StackView {
|
||||
delegate: StackViewDelegate {
|
||||
function transitionFinished(properties)
|
||||
{
|
||||
properties.exitItem.x = 0
|
||||
properties.exitItem.rotation = 0
|
||||
}
|
||||
|
||||
pushTransition: StackViewTransition {
|
||||
SequentialAnimation {
|
||||
ScriptAction {
|
||||
script: enterItem.rotation = 90
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "x"
|
||||
from: enterItem.width
|
||||
to: 0
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "rotation"
|
||||
from: 90
|
||||
to: 0
|
||||
}
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "x"
|
||||
from: 0
|
||||
to: -exitItem.width
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
\section2 Advanced usage
|
||||
|
||||
When the StackView needs a new transition, it first calls
|
||||
\l {StackViewDelegate::getTransition()}{StackViewDelegate.getTransition()}.
|
||||
The base implementation of this function just looks for a property named \c properties.name inside
|
||||
itself (root), which is how it finds \c {property Component pushTransition} in the examples above.
|
||||
|
||||
\code
|
||||
function getTransition(properties)
|
||||
{
|
||||
return root[properties.name]
|
||||
}
|
||||
\endcode
|
||||
|
||||
You can override this function for your delegate if you need extra logic to decide which
|
||||
transition to return. You could for example introspect the items, and return different animations
|
||||
depending on the their internal state. StackView will expect you to return a Component that
|
||||
contains a StackViewTransition, or a StackViewTransition directly. The former is easier, as StackView will
|
||||
then create the transition and later destroy it when it's done, while avoiding any side effects
|
||||
caused by the transition being alive long after it has run. Returning a StackViewTransition directly
|
||||
can be useful if you need to write some sort of transition caching for performance reasons.
|
||||
As an optimization, you can also return \c null to signal that you just want to show/hide the items
|
||||
immediately without creating or running any transitions. You can also override this function if
|
||||
you need to alter the items in any way before the transition starts.
|
||||
|
||||
\c properties contains the properties that will be assigned to the StackViewTransition before
|
||||
it runs. In fact, you can add more properties to this object during the call
|
||||
if you need to initialize additional properties of your custom StackViewTransition when the returned
|
||||
component is instantiated.
|
||||
|
||||
The following example shows how you can decide which animation to use at runtime:
|
||||
|
||||
\qml
|
||||
StackViewDelegate {
|
||||
function getTransition(properties)
|
||||
{
|
||||
return (properties.enterItem.Stack.index % 2) ? horizontalTransition : verticalTransition
|
||||
}
|
||||
|
||||
function transitionFinished(properties)
|
||||
{
|
||||
properties.exitItem.x = 0
|
||||
properties.exitItem.y = 0
|
||||
}
|
||||
|
||||
property Component horizontalTransition: StackViewTransition {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "x"
|
||||
from: target.width
|
||||
to: 0
|
||||
duration: 300
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "x"
|
||||
from: 0
|
||||
to: target.width
|
||||
duration: 300
|
||||
}
|
||||
}
|
||||
|
||||
property Component verticalTransition: StackViewTransition {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "y"
|
||||
from: target.height
|
||||
to: 0
|
||||
duration: 300
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "y"
|
||||
from: 0
|
||||
to: target.height
|
||||
duration: 300
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
\section1 Supported Attached Properties
|
||||
|
||||
Items in a StackView support these attached properties:
|
||||
\list
|
||||
\li \l{Stack::index}{Stack.index} - Contains the index of the item inside the StackView
|
||||
\li \l{Stack::view}{Stack.view} - Contains the StackView the item is in
|
||||
\li \l{Stack::status}{Stack.status} - Contains the status of the item
|
||||
\endlist
|
||||
*/
|
||||
|
||||
FocusScope {
|
||||
id: root
|
||||
|
||||
/*! \qmlproperty int StackView::depth
|
||||
\readonly
|
||||
The number of items currently pushed onto the stack.
|
||||
*/
|
||||
readonly property alias depth: root.__depth
|
||||
|
||||
/*! \qmlproperty Item StackView::currentItem
|
||||
\readonly
|
||||
The currently top-most item in the stack.
|
||||
*/
|
||||
readonly property alias currentItem: root.__currentItem
|
||||
|
||||
/*! The first item that should be shown when the StackView is created.
|
||||
\a initialItem can take same value as the first argument to \l{StackView::push()}
|
||||
{StackView.push()}. Note that this is just a convenience for writing
|
||||
\c{Component.onCompleted: stackView.push(myInitialItem)}
|
||||
|
||||
Examples:
|
||||
|
||||
\list
|
||||
\li initialItem: Qt.resolvedUrl("MyItem.qml")
|
||||
\li initialItem: myItem
|
||||
\li initialItem: {"item" : Qt.resolvedUrl("MyRectangle.qml"), "properties" : {"color" : "red"}}
|
||||
\endlist
|
||||
\sa push
|
||||
*/
|
||||
property var initialItem: null
|
||||
|
||||
/*! \readonly
|
||||
\a busy is \c true if a transition is running, and \c false otherwise. */
|
||||
readonly property bool busy: __currentTransition !== null
|
||||
|
||||
/*! The transitions to use when pushing or popping items.
|
||||
For better understanding on how to apply custom transitions, read \l{Transitions}.
|
||||
\sa {Transitions} */
|
||||
property StackViewDelegate delegate: StackViewSlideDelegate {}
|
||||
|
||||
/*! \qmlmethod Item StackView::push(Item item)
|
||||
Pushes an \a item onto the stack.
|
||||
|
||||
The function can also take a property list as argument - \c {Item StackView::push(jsobject dict)}, which
|
||||
should contain one or more of the following properties:
|
||||
\list
|
||||
\li \a item: this property is required, and holds the item you want to push.
|
||||
\li \e properties: a list of QML properties that should be assigned
|
||||
to the item upon push. These properties will be copied into the item when it is
|
||||
loaded (in case of a component or URL), or when it becomes the current item for the
|
||||
first time (normally upon push).
|
||||
\li \e immediate: set this property to \c true to skip transition effects. When pushing
|
||||
an array, you only need to set this property on the first element to make the
|
||||
whole operation immediate.
|
||||
\li \e replace: set this property to replace the current item on the stack. When pushing
|
||||
an array, you only need to set this property on the first element to replace
|
||||
as many elements on the stack as inside the array.
|
||||
\li \e destroyOnPop: set this property to specify if the item needs to be destroyed
|
||||
when its popped off the stack. By default (if \e destroyOnPop is not specified),
|
||||
StackView will destroy items pushed as components or URLs. Items
|
||||
not destroyed will be re-parented to the original parents they had before being
|
||||
pushed onto the stack, and hidden. If you need to set this property, do it with
|
||||
care, so that items are not leaked.
|
||||
\endlist
|
||||
|
||||
You can also push an array of items (property lists) if you need to push several items
|
||||
in one go. A transition will then only occur between the current item and the last
|
||||
item in the list. Loading the other items will be deferred until needed.
|
||||
|
||||
Examples:
|
||||
\list
|
||||
\li stackView.push({item:anItem})
|
||||
\li stackView.push({item:aURL, immediate: true, replace: true})
|
||||
\li stackView.push({item:aRectangle, properties:{color:"red"}})
|
||||
\li stackView.push({item:aComponent, properties:{color:"red"}})
|
||||
\li stackView.push({item:aComponent.createObject(), destroyOnPop:true})
|
||||
\li stackView.push([{item:anitem, immediate:true}, {item:aURL}])
|
||||
\endlist
|
||||
|
||||
\note If the only argument needed is "item", you can apply the following short-
|
||||
hand notation: \c{stackView.push(anItem)}.
|
||||
|
||||
Returns the item that became current.
|
||||
|
||||
\sa initialItem
|
||||
\sa {Pushing items}
|
||||
*/
|
||||
function push(item) {
|
||||
// Note: we support two different APIs in this function; The old meego API, and
|
||||
// the new "property list" API. Hence the reason for hiding the fact that you
|
||||
// can pass more arguments than shown in the signature:
|
||||
if (__recursionGuard(true))
|
||||
return
|
||||
var properties = arguments[1]
|
||||
var immediate = arguments[2]
|
||||
var replace = arguments[3]
|
||||
var arrayPushed = (item instanceof Array)
|
||||
var firstItem = arrayPushed ? item[0] : item
|
||||
immediate = (immediate || JSArray.stackView.length === 0)
|
||||
|
||||
if (firstItem && firstItem.item && firstItem.hasOwnProperty("x") === false) {
|
||||
// Property list API used:
|
||||
immediate = immediate || firstItem.immediate
|
||||
replace = replace || firstItem.replace
|
||||
}
|
||||
|
||||
// Create, and push, a new javascript object, called "element", onto the stack.
|
||||
// This element contains all the information necessary to construct the item, and
|
||||
// will, after loaded, also contain the loaded item:
|
||||
if (arrayPushed) {
|
||||
if (item.length === 0)
|
||||
return
|
||||
var outElement = replace ? JSArray.pop() : JSArray.current()
|
||||
for (var i=0; i<item.length; ++i)
|
||||
JSArray.push({itemComponent:item[i], loaded: false, index: __depth, properties: properties});
|
||||
} else {
|
||||
outElement = replace ? JSArray.pop() : JSArray.current()
|
||||
JSArray.push({itemComponent:item, loaded: false, index: __depth, properties: properties})
|
||||
}
|
||||
|
||||
var currentElement = JSArray.current()
|
||||
var transition = {
|
||||
inElement: currentElement,
|
||||
outElement: outElement,
|
||||
immediate: immediate,
|
||||
replace: replace,
|
||||
push: true
|
||||
}
|
||||
__performTransition(transition)
|
||||
__recursionGuard(false)
|
||||
return __currentItem
|
||||
}
|
||||
|
||||
/*! \qmlmethod Item StackView::pop(Item item = undefined)
|
||||
Pops one or more items off the stack.
|
||||
|
||||
The function can also take a property list as argument - \c {Item StackView::pop(jsobject dict)},
|
||||
which can contain one or more of the following properties:
|
||||
\list
|
||||
\li \c item: if specified, all items down to (but not including) \a item will be
|
||||
popped off. If \a item is \c null, all items down to (but not including) the
|
||||
first item will be popped. If not specified, only the current item will be
|
||||
popped.
|
||||
\li \c immediate: set this property to \c true to skip transition effects.
|
||||
\endlist
|
||||
|
||||
Examples:
|
||||
\list
|
||||
\li stackView.pop()
|
||||
\li stackView.pop({item:someItem, immediate: true})
|
||||
\li stackView.pop({immediate: true})
|
||||
\li stackView.pop(null)
|
||||
\endlist
|
||||
|
||||
\note If the only argument needed is "item", you can apply the following short-
|
||||
hand notation: \c{stackView.pop(anItem)}.
|
||||
|
||||
Returns the item that was popped off
|
||||
\sa clear()
|
||||
*/
|
||||
function pop(item) {
|
||||
if (__depth <= 1)
|
||||
return null
|
||||
if (item && item.hasOwnProperty("x") === false) {
|
||||
// Property list API used:
|
||||
var immediate = (item.immediate === true)
|
||||
item = item.item
|
||||
} else {
|
||||
immediate = (arguments[1] === true)
|
||||
}
|
||||
|
||||
if (item === __currentItem)
|
||||
return
|
||||
|
||||
if (__recursionGuard(true))
|
||||
return
|
||||
|
||||
var outElement = JSArray.pop()
|
||||
var inElement = JSArray.current()
|
||||
|
||||
if (__depth > 1 && item !== undefined && item !== inElement.item) {
|
||||
// Pop from the top until we find 'item', and return the corresponding
|
||||
// element. Skip all non-loaded items (except the first), since no one
|
||||
// has any references to such items anyway:
|
||||
while (__depth > 1 && !JSArray.current().loaded)
|
||||
JSArray.pop()
|
||||
inElement = JSArray.current()
|
||||
while (__depth > 1 && item !== inElement.item) {
|
||||
JSArray.pop()
|
||||
__cleanup(inElement)
|
||||
while (__depth > 1 && !JSArray.current().loaded)
|
||||
JSArray.pop()
|
||||
inElement = JSArray.current()
|
||||
}
|
||||
}
|
||||
|
||||
var transition = {
|
||||
inElement: inElement,
|
||||
outElement: outElement,
|
||||
immediate: immediate,
|
||||
replace: false,
|
||||
push: false
|
||||
}
|
||||
__performTransition(transition)
|
||||
__recursionGuard(false)
|
||||
return outElement.item;
|
||||
}
|
||||
|
||||
/*! \qmlmethod void StackView::clear()
|
||||
Remove all items from the stack. No animations will be applied. */
|
||||
function clear() {
|
||||
if (__recursionGuard(true))
|
||||
return
|
||||
if (__currentTransition)
|
||||
__currentTransition.animation.complete()
|
||||
__currentItem = null
|
||||
var count = __depth
|
||||
for (var i=0; i<count; ++i) {
|
||||
var element = JSArray.pop()
|
||||
if (element.item)
|
||||
__cleanup(element);
|
||||
}
|
||||
__recursionGuard(false)
|
||||
}
|
||||
|
||||
/*! \qmlmethod Item StackView::find(function, bool onlySearchLoadedItems = false)
|
||||
Search for a specific item inside the stack. \a function will
|
||||
be called for each item in the stack (with the item as argument)
|
||||
until the function returns true. Return value will be the item found. For
|
||||
example:
|
||||
find(function(item, index) { return item.isTheOne })
|
||||
Set \a onlySearchLoadedItems to \c true to not load items that are
|
||||
not loaded into memory */
|
||||
function find(func, onlySearchLoadedItems) {
|
||||
for (var i=__depth-1; i>=0; --i) {
|
||||
var element = JSArray.stackView[i];
|
||||
if (onlySearchLoadedItems !== true)
|
||||
__loadElement(element)
|
||||
else if (!element.item)
|
||||
continue
|
||||
if (func(element.item))
|
||||
return element.item
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*! \qmlmethod Item StackView::get(int index, bool dontLoad = false)
|
||||
Returns the item at position \a index in
|
||||
the stack. If \a dontLoad is true, the
|
||||
item will not be forced to load (and \c null
|
||||
will be returned if not yet loaded) */
|
||||
function get(index, dontLoad)
|
||||
{
|
||||
if (index < 0 || index >= JSArray.stackView.length)
|
||||
return null
|
||||
var element = JSArray.stackView[index]
|
||||
if (dontLoad !== true) {
|
||||
__loadElement(element)
|
||||
return element.item
|
||||
} else if (element.item) {
|
||||
return element.item
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/*! \qmlmethod void StackView::completeTransition()
|
||||
Immediately completes any ongoing transition.
|
||||
/sa Animation.complete
|
||||
*/
|
||||
function completeTransition()
|
||||
{
|
||||
if (__recursionGuard(true))
|
||||
return
|
||||
if (__currentTransition)
|
||||
__currentTransition.animation.complete()
|
||||
__recursionGuard(false)
|
||||
}
|
||||
|
||||
/********* DEPRECATED API *********/
|
||||
|
||||
/*! \internal
|
||||
\deprecated Use Push() instead */
|
||||
function replace(item, properties, immediate) {
|
||||
push(item, properties, immediate, true)
|
||||
}
|
||||
|
||||
/********* PRIVATE API *********/
|
||||
|
||||
/*! \internal The currently top-most item on the stack. */
|
||||
property Item __currentItem: null
|
||||
/*! \internal The number of items currently pushed onto the stack. */
|
||||
property int __depth: 0
|
||||
/*! \internal Stores the transition info while a transition is ongoing */
|
||||
property var __currentTransition: null
|
||||
/*! \internal Stops the user from pushing items while preparing a transition */
|
||||
property bool __guard: false
|
||||
|
||||
Component.onCompleted: {
|
||||
if (initialItem)
|
||||
push(initialItem)
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
if (__currentTransition)
|
||||
__currentTransition.animation.complete()
|
||||
__currentItem = null
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __recursionGuard(use)
|
||||
{
|
||||
if (use && __guard) {
|
||||
console.warn("Warning: StackView: You cannot push/pop recursively!")
|
||||
console.trace()
|
||||
return true
|
||||
}
|
||||
__guard = use
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __loadElement(element)
|
||||
{
|
||||
if (element.loaded) {
|
||||
if (!element.item) {
|
||||
element.item = invalidItemReplacement.createObject(root)
|
||||
element.item.text = "\nError: The item has been deleted outside StackView!"
|
||||
}
|
||||
return
|
||||
}
|
||||
if (!element.itemComponent) {
|
||||
element.item = invalidItemReplacement.createObject(root)
|
||||
element.item.text = "\nError: Invalid item (item was 'null'). "
|
||||
+ "This might indicate that the item was deleted outside StackView!"
|
||||
return
|
||||
}
|
||||
|
||||
var comp = __resolveComponent(element.itemComponent, element)
|
||||
|
||||
// Assign properties to item:
|
||||
if (!element.properties)
|
||||
element.properties = {}
|
||||
|
||||
if (comp.hasOwnProperty("createObject")) {
|
||||
if (comp.status === Component.Error) {
|
||||
element.item = invalidItemReplacement.createObject(root)
|
||||
element.item.text = "\nError: Could not load: " + comp.errorString()
|
||||
} else {
|
||||
element.item = comp.createObject(root, element.properties)
|
||||
// Destroy items we create unless the user specified something else:
|
||||
if (!element.hasOwnProperty("destroyOnPop"))
|
||||
element.destroyOnPop = true
|
||||
}
|
||||
} else {
|
||||
// comp is already an Item, so just re-parent it into the StackView:
|
||||
element.item = comp
|
||||
element.originalParent = parent
|
||||
element.item.parent = root
|
||||
for (var prop in element.properties) {
|
||||
if (element.item.hasOwnProperty(prop))
|
||||
element.item[prop] = element.properties[prop];
|
||||
}
|
||||
// Do not destroy items we didn't create, unless the user specified something else:
|
||||
if (!element.hasOwnProperty("destroyOnPop"))
|
||||
element.destroyOnPop = false
|
||||
}
|
||||
|
||||
element.item.Stack.__index = element.index
|
||||
element.item.Stack.__view = root
|
||||
// Let item fill all available space by default:
|
||||
element.item.width = Qt.binding(function() { return root.width })
|
||||
element.item.height = Qt.binding(function() { return root.height })
|
||||
element.loaded = true
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __resolveComponent(unknownObjectType, element)
|
||||
{
|
||||
// We need this extra resolve function since we don't really
|
||||
// know what kind of object the user pushed. So we try to
|
||||
// figure it out by inspecting the object:
|
||||
if (unknownObjectType.hasOwnProperty("createObject")) {
|
||||
return unknownObjectType
|
||||
} else if (typeof unknownObjectType == "string") {
|
||||
return Qt.createComponent(unknownObjectType)
|
||||
} else if (unknownObjectType.hasOwnProperty("x")) {
|
||||
return unknownObjectType
|
||||
} else if (unknownObjectType.hasOwnProperty("item")) {
|
||||
// INVARIANT: user pushed a JS-object
|
||||
element.properties = unknownObjectType.properties
|
||||
if (!unknownObjectType.item)
|
||||
unknownObjectType.item = invalidItemReplacement
|
||||
if (unknownObjectType.hasOwnProperty("destroyOnPop"))
|
||||
element.destroyOnPop = unknownObjectType.destroyOnPop
|
||||
return __resolveComponent(unknownObjectType.item, element)
|
||||
} else {
|
||||
// We cannot determine the type, so assume its a URL:
|
||||
return Qt.createComponent(unknownObjectType)
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __cleanup(element) {
|
||||
// INVARIANT: element has been removed from JSArray. Destroy its
|
||||
// item, or re-parent it back to the parent it had before it was pushed:
|
||||
var item = element.item
|
||||
if (element.destroyOnPop) {
|
||||
item.destroy()
|
||||
} else {
|
||||
// Mark the item as no longer part of the StackView. It
|
||||
// might reenter on pop if pushed several times:
|
||||
item.visible = false
|
||||
__setStatus(item, Stack.Inactive)
|
||||
item.Stack.__view = null
|
||||
item.Stack.__index = -1
|
||||
if (element.originalParent)
|
||||
item.parent = element.originalParent
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __setStatus(item, status) {
|
||||
item.Stack.__status = status
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __performTransition(transition)
|
||||
{
|
||||
// Animate item in "outElement" out, and item in "inElement" in. Set a guard to protect
|
||||
// the user from pushing new items on signals that will fire while preparing for the transition
|
||||
// (e.g Stack.onCompleted, Stack.onStatusChanged, Stack.onIndexChanged etc). Otherwise, we will enter
|
||||
// this function several times, which causes the items to be updated half-way.
|
||||
if (__currentTransition)
|
||||
__currentTransition.animation.complete()
|
||||
__loadElement(transition.inElement)
|
||||
|
||||
transition.name = transition.replace ? "replaceTransition" : (transition.push ? "pushTransition" : "popTransition")
|
||||
var enterItem = transition.inElement.item
|
||||
transition.enterItem = enterItem
|
||||
|
||||
// Since an item can be pushed several times, we need to update its properties:
|
||||
enterItem.parent = root
|
||||
enterItem.Stack.__view = root
|
||||
enterItem.Stack.__index = transition.inElement.index
|
||||
__currentItem = enterItem
|
||||
|
||||
if (!transition.outElement) {
|
||||
// A transition consists of two items, but we got just one. So just show the item:
|
||||
enterItem.visible = true
|
||||
__setStatus(enterItem, Stack.Activating)
|
||||
__setStatus(enterItem, Stack.Active)
|
||||
return
|
||||
}
|
||||
|
||||
var exitItem = transition.outElement.item
|
||||
transition.exitItem = exitItem
|
||||
if (enterItem === exitItem)
|
||||
return
|
||||
|
||||
if (root.delegate) {
|
||||
transition.properties = {
|
||||
"name":transition.name,
|
||||
"enterItem":transition.enterItem,
|
||||
"exitItem":transition.exitItem,
|
||||
"immediate":transition.immediate }
|
||||
var anim = root.delegate.getTransition(transition.properties)
|
||||
if (anim.createObject) {
|
||||
anim = anim.createObject(null, transition.properties)
|
||||
anim.runningChanged.connect(function(){ if (anim.running === false) anim.destroy() })
|
||||
}
|
||||
transition.animation = anim
|
||||
}
|
||||
|
||||
if (!transition.animation) {
|
||||
console.warn("Warning: StackView: no", transition.name, "found!")
|
||||
return
|
||||
}
|
||||
if (enterItem.anchors.fill || exitItem.anchors.fill)
|
||||
console.warn("Warning: StackView: cannot transition an item that is anchored!")
|
||||
|
||||
__currentTransition = transition
|
||||
__setStatus(exitItem, Stack.Deactivating)
|
||||
enterItem.visible = true
|
||||
__setStatus(enterItem, Stack.Activating)
|
||||
transition.animation.runningChanged.connect(animationFinished)
|
||||
transition.animation.start()
|
||||
// NB! For empty animations, "animationFinished" is already
|
||||
// executed at this point, leaving __animation === null:
|
||||
if (transition.immediate === true && transition.animation)
|
||||
transition.animation.complete()
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function animationFinished()
|
||||
{
|
||||
if (!__currentTransition || __currentTransition.animation.running)
|
||||
return
|
||||
|
||||
__currentTransition.animation.runningChanged.disconnect(animationFinished)
|
||||
__currentTransition.exitItem.visible = false
|
||||
__setStatus(__currentTransition.exitItem, Stack.Inactive);
|
||||
__setStatus(__currentTransition.enterItem, Stack.Active);
|
||||
__currentTransition.properties.animation = __currentTransition.animation
|
||||
root.delegate.transitionFinished(__currentTransition.properties)
|
||||
|
||||
if (!__currentTransition.push || __currentTransition.replace)
|
||||
__cleanup(__currentTransition.outElement)
|
||||
|
||||
__currentTransition = null
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component invalidItemReplacement: Component {
|
||||
Text {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
/*!
|
||||
\qmltype StackViewDelegate
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\ingroup controls
|
||||
\since 5.1
|
||||
|
||||
\brief A delegate used by StackView for loading transitions.
|
||||
|
||||
See the documentation for the \l {StackView} component.
|
||||
|
||||
*/
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
/*!
|
||||
\qmlmethod Transition StackViewDelegate::getTransition(properties)
|
||||
|
||||
The base implementation of this function just looks for a property named
|
||||
\a {properties}.name inside itself and returns it.
|
||||
\sa {Transitions}
|
||||
*/
|
||||
function getTransition(properties)
|
||||
{
|
||||
return root[properties.name]
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod void StackViewDelegate::transitionFinished(properties)
|
||||
|
||||
Handles the completion of a transition for \a properties. The base
|
||||
implementation of this function is empty.
|
||||
|
||||
\sa {Transitions}
|
||||
*/
|
||||
function transitionFinished(properties)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty Component StackViewDelegate::pushTransition
|
||||
|
||||
The transition used on push operation.
|
||||
*/
|
||||
property Component pushTransition: StackViewTransition {}
|
||||
/*!
|
||||
\qmlproperty Component StackViewDelegate::popTransition
|
||||
|
||||
The transition used on pop operation.
|
||||
Unless set, the popTransition is the same as pushTransition
|
||||
*/
|
||||
property Component popTransition: root["pushTransition"]
|
||||
/*!
|
||||
\qmlproperty Component StackViewDelegate::replaceTransition
|
||||
|
||||
The transition used on replace operation.
|
||||
Unless set, the replaceTransition is the same as pushTransition
|
||||
*/
|
||||
property Component replaceTransition: root["pushTransition"]
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
ParallelAnimation {
|
||||
id: root
|
||||
/*! The name of the animation that is running. Can be one of the following:
|
||||
\list
|
||||
\li 'PushTransition'
|
||||
\li 'PopTransition'
|
||||
\li 'ReplaceTransition'
|
||||
\endlist
|
||||
*/
|
||||
property string name
|
||||
/*! The page that is transitioning in. */
|
||||
property Item enterItem
|
||||
/*! The page that is transitioning out */
|
||||
property Item exitItem
|
||||
/*! Set to \c true if the transition is told to
|
||||
fast-forward directly to its end-state */
|
||||
property bool immediate
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype StatusBar
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup applicationwindow
|
||||
\ingroup controls
|
||||
\brief Contains status information in your app.
|
||||
|
||||
The common way of using StatusBar is in relation to \l ApplicationWindow.
|
||||
|
||||
Note that the StatusBar does not provide a layout of its own, but requires
|
||||
you to position its contents, for instance by creating a \l RowLayout.
|
||||
|
||||
If only a single item is used within the StatusBar, it will resize to fit the implicitHeight
|
||||
of its contained item. This makes it particularly suitable for use together with layouts.
|
||||
Otherwise the height is platform dependent.
|
||||
|
||||
\code
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Layouts 1.0
|
||||
|
||||
ApplicationWindow {
|
||||
statusBar: StatusBar {
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
Label { text: "Read Only" }
|
||||
}
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
||||
FocusScope {
|
||||
id: statusbar
|
||||
|
||||
activeFocusOnTab: false
|
||||
Accessible.role: Accessible.StatusBar
|
||||
|
||||
width: parent ? parent.width : implicitWidth
|
||||
implicitWidth: container.leftMargin + container.rightMargin
|
||||
+ Math.max(container.layoutWidth, __panel ? __panel.implicitWidth : 0)
|
||||
implicitHeight: container.topMargin + container.bottomMargin
|
||||
+ Math.max(container.layoutHeight, __panel ? __panel.implicitHeight : 0)
|
||||
|
||||
/*! \qmlproperty Component StatusBar::style
|
||||
|
||||
The style Component for this control.
|
||||
\sa {StatusBarStyle}
|
||||
|
||||
*/
|
||||
property Component style: Settings.styleComponent(Settings.style, "StatusBarStyle.qml", statusbar)
|
||||
|
||||
/*! \internal */
|
||||
property alias __style: styleLoader.item
|
||||
|
||||
/*! \internal */
|
||||
property Item __panel: panelLoader.item
|
||||
|
||||
/*! \internal */
|
||||
default property alias __content: container.data
|
||||
|
||||
/*!
|
||||
\qmlproperty Item StatusBar::contentItem
|
||||
|
||||
This property holds the content Item of the status bar.
|
||||
|
||||
Items declared as children of a StatusBar are automatically parented to the StatusBar's contentItem.
|
||||
Items created dynamically need to be explicitly parented to the contentItem:
|
||||
|
||||
\note The implicit size of the StatusBar is calculated based on the size of its content. If you want to anchor
|
||||
items inside the status bar, you must specify an explicit width and height on the StatusBar itself.
|
||||
*/
|
||||
readonly property alias contentItem: container
|
||||
|
||||
data: [
|
||||
Loader {
|
||||
id: panelLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: styleLoader.item ? styleLoader.item.panel : null
|
||||
onLoaded: item.z = -1
|
||||
Loader {
|
||||
id: styleLoader
|
||||
property alias __control: statusbar
|
||||
sourceComponent: style
|
||||
}
|
||||
},
|
||||
Item {
|
||||
id: container
|
||||
z: 1
|
||||
focus: true
|
||||
anchors.fill: parent
|
||||
|
||||
anchors.topMargin: topMargin
|
||||
anchors.leftMargin: leftMargin
|
||||
anchors.rightMargin: rightMargin
|
||||
anchors.bottomMargin: bottomMargin
|
||||
|
||||
property int topMargin: __style ? __style.padding.top : 0
|
||||
property int bottomMargin: __style ? __style.padding.bottom : 0
|
||||
property int leftMargin: __style ? __style.padding.left : 0
|
||||
property int rightMargin: __style ? __style.padding.right : 0
|
||||
|
||||
property Item layoutItem: container.children.length === 1 ? container.children[0] : null
|
||||
property real layoutWidth: layoutItem ? (layoutItem.implicitWidth || layoutItem.width) +
|
||||
(layoutItem.anchors.fill ? layoutItem.anchors.leftMargin +
|
||||
layoutItem.anchors.rightMargin : 0) : 0
|
||||
property real layoutHeight: layoutItem ? (layoutItem.implicitHeight || layoutItem.height) +
|
||||
(layoutItem.anchors.fill ? layoutItem.anchors.topMargin +
|
||||
layoutItem.anchors.bottomMargin : 0) : 0
|
||||
}]
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype ApplicationWindowStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.4
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for ApplicationWindow.
|
||||
|
||||
You can create a custom window background by replacing the "background"
|
||||
delegate of ApplicationWindowStyle with a custom design.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
ApplicationWindow {
|
||||
style: ApplicationWindowStyle {
|
||||
background: BorderImage {
|
||||
source: "background.png"
|
||||
border { left: 20; top: 20; right: 20; bottom: 20 }
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
QtObject {
|
||||
/*! The window attached to this style. */
|
||||
readonly property ApplicationWindow control: __control
|
||||
|
||||
/*! A custom background for the window.
|
||||
|
||||
\note The window might have a custom background color set. The custom
|
||||
background color is automatically filled by the window. The background
|
||||
delegate should respect the custom background color by either hiding
|
||||
itself altogether when a custom background color is set, or by letting
|
||||
the custom background color shine through.
|
||||
|
||||
The following read-only property is available within the scope
|
||||
of the background delegate:
|
||||
\table
|
||||
\row \li \b {styleData.hasColor} : bool \li Whether the window has a custom background color set.
|
||||
\endtable
|
||||
*/
|
||||
property Component background: Rectangle {
|
||||
visible: !styleData.hasColor
|
||||
color: SystemPaletteSingleton.window(true)
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
readonly property alias contentArea: contentArea
|
||||
readonly property alias menuBarArea: menuBarArea
|
||||
readonly property alias toolBarArea: toolBarArea
|
||||
readonly property alias statusBarArea: statusBarArea
|
||||
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
sourceComponent: background
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentArea
|
||||
anchors.top: toolBarArea.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: statusBarArea.top
|
||||
}
|
||||
|
||||
Item {
|
||||
id: toolBarArea
|
||||
anchors.top: parent.menuBarArea.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
implicitHeight: childrenRect.height
|
||||
height: visibleChildren.length > 0 ? implicitHeight: 0
|
||||
}
|
||||
|
||||
Item {
|
||||
id: menuBarArea
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
implicitHeight: childrenRect.height
|
||||
height: visibleChildren.length > 0 ? implicitHeight: 0
|
||||
}
|
||||
|
||||
Item {
|
||||
id: statusBarArea
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
implicitHeight: childrenRect.height
|
||||
height: visibleChildren.length > 0 ? implicitHeight: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype BasicTableViewStyle
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\inherits ScrollViewStyle
|
||||
\qmlabstract
|
||||
*/
|
||||
|
||||
ScrollViewStyle {
|
||||
id: root
|
||||
|
||||
/*! \qmlproperty BasicTableView BasicTableViewStyle::control
|
||||
\internal */
|
||||
readonly property BasicTableView control: __control
|
||||
|
||||
/*! \qmlproperty color BasicTableViewStyle::textColor
|
||||
The text color. */
|
||||
property color textColor: SystemPaletteSingleton.text(control.enabled)
|
||||
|
||||
/*! \qmlproperty color BasicTableViewStyle::backgroundColor
|
||||
The background color. */
|
||||
property color backgroundColor: control.backgroundVisible ? SystemPaletteSingleton.base(control.enabled) : "transparent"
|
||||
|
||||
/*! \qmlproperty color BasicTableViewStyle::alternateBackgroundColor
|
||||
The alternate background color. */
|
||||
property color alternateBackgroundColor: "#f5f5f5"
|
||||
|
||||
/*! \qmlproperty color BasicTableViewStyle::highlightedTextColor
|
||||
The text highlight color, used within selections. */
|
||||
property color highlightedTextColor: "white"
|
||||
|
||||
/*! \qmlproperty bool BasicTableViewStyle::activateItemOnSingleClick
|
||||
Activates items on single click.
|
||||
|
||||
Its default value is \c false.
|
||||
*/
|
||||
property bool activateItemOnSingleClick: false
|
||||
|
||||
padding.top: control.headerVisible ? 0 : 1
|
||||
|
||||
/*! \qmlproperty Component BasicTableViewStyle::headerDelegate
|
||||
\internal
|
||||
|
||||
Different documentation for TableViewStyle and TreeViewStyle.
|
||||
See qtquickcontrolsstyles-tableviewstyle.qdoc and qtquickcontrolsstyles-treeviewstyle.qdoc
|
||||
*/
|
||||
property Component headerDelegate: BorderImage {
|
||||
height: Math.round(textItem.implicitHeight * 1.2)
|
||||
source: "images/header.png"
|
||||
border.left: 4
|
||||
border.bottom: 2
|
||||
border.top: 2
|
||||
Text {
|
||||
id: textItem
|
||||
anchors.fill: parent
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: styleData.textAlignment
|
||||
anchors.leftMargin: horizontalAlignment === Text.AlignLeft ? 12 : 1
|
||||
anchors.rightMargin: horizontalAlignment === Text.AlignRight ? 8 : 1
|
||||
text: styleData.value
|
||||
elide: Text.ElideRight
|
||||
color: textColor
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
}
|
||||
Rectangle {
|
||||
width: 1
|
||||
height: parent.height - 2
|
||||
y: 1
|
||||
color: "#ccc"
|
||||
}
|
||||
}
|
||||
|
||||
/*! \qmlproperty Component BasicTableViewStyle::rowDelegate
|
||||
\internal
|
||||
|
||||
Different documentation for TableViewStyle and TreeViewStyle.
|
||||
See qtquickcontrolsstyles-tableviewstyle.qdoc and qtquickcontrolsstyles-treeviewstyle.qdoc
|
||||
*/
|
||||
property Component rowDelegate: Rectangle {
|
||||
height: Math.round(TextSingleton.implicitHeight * 1.2)
|
||||
property color selectedColor: control.activeFocus ? "#07c" : "#999"
|
||||
color: styleData.selected ? selectedColor :
|
||||
!styleData.alternate ? alternateBackgroundColor : backgroundColor
|
||||
}
|
||||
|
||||
/*! \qmlproperty Component BasicTableViewStyle::itemDelegate
|
||||
\internal
|
||||
|
||||
Different documentation for TableViewStyle and TreeViewStyle.
|
||||
See qtquickcontrolsstyles-tableviewstyle.qdoc and qtquickcontrolsstyles-treeviewstyle.qdoc
|
||||
*/
|
||||
property Component itemDelegate: Item {
|
||||
height: Math.max(16, label.implicitHeight)
|
||||
property int implicitWidth: label.implicitWidth + 20
|
||||
|
||||
Text {
|
||||
id: label
|
||||
objectName: "label"
|
||||
width: parent.width - x - (horizontalAlignment === Text.AlignRight ? 8 : 1)
|
||||
x: (styleData.hasOwnProperty("depth") && styleData.column === 0) ? 0 :
|
||||
horizontalAlignment === Text.AlignRight ? 1 : 8
|
||||
horizontalAlignment: styleData.textAlignment
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: 1
|
||||
elide: styleData.elideMode
|
||||
text: styleData.value !== undefined ? styleData.value.toString() : ""
|
||||
color: styleData.textColor
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
Part of TreeViewStyle
|
||||
*/
|
||||
property Component __branchDelegate: null
|
||||
|
||||
/*! \internal
|
||||
Part of TreeViewStyle
|
||||
*/
|
||||
property int __indentation: 12
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype BusyIndicatorStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.2
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for BusyIndicatorStyle.
|
||||
|
||||
You can create a busy indicator by replacing the "indicator" delegate
|
||||
of the BusyIndicatorStyle with a custom design.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
BusyIndicator {
|
||||
style: BusyIndicatorStyle {
|
||||
indicator: Image {
|
||||
visible: control.running
|
||||
source: "spinner.png"
|
||||
RotationAnimator on rotation {
|
||||
running: control.running
|
||||
loops: Animation.Infinite
|
||||
duration: 2000
|
||||
from: 0 ; to: 360
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
Style {
|
||||
id: indicatorstyle
|
||||
|
||||
/*! The \l BusyIndicator this style is attached to. */
|
||||
readonly property BusyIndicator control: __control
|
||||
|
||||
/*! This defines the appearance of the busy indicator. */
|
||||
property Component indicator: Item {
|
||||
id: indicatorItem
|
||||
|
||||
implicitWidth: 48
|
||||
implicitHeight: 48
|
||||
|
||||
opacity: control.running ? 1 : 0
|
||||
Behavior on opacity { OpacityAnimator { duration: 250 } }
|
||||
|
||||
Image {
|
||||
anchors.centerIn: parent
|
||||
anchors.alignWhenCentered: true
|
||||
width: Math.min(parent.width, parent.height)
|
||||
height: width
|
||||
source: width <= 32 ? "images/spinner_small.png" :
|
||||
width >= 48 ? "images/spinner_large.png" :
|
||||
"images/spinner_medium.png"
|
||||
RotationAnimator on rotation {
|
||||
duration: 800
|
||||
loops: Animation.Infinite
|
||||
from: 0
|
||||
to: 360
|
||||
running: indicatorItem.visible && (control.running || indicatorItem.opacity > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
anchors.fill: parent
|
||||
implicitWidth: indicatorLoader.implicitWidth
|
||||
implicitHeight: indicatorLoader.implicitHeight
|
||||
|
||||
Loader {
|
||||
id: indicatorLoader
|
||||
sourceComponent: indicator
|
||||
anchors.centerIn: parent
|
||||
width: Math.min(parent.width, parent.height)
|
||||
height: width
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype ButtonStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.1
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for Button.
|
||||
|
||||
You can create a custom button by replacing the "background" delegate
|
||||
of the ButtonStyle with a custom design.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
Button {
|
||||
text: "A button"
|
||||
style: ButtonStyle {
|
||||
background: Rectangle {
|
||||
implicitWidth: 100
|
||||
implicitHeight: 25
|
||||
border.width: control.activeFocus ? 2 : 1
|
||||
border.color: "#888"
|
||||
radius: 4
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0 ; color: control.pressed ? "#ccc" : "#eee" }
|
||||
GradientStop { position: 1 ; color: control.pressed ? "#aaa" : "#ccc" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
If you need a custom label, you can replace the label item.
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: buttonstyle
|
||||
|
||||
/*! The \l {QtQuick.Controls::}{Button} this style is attached to. */
|
||||
readonly property Button control: __control
|
||||
|
||||
/*! The padding between the background and the label components. */
|
||||
padding {
|
||||
top: 4
|
||||
left: 4
|
||||
right: 4 + (control.menu !== null ? Math.round(TextSingleton.implicitHeight * 0.5) : 0)
|
||||
bottom: 4
|
||||
}
|
||||
|
||||
/*! This defines the background of the button. */
|
||||
property Component background: Item {
|
||||
property bool down: control.pressed || (control.checkable && control.checked)
|
||||
implicitWidth: Math.round(TextSingleton.implicitHeight * 4.5)
|
||||
implicitHeight: Math.max(25, Math.round(TextSingleton.implicitHeight * 1.2))
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: down ? 0 : -1
|
||||
color: "#10000000"
|
||||
radius: baserect.radius
|
||||
}
|
||||
Rectangle {
|
||||
id: baserect
|
||||
gradient: Gradient {
|
||||
GradientStop {color: down ? "#aaa" : "#fefefe" ; position: 0}
|
||||
GradientStop {color: down ? "#ccc" : "#e3e3e3" ; position: down ? 0.1: 1}
|
||||
}
|
||||
radius: TextSingleton.implicitHeight * 0.16
|
||||
anchors.fill: parent
|
||||
border.color: control.activeFocus ? "#47b" : "#999"
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: parent.radius
|
||||
color: control.activeFocus ? "#47b" : "white"
|
||||
opacity: control.hovered || control.activeFocus ? 0.1 : 0
|
||||
Behavior on opacity {NumberAnimation{ duration: 100 }}
|
||||
}
|
||||
}
|
||||
Image {
|
||||
id: imageItem
|
||||
visible: control.menu !== null
|
||||
source: "images/arrow-down.png"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 4
|
||||
opacity: control.enabled ? 0.6 : 0.5
|
||||
}
|
||||
}
|
||||
|
||||
/*! This defines the label of the button. */
|
||||
property Component label: Item {
|
||||
implicitWidth: row.implicitWidth
|
||||
implicitHeight: row.implicitHeight
|
||||
baselineOffset: row.y + text.y + text.baselineOffset
|
||||
Row {
|
||||
id: row
|
||||
anchors.centerIn: parent
|
||||
spacing: 2
|
||||
Image {
|
||||
source: control.iconSource
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
Text {
|
||||
id: text
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: StyleHelpers.stylizeMnemonics(control.text)
|
||||
color: SystemPaletteSingleton.buttonText(control.enabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
anchors.fill: parent
|
||||
implicitWidth: Math.max(labelLoader.implicitWidth + padding.left + padding.right, backgroundLoader.implicitWidth)
|
||||
implicitHeight: Math.max(labelLoader.implicitHeight + padding.top + padding.bottom, backgroundLoader.implicitHeight)
|
||||
baselineOffset: labelLoader.item ? padding.top + labelLoader.item.baselineOffset : 0
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: background
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: labelLoader
|
||||
sourceComponent: label
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: padding.left
|
||||
anchors.topMargin: padding.top
|
||||
anchors.rightMargin: padding.right
|
||||
anchors.bottomMargin: padding.bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,703 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype CalendarStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.3
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for \l Calendar.
|
||||
|
||||
\section2 Component Map
|
||||
|
||||
\image calendarstyle-components-week-numbers.png
|
||||
|
||||
The calendar has the following styleable components:
|
||||
|
||||
\table
|
||||
\row \li \image square-white.png
|
||||
\li \l background
|
||||
\li Fills the entire control.
|
||||
\row \li \image square-yellow.png
|
||||
\li \l navigationBar
|
||||
\li
|
||||
\row \li \image square-green.png
|
||||
\li \l dayOfWeekDelegate
|
||||
\li One instance per day of week.
|
||||
\row \li \image square-red.png
|
||||
\li \l weekNumberDelegate
|
||||
\li One instance per week.
|
||||
\row \li \image square-blue.png
|
||||
\li \l dayDelegate
|
||||
\li One instance per day of month.
|
||||
\endtable
|
||||
|
||||
\section2 Custom Style Example
|
||||
\qml
|
||||
Calendar {
|
||||
anchors.centerIn: parent
|
||||
|
||||
style: CalendarStyle {
|
||||
gridVisible: false
|
||||
dayDelegate: Rectangle {
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0.00
|
||||
color: styleData.selected ? "#111" : (styleData.visibleMonth && styleData.valid ? "#444" : "#666");
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.00
|
||||
color: styleData.selected ? "#444" : (styleData.visibleMonth && styleData.valid ? "#111" : "#666");
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.00
|
||||
color: styleData.selected ? "#777" : (styleData.visibleMonth && styleData.valid ? "#111" : "#666");
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: styleData.date.getDate()
|
||||
anchors.centerIn: parent
|
||||
color: styleData.valid ? "white" : "grey"
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: "#555"
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 1
|
||||
height: parent.height
|
||||
color: "#555"
|
||||
anchors.right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: calendarStyle
|
||||
|
||||
/*!
|
||||
The Calendar this style is attached to.
|
||||
*/
|
||||
readonly property Calendar control: __control
|
||||
|
||||
/*!
|
||||
The color of the grid lines.
|
||||
*/
|
||||
property color gridColor: "#d3d3d3"
|
||||
|
||||
/*!
|
||||
This property determines the visibility of the grid.
|
||||
|
||||
The default value is \c true.
|
||||
*/
|
||||
property bool gridVisible: true
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
The width of each grid line.
|
||||
*/
|
||||
property real __gridLineWidth: 1
|
||||
|
||||
/*! \internal */
|
||||
property color __horizontalSeparatorColor: gridColor
|
||||
|
||||
/*! \internal */
|
||||
property color __verticalSeparatorColor: gridColor
|
||||
|
||||
function __cellRectAt(index) {
|
||||
return CalendarUtils.cellRectAt(index, control.__panel.columns, control.__panel.rows,
|
||||
control.__panel.availableWidth, control.__panel.availableHeight, gridVisible ? __gridLineWidth : 0);
|
||||
}
|
||||
|
||||
function __isValidDate(date) {
|
||||
return date !== undefined
|
||||
&& date.getTime() >= control.minimumDate.getTime()
|
||||
&& date.getTime() <= control.maximumDate.getTime();
|
||||
}
|
||||
|
||||
/*!
|
||||
The background of the calendar.
|
||||
|
||||
The implicit size of the calendar is calculated based on the implicit size of the background delegate.
|
||||
*/
|
||||
property Component background: Rectangle {
|
||||
color: "#fff"
|
||||
implicitWidth: Math.max(250, Math.round(TextSingleton.implicitHeight * 14))
|
||||
implicitHeight: Math.max(250, Math.round(TextSingleton.implicitHeight * 14))
|
||||
}
|
||||
|
||||
/*!
|
||||
The navigation bar of the calendar.
|
||||
|
||||
Styles the bar at the top of the calendar that contains the
|
||||
next month/previous month buttons and the selected date label.
|
||||
|
||||
The properties provided to the delegate are:
|
||||
\table
|
||||
\row \li readonly property string \b styleData.title
|
||||
\li The title of the calendar.
|
||||
\endtable
|
||||
*/
|
||||
property Component navigationBar: Rectangle {
|
||||
height: Math.round(TextSingleton.implicitHeight * 2.73)
|
||||
color: "#f9f9f9"
|
||||
|
||||
Rectangle {
|
||||
color: Qt.rgba(1,1,1,0.6)
|
||||
height: 1
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.bottom: parent.bottom
|
||||
height: 1
|
||||
width: parent.width
|
||||
color: "#ddd"
|
||||
}
|
||||
HoverButton {
|
||||
id: previousMonth
|
||||
width: parent.height
|
||||
height: width
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
source: "images/leftanglearrow.png"
|
||||
onClicked: control.showPreviousMonth()
|
||||
}
|
||||
Label {
|
||||
id: dateText
|
||||
text: styleData.title
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: TextSingleton.implicitHeight * 1.25
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: previousMonth.right
|
||||
anchors.leftMargin: 2
|
||||
anchors.right: nextMonth.left
|
||||
anchors.rightMargin: 2
|
||||
}
|
||||
HoverButton {
|
||||
id: nextMonth
|
||||
width: parent.height
|
||||
height: width
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
source: "images/rightanglearrow.png"
|
||||
onClicked: control.showNextMonth()
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The delegate that styles each date in the calendar.
|
||||
|
||||
The properties provided to each delegate are:
|
||||
\table
|
||||
\row \li readonly property date \b styleData.date
|
||||
\li The date this delegate represents.
|
||||
\row \li readonly property bool \b styleData.selected
|
||||
\li \c true if this is the selected date.
|
||||
\row \li readonly property int \b styleData.index
|
||||
\li The index of this delegate.
|
||||
\row \li readonly property bool \b styleData.valid
|
||||
\li \c true if this date is greater than or equal to than \l {Calendar::minimumDate}{minimumDate} and
|
||||
less than or equal to \l {Calendar::maximumDate}{maximumDate}.
|
||||
\row \li readonly property bool \b styleData.today
|
||||
\li \c true if this date is equal to today's date.
|
||||
\row \li readonly property bool \b styleData.visibleMonth
|
||||
\li \c true if the month in this date is the visible month.
|
||||
\row \li readonly property bool \b styleData.hovered
|
||||
\li \c true if the mouse is over this cell.
|
||||
\note This property is \c true even when the mouse is hovered over an invalid date.
|
||||
\row \li readonly property bool \b styleData.pressed
|
||||
\li \c true if the mouse is pressed on this cell.
|
||||
\note This property is \c true even when the mouse is pressed on an invalid date.
|
||||
\endtable
|
||||
*/
|
||||
property Component dayDelegate: Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: (!addExtraMargin || control.weekNumbersVisible) && styleData.index % CalendarUtils.daysInAWeek === 0 ? 0 : -1
|
||||
anchors.rightMargin: !addExtraMargin && styleData.index % CalendarUtils.daysInAWeek === CalendarUtils.daysInAWeek - 1 ? 0 : -1
|
||||
anchors.bottomMargin: !addExtraMargin && styleData.index >= CalendarUtils.daysInAWeek * (CalendarUtils.weeksOnACalendarMonth - 1) ? 0 : -1
|
||||
anchors.topMargin: styleData.selected ? -1 : 0
|
||||
color: styleData.date !== undefined && styleData.selected ? selectedDateColor : "transparent"
|
||||
|
||||
readonly property bool addExtraMargin: control.frameVisible && styleData.selected
|
||||
readonly property color sameMonthDateTextColor: "#444"
|
||||
readonly property color selectedDateColor: Qt.platform.os === "osx" ? "#3778d0" : SystemPaletteSingleton.highlight(control.enabled)
|
||||
readonly property color selectedDateTextColor: "white"
|
||||
readonly property color differentMonthDateTextColor: "#bbb"
|
||||
readonly property color invalidDateColor: "#dddddd"
|
||||
Label {
|
||||
id: dayDelegateText
|
||||
text: styleData.date.getDate()
|
||||
anchors.centerIn: parent
|
||||
horizontalAlignment: Text.AlignRight
|
||||
font.pixelSize: Math.min(parent.height/3, parent.width/3)
|
||||
color: {
|
||||
var theColor = invalidDateColor;
|
||||
if (styleData.valid) {
|
||||
// Date is within the valid range.
|
||||
theColor = styleData.visibleMonth ? sameMonthDateTextColor : differentMonthDateTextColor;
|
||||
if (styleData.selected)
|
||||
theColor = selectedDateTextColor;
|
||||
}
|
||||
theColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The delegate that styles each weekday.
|
||||
|
||||
The height of the weekday row is calculated based on the maximum implicit height of the delegates.
|
||||
|
||||
The properties provided to each delegate are:
|
||||
\table
|
||||
\row \li readonly property int \b styleData.index
|
||||
\li The index (0-6) of the delegate.
|
||||
\row \li readonly property int \b styleData.dayOfWeek
|
||||
\li The day of the week this delegate represents. Possible values:
|
||||
\list
|
||||
\li \c Locale.Sunday
|
||||
\li \c Locale.Monday
|
||||
\li \c Locale.Tuesday
|
||||
\li \c Locale.Wednesday
|
||||
\li \c Locale.Thursday
|
||||
\li \c Locale.Friday
|
||||
\li \c Locale.Saturday
|
||||
\endlist
|
||||
\endtable
|
||||
*/
|
||||
property Component dayOfWeekDelegate: Rectangle {
|
||||
color: gridVisible ? "#fcfcfc" : "transparent"
|
||||
implicitHeight: Math.round(TextSingleton.implicitHeight * 2.25)
|
||||
Label {
|
||||
text: control.locale.dayName(styleData.dayOfWeek, control.dayOfWeekFormat)
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The delegate that styles each week number.
|
||||
|
||||
The width of the week number column is calculated based on the maximum implicit width of the delegates.
|
||||
|
||||
The properties provided to each delegate are:
|
||||
\table
|
||||
\row \li readonly property int \b styleData.index
|
||||
\li The index (0-5) of the delegate.
|
||||
\row \li readonly property int \b styleData.weekNumber
|
||||
\li The number of the week this delegate represents.
|
||||
\endtable
|
||||
*/
|
||||
property Component weekNumberDelegate: Rectangle {
|
||||
implicitWidth: Math.round(TextSingleton.implicitHeight * 2)
|
||||
Label {
|
||||
text: styleData.weekNumber
|
||||
anchors.centerIn: parent
|
||||
color: "#444"
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
id: panelItem
|
||||
|
||||
implicitWidth: backgroundLoader.implicitWidth
|
||||
implicitHeight: backgroundLoader.implicitHeight
|
||||
|
||||
property alias navigationBarItem: navigationBarLoader.item
|
||||
|
||||
property alias dayOfWeekHeaderRow: dayOfWeekHeaderRow
|
||||
|
||||
readonly property int weeksToShow: 6
|
||||
readonly property int rows: weeksToShow
|
||||
readonly property int columns: CalendarUtils.daysInAWeek
|
||||
|
||||
// The combined available width and height to be shared amongst each cell.
|
||||
readonly property real availableWidth: viewContainer.width
|
||||
readonly property real availableHeight: viewContainer.height
|
||||
|
||||
property int hoveredCellIndex: -1
|
||||
property int pressedCellIndex: -1
|
||||
property int pressCellIndex: -1
|
||||
property var pressDate: null
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
border.color: gridColor
|
||||
visible: control.frameVisible
|
||||
}
|
||||
|
||||
Item {
|
||||
id: container
|
||||
anchors.fill: parent
|
||||
anchors.margins: control.frameVisible ? 1 : 0
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: background
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: navigationBarLoader
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
sourceComponent: navigationBar
|
||||
active: control.navigationBarVisible
|
||||
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property string title: control.locale.standaloneMonthName(control.visibleMonth)
|
||||
+ new Date(control.visibleYear, control.visibleMonth, 1).toLocaleDateString(control.locale, " yyyy")
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: dayOfWeekHeaderRow
|
||||
anchors.top: navigationBarLoader.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: (control.weekNumbersVisible ? weekNumbersItem.width : 0)
|
||||
anchors.right: parent.right
|
||||
spacing: gridVisible ? __gridLineWidth : 0
|
||||
property alias __repeater: repeater
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: CalendarHeaderModel {
|
||||
locale: control.locale
|
||||
}
|
||||
Loader {
|
||||
id: dayOfWeekDelegateLoader
|
||||
sourceComponent: dayOfWeekDelegate
|
||||
width: __cellRectAt(index).width
|
||||
|
||||
readonly property int __index: index
|
||||
readonly property var __dayOfWeek: dayOfWeek
|
||||
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias index: dayOfWeekDelegateLoader.__index
|
||||
readonly property alias dayOfWeek: dayOfWeekDelegateLoader.__dayOfWeek
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: topGridLine
|
||||
color: __horizontalSeparatorColor
|
||||
width: parent.width
|
||||
height: __gridLineWidth
|
||||
visible: gridVisible
|
||||
anchors.top: dayOfWeekHeaderRow.bottom
|
||||
}
|
||||
|
||||
Row {
|
||||
id: gridRow
|
||||
width: weekNumbersItem.width + viewContainer.width
|
||||
height: viewContainer.height
|
||||
anchors.top: topGridLine.bottom
|
||||
|
||||
Column {
|
||||
id: weekNumbersItem
|
||||
visible: control.weekNumbersVisible
|
||||
height: viewContainer.height
|
||||
spacing: gridVisible ? __gridLineWidth : 0
|
||||
Repeater {
|
||||
id: weekNumberRepeater
|
||||
model: panelItem.weeksToShow
|
||||
|
||||
Loader {
|
||||
id: weekNumberDelegateLoader
|
||||
height: __cellRectAt(index * panelItem.columns).height
|
||||
sourceComponent: weekNumberDelegate
|
||||
|
||||
readonly property int __index: index
|
||||
property int __weekNumber: control.__model.weekNumberAt(index)
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
|
||||
function onVisibleMonthChanged() {
|
||||
__weekNumber = control.__model.weekNumberAt(index)
|
||||
}
|
||||
|
||||
function onVisibleYearChanged() {
|
||||
__weekNumber = control.__model.weekNumberAt(index)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: control.__model
|
||||
function onCountChanged() {
|
||||
__weekNumber = control.__model.weekNumberAt(index)
|
||||
}
|
||||
}
|
||||
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias index: weekNumberDelegateLoader.__index
|
||||
readonly property int weekNumber: weekNumberDelegateLoader.__weekNumber
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: separator
|
||||
anchors.topMargin: - dayOfWeekHeaderRow.height - 1
|
||||
anchors.top: weekNumbersItem.top
|
||||
anchors.bottom: weekNumbersItem.bottom
|
||||
|
||||
width: __gridLineWidth
|
||||
color: __verticalSeparatorColor
|
||||
visible: control.weekNumbersVisible
|
||||
}
|
||||
|
||||
// Contains the grid lines and the grid itself.
|
||||
Item {
|
||||
id: viewContainer
|
||||
width: container.width - (control.weekNumbersVisible ? weekNumbersItem.width + separator.width : 0)
|
||||
height: container.height - navigationBarLoader.height - dayOfWeekHeaderRow.height - topGridLine.height
|
||||
|
||||
Repeater {
|
||||
id: verticalGridLineRepeater
|
||||
model: panelItem.columns - 1
|
||||
delegate: Rectangle {
|
||||
x: __cellRectAt(index + 1).x - __gridLineWidth
|
||||
y: 0
|
||||
width: __gridLineWidth
|
||||
height: viewContainer.height
|
||||
color: gridColor
|
||||
visible: gridVisible
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: horizontalGridLineRepeater
|
||||
model: panelItem.rows - 1
|
||||
delegate: Rectangle {
|
||||
x: 0
|
||||
y: __cellRectAt((index + 1) * panelItem.columns).y - __gridLineWidth
|
||||
width: viewContainer.width
|
||||
height: __gridLineWidth
|
||||
color: gridColor
|
||||
visible: gridVisible
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
|
||||
function cellIndexAt(mouseX, mouseY) {
|
||||
var viewContainerPos = viewContainer.mapFromItem(mouseArea, mouseX, mouseY);
|
||||
var child = viewContainer.childAt(viewContainerPos.x, viewContainerPos.y);
|
||||
// In the tests, the mouseArea sometimes gets picked instead of the cells,
|
||||
// probably because stuff is still loading. To be safe, we check for that here.
|
||||
return child && child !== mouseArea ? child.__index : -1;
|
||||
}
|
||||
|
||||
onEntered: {
|
||||
hoveredCellIndex = cellIndexAt(mouseX, mouseY);
|
||||
if (hoveredCellIndex === undefined) {
|
||||
hoveredCellIndex = cellIndexAt(mouseX, mouseY);
|
||||
}
|
||||
|
||||
var date = view.model.dateAt(hoveredCellIndex);
|
||||
if (__isValidDate(date)) {
|
||||
control.hovered(date);
|
||||
}
|
||||
}
|
||||
|
||||
onExited: {
|
||||
hoveredCellIndex = -1;
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
var indexOfCell = cellIndexAt(mouse.x, mouse.y);
|
||||
var previousHoveredCellIndex = hoveredCellIndex;
|
||||
hoveredCellIndex = indexOfCell;
|
||||
if (indexOfCell !== -1) {
|
||||
var date = view.model.dateAt(indexOfCell);
|
||||
if (__isValidDate(date)) {
|
||||
if (hoveredCellIndex !== previousHoveredCellIndex)
|
||||
control.hovered(date);
|
||||
|
||||
// The date must be different for the pressed signal to be emitted.
|
||||
if (pressed && date.getTime() !== control.selectedDate.getTime()) {
|
||||
control.pressed(date);
|
||||
|
||||
// You can't select dates in a different month while dragging.
|
||||
if (date.getMonth() === control.selectedDate.getMonth()) {
|
||||
control.selectedDate = date;
|
||||
pressedCellIndex = indexOfCell;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
pressCellIndex = cellIndexAt(mouse.x, mouse.y);
|
||||
pressDate = null;
|
||||
if (pressCellIndex !== -1) {
|
||||
var date = view.model.dateAt(pressCellIndex);
|
||||
pressedCellIndex = pressCellIndex;
|
||||
pressDate = date;
|
||||
if (__isValidDate(date)) {
|
||||
control.selectedDate = date;
|
||||
control.pressed(date);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
var indexOfCell = cellIndexAt(mouse.x, mouse.y);
|
||||
if (indexOfCell !== -1) {
|
||||
// The cell index might be valid, but the date has to be too. We could let the
|
||||
// selected date validation take care of this, but then the selected date would
|
||||
// change to the earliest day if a day before the minimum date is clicked, for example.
|
||||
var date = view.model.dateAt(indexOfCell);
|
||||
if (__isValidDate(date)) {
|
||||
control.released(date);
|
||||
}
|
||||
}
|
||||
pressedCellIndex = -1;
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
var indexOfCell = cellIndexAt(mouse.x, mouse.y);
|
||||
if (indexOfCell !== -1 && indexOfCell === pressCellIndex) {
|
||||
if (__isValidDate(pressDate))
|
||||
control.clicked(pressDate);
|
||||
}
|
||||
}
|
||||
|
||||
onDoubleClicked: {
|
||||
var indexOfCell = cellIndexAt(mouse.x, mouse.y);
|
||||
if (indexOfCell !== -1) {
|
||||
var date = view.model.dateAt(indexOfCell);
|
||||
if (__isValidDate(date))
|
||||
control.doubleClicked(date);
|
||||
}
|
||||
}
|
||||
|
||||
onPressAndHold: {
|
||||
var indexOfCell = cellIndexAt(mouse.x, mouse.y);
|
||||
if (indexOfCell !== -1 && indexOfCell === pressCellIndex) {
|
||||
var date = view.model.dateAt(indexOfCell);
|
||||
if (__isValidDate(date))
|
||||
control.pressAndHold(date);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
function onSelectedDateChanged() { view.selectedDateChanged() }
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: view
|
||||
|
||||
property int currentIndex: -1
|
||||
|
||||
model: control.__model
|
||||
|
||||
Component.onCompleted: selectedDateChanged()
|
||||
|
||||
function selectedDateChanged() {
|
||||
if (model !== undefined && model.locale !== undefined) {
|
||||
currentIndex = model.indexAt(control.selectedDate);
|
||||
}
|
||||
}
|
||||
|
||||
delegate: Loader {
|
||||
id: delegateLoader
|
||||
|
||||
x: __cellRectAt(index).x
|
||||
y: __cellRectAt(index).y
|
||||
width: __cellRectAt(index).width
|
||||
height: __cellRectAt(index).height
|
||||
sourceComponent: dayDelegate
|
||||
|
||||
readonly property int __index: index
|
||||
readonly property date __date: date
|
||||
// We rely on the fact that an invalid QDate will be converted to a Date
|
||||
// whose year is -4713, which is always an invalid date since our
|
||||
// earliest minimum date is the year 1.
|
||||
readonly property bool valid: __isValidDate(date)
|
||||
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias index: delegateLoader.__index
|
||||
readonly property bool selected: control.selectedDate.getFullYear() === date.getFullYear() &&
|
||||
control.selectedDate.getMonth() === date.getMonth() &&
|
||||
control.selectedDate.getDate() === date.getDate()
|
||||
readonly property alias date: delegateLoader.__date
|
||||
readonly property bool valid: delegateLoader.valid
|
||||
// TODO: this will not be correct if the app is running when a new day begins.
|
||||
readonly property bool today: date.getTime() === new Date().setHours(0, 0, 0, 0)
|
||||
readonly property bool visibleMonth: date.getMonth() === control.visibleMonth
|
||||
readonly property bool hovered: panelItem.hoveredCellIndex == index
|
||||
readonly property bool pressed: panelItem.pressedCellIndex == index
|
||||
// todo: pressed property here, clicked and doubleClicked in the control itself
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Window 2.1
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype CheckBoxStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.1
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for CheckBox.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
CheckBox {
|
||||
text: "Check Box"
|
||||
style: CheckBoxStyle {
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 16
|
||||
implicitHeight: 16
|
||||
radius: 3
|
||||
border.color: control.activeFocus ? "darkblue" : "gray"
|
||||
border.width: 1
|
||||
Rectangle {
|
||||
visible: control.checked
|
||||
color: "#555"
|
||||
border.color: "#333"
|
||||
radius: 1
|
||||
anchors.margins: 4
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
Style {
|
||||
id: checkboxStyle
|
||||
|
||||
/*! The \l CheckBox this style is attached to. */
|
||||
readonly property CheckBox control: __control
|
||||
|
||||
/*! This defines the text label. */
|
||||
property Component label: Item {
|
||||
implicitWidth: text.implicitWidth + 2
|
||||
implicitHeight: text.implicitHeight
|
||||
baselineOffset: text.baselineOffset
|
||||
Rectangle {
|
||||
anchors.fill: text
|
||||
anchors.margins: -1
|
||||
anchors.leftMargin: -3
|
||||
anchors.rightMargin: -3
|
||||
visible: control.activeFocus
|
||||
height: 6
|
||||
radius: 3
|
||||
color: "#224f9fef"
|
||||
border.color: "#47b"
|
||||
opacity: 0.6
|
||||
}
|
||||
Text {
|
||||
id: text
|
||||
text: StyleHelpers.stylizeMnemonics(control.text)
|
||||
anchors.centerIn: parent
|
||||
color: SystemPaletteSingleton.text(control.enabled)
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
}
|
||||
}
|
||||
/*! The background under indicator and label. */
|
||||
property Component background
|
||||
|
||||
/*! The spacing between indicator and label. */
|
||||
property int spacing: Math.round(TextSingleton.implicitHeight/4)
|
||||
|
||||
/*! This defines the indicator button. */
|
||||
property Component indicator: Item {
|
||||
implicitWidth: Math.round(TextSingleton.implicitHeight)
|
||||
implicitHeight: implicitWidth
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: -1
|
||||
color: "#44ffffff"
|
||||
radius: baserect.radius
|
||||
}
|
||||
Rectangle {
|
||||
id: baserect
|
||||
gradient: Gradient {
|
||||
GradientStop {color: "#eee" ; position: 0}
|
||||
GradientStop {color: control.pressed ? "#eee" : "#fff" ; position: 0.1}
|
||||
GradientStop {color: "#fff" ; position: 1}
|
||||
}
|
||||
radius: TextSingleton.implicitHeight * 0.16
|
||||
anchors.fill: parent
|
||||
border.color: control.activeFocus ? "#47b" : "#999"
|
||||
}
|
||||
|
||||
Image {
|
||||
source: "images/check.png"
|
||||
opacity: control.checkedState === Qt.Checked ? control.enabled ? 1 : 0.5 : 0
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: 1
|
||||
Behavior on opacity {NumberAnimation {duration: 80}}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Math.round(baserect.radius)
|
||||
antialiasing: true
|
||||
gradient: Gradient {
|
||||
GradientStop {color: control.pressed ? "#555" : "#999" ; position: 0}
|
||||
GradientStop {color: "#555" ; position: 1}
|
||||
}
|
||||
radius: baserect.radius - 1
|
||||
anchors.centerIn: parent
|
||||
anchors.alignWhenCentered: true
|
||||
border.color: "#222"
|
||||
Behavior on opacity {NumberAnimation {duration: 80}}
|
||||
opacity: control.checkedState === Qt.PartiallyChecked ? control.enabled ? 1 : 0.5 : 0
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
implicitWidth: Math.max(backgroundLoader.implicitWidth, row.implicitWidth + padding.left + padding.right)
|
||||
implicitHeight: Math.max(backgroundLoader.implicitHeight, labelLoader.implicitHeight + padding.top + padding.bottom,indicatorLoader.implicitHeight + padding.top + padding.bottom)
|
||||
baselineOffset: labelLoader.item ? padding.top + labelLoader.item.baselineOffset : 0
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
sourceComponent: background
|
||||
anchors.fill: parent
|
||||
}
|
||||
RowLayout {
|
||||
id: row
|
||||
anchors.fill: parent
|
||||
|
||||
anchors.leftMargin: padding.left
|
||||
anchors.rightMargin: padding.right
|
||||
anchors.topMargin: padding.top
|
||||
anchors.bottomMargin: padding.bottom
|
||||
|
||||
spacing: checkboxStyle.spacing
|
||||
Loader {
|
||||
id: indicatorLoader
|
||||
sourceComponent: indicator
|
||||
}
|
||||
Loader {
|
||||
id: labelLoader
|
||||
Layout.fillWidth: true
|
||||
sourceComponent: label
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Extras module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Extras.Private 1.0
|
||||
|
||||
ButtonStyle {
|
||||
id: buttonStyle
|
||||
|
||||
label: Text {
|
||||
anchors.fill: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: control.text
|
||||
font.pixelSize: TextSingleton.font.pixelSize * 1.25
|
||||
color: control.pressed || control.checked ? __buttonHelper.textColorDown : __buttonHelper.textColorUp
|
||||
styleColor: control.pressed || control.checked ? __buttonHelper.textRaisedColorDown : __buttonHelper.textRaisedColorUp
|
||||
style: Text.Raised
|
||||
wrapMode: Text.Wrap
|
||||
fontSizeMode: Text.Fit
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property alias __buttonHelper: buttonHelper
|
||||
|
||||
CircularButtonStyleHelper {
|
||||
id: buttonHelper
|
||||
control: buttonStyle.control
|
||||
}
|
||||
|
||||
background: Item {
|
||||
implicitWidth: __buttonHelper.implicitWidth
|
||||
implicitHeight: __buttonHelper.implicitHeight
|
||||
|
||||
Canvas {
|
||||
id: backgroundCanvas
|
||||
anchors.fill: parent
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
function onPressedChanged() { backgroundCanvas.requestPaint() }
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
__buttonHelper.paintBackground(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,497 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Extras module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Controls.Private 1.0
|
||||
import QtQuick.Extras 1.4
|
||||
import QtQuick.Extras.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype CircularGaugeStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.5
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for CircularGauge.
|
||||
|
||||
You can create a custom circular gauge by replacing the following delegates:
|
||||
\list
|
||||
\li \l background
|
||||
\li \l tickmark
|
||||
\li \l minorTickmark
|
||||
\li \l tickmarkLabel
|
||||
\li \l needle
|
||||
\li \l foreground
|
||||
\endlist
|
||||
|
||||
Below is an example that changes the needle to a basic orange \l Rectangle:
|
||||
\code
|
||||
CircularGauge {
|
||||
style: CircularGaugeStyle {
|
||||
needle: Rectangle {
|
||||
y: outerRadius * 0.15
|
||||
implicitWidth: outerRadius * 0.03
|
||||
implicitHeight: outerRadius * 0.9
|
||||
antialiasing: true
|
||||
color: Qt.rgba(0.66, 0.3, 0, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
The result:
|
||||
\image circulargauge-needle-example-2.png CircularGaugeStyle example
|
||||
|
||||
\section2 Direction
|
||||
|
||||
\l minimumValueAngle and \l maximumValueAngle determine not only the
|
||||
position of the tickmarks, labels and needle, but the direction in which
|
||||
they are displayed around the gauge. For example, if \l minimumValueAngle
|
||||
is greater than \l maximumValueAngle, the gauge will be anti-clockwise.
|
||||
Below, there are two gauges: the top gauge has a \l minimumValueAngle of
|
||||
\c -90 degrees and a \l maximumValueAngle of \c 90 degrees, and the bottom
|
||||
gauge has the opposite.
|
||||
|
||||
\image circulargauge-reversed.png Reversed CircularGauge
|
||||
|
||||
\sa {Styling CircularGauge}
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: circularGaugeStyle
|
||||
|
||||
/*!
|
||||
The \l CircularGauge that this style is attached to.
|
||||
*/
|
||||
readonly property CircularGauge control: __control
|
||||
|
||||
/*!
|
||||
The distance from the center of the gauge to the outer edge of the
|
||||
gauge.
|
||||
|
||||
This property is useful for determining the size of the various
|
||||
components of the style, in order to ensure that they are scaled
|
||||
proportionately when the gauge is resized.
|
||||
*/
|
||||
readonly property real outerRadius: Math.min(control.width, control.height) * 0.5
|
||||
|
||||
/*!
|
||||
This property determines the angle at which the minimum value is
|
||||
displayed on the gauge.
|
||||
|
||||
The angle set affects the following components of the gauge:
|
||||
\list
|
||||
\li The angle of the needle
|
||||
\li The position of the tickmarks and labels
|
||||
\endlist
|
||||
|
||||
The angle origin points north:
|
||||
|
||||
\image circulargauge-angles.png
|
||||
|
||||
There is no minimum or maximum angle for this property, but the default
|
||||
style only supports angles whose absolute range is less than or equal
|
||||
to \c 360 degrees. This is because ranges higher than \c 360 degrees
|
||||
will cause the tickmarks and labels to overlap each other.
|
||||
|
||||
The default value is \c -145.
|
||||
*/
|
||||
property real minimumValueAngle: -145
|
||||
|
||||
/*!
|
||||
This property determines the angle at which the maximum value is
|
||||
displayed on the gauge.
|
||||
|
||||
The angle set affects the following components of the gauge:
|
||||
\list
|
||||
\li The angle of the needle
|
||||
\li The position of the tickmarks and labels
|
||||
\endlist
|
||||
|
||||
The angle origin points north:
|
||||
|
||||
\image circulargauge-angles.png
|
||||
|
||||
There is no minimum or maximum angle for this property, but the default
|
||||
style only supports angles whose absolute range is less than or equal
|
||||
to \c 360 degrees. This is because ranges higher than \c 360 degrees
|
||||
will cause the tickmarks and labels to overlap each other.
|
||||
|
||||
The default value is \c 145.
|
||||
*/
|
||||
property real maximumValueAngle: 145
|
||||
|
||||
/*!
|
||||
The range between \l minimumValueAngle and \l maximumValueAngle, in
|
||||
degrees. This value will always be positive.
|
||||
*/
|
||||
readonly property real angleRange: control.__panel.circularTickmarkLabel.angleRange
|
||||
|
||||
/*!
|
||||
This property holds the rotation of the needle in degrees.
|
||||
*/
|
||||
property real needleRotation: {
|
||||
var percentage = (control.value - control.minimumValue) / (control.maximumValue - control.minimumValue);
|
||||
minimumValueAngle + percentage * angleRange;
|
||||
}
|
||||
|
||||
/*!
|
||||
The interval at which tickmarks are displayed.
|
||||
|
||||
For example, if this property is set to \c 10 (the default),
|
||||
control.minimumValue to \c 0, and control.maximumValue to \c 100,
|
||||
the tickmarks displayed will be 0, 10, 20, etc., to 100,
|
||||
around the gauge.
|
||||
*/
|
||||
property real tickmarkStepSize: 10
|
||||
|
||||
/*!
|
||||
The distance in pixels from the outside of the gauge (outerRadius) at
|
||||
which the outermost point of the tickmark line is drawn.
|
||||
*/
|
||||
property real tickmarkInset: 0
|
||||
|
||||
|
||||
/*!
|
||||
The amount of tickmarks displayed by the gauge, calculated from
|
||||
\l tickmarkStepSize and the control's
|
||||
\l {CircularGauge::minimumValue}{minimumValue} and
|
||||
\l {CircularGauge::maximumValue}{maximumValue}.
|
||||
|
||||
\sa minorTickmarkCount
|
||||
*/
|
||||
readonly property int tickmarkCount: control.__panel.circularTickmarkLabel.tickmarkCount
|
||||
|
||||
/*!
|
||||
The amount of minor tickmarks between each tickmark.
|
||||
|
||||
The default value is \c 4.
|
||||
|
||||
\sa tickmarkCount
|
||||
*/
|
||||
property int minorTickmarkCount: 4
|
||||
|
||||
/*!
|
||||
The distance in pixels from the outside of the gauge (outerRadius) at
|
||||
which the outermost point of the minor tickmark line is drawn.
|
||||
*/
|
||||
property real minorTickmarkInset: 0
|
||||
|
||||
/*!
|
||||
The distance in pixels from the outside of the gauge (outerRadius) at
|
||||
which the center of the value marker text is drawn.
|
||||
*/
|
||||
property real labelInset: __protectedScope.toPixels(0.19)
|
||||
|
||||
/*!
|
||||
The interval at which tickmark labels are displayed.
|
||||
|
||||
For example, if this property is set to \c 10 (the default),
|
||||
control.minimumValue to \c 0, and control.maximumValue to \c 100, the
|
||||
tickmark labels displayed will be 0, 10, 20, etc., to 100,
|
||||
around the gauge.
|
||||
*/
|
||||
property real labelStepSize: tickmarkStepSize
|
||||
|
||||
/*!
|
||||
The amount of tickmark labels displayed by the gauge, calculated from
|
||||
\l labelStepSize and the control's
|
||||
\l {CircularGauge::minimumValue}{minimumValue} and
|
||||
\l {CircularGauge::maximumValue}{maximumValue}.
|
||||
|
||||
\sa tickmarkCount, minorTickmarkCount
|
||||
*/
|
||||
readonly property int labelCount: control.__panel.circularTickmarkLabel.labelCount
|
||||
|
||||
/*! \qmlmethod real CircularGaugeStyle::valueToAngle(real value)
|
||||
Returns \a value as an angle in degrees.
|
||||
|
||||
This function is useful for custom drawing or positioning of items in
|
||||
the style's components. For example, it can be used to calculate the
|
||||
angles at which to draw an arc around the gauge indicating the safe
|
||||
area for the needle to be within.
|
||||
|
||||
For example, if minimumValueAngle is set to \c 270 and
|
||||
maximumValueAngle is set to \c 90, this function will return \c 270
|
||||
when passed minimumValue and \c 90 when passed maximumValue.
|
||||
|
||||
\sa {Styling CircularGauge#styling-circulargauge-background}{
|
||||
Styling CircularGauge's background}
|
||||
*/
|
||||
function valueToAngle(value) {
|
||||
return control.__panel.circularTickmarkLabel.valueToAngle(value);
|
||||
}
|
||||
|
||||
property QtObject __protectedScope: QtObject {
|
||||
/*!
|
||||
Converts a value expressed as a percentage of \l outerRadius to
|
||||
a pixel value.
|
||||
*/
|
||||
function toPixels(percentageOfOuterRadius) {
|
||||
return percentageOfOuterRadius * outerRadius;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The background of the gauge.
|
||||
|
||||
If set, the background determines the implicit size of the gauge.
|
||||
|
||||
By default, there is no background defined.
|
||||
|
||||
\sa {Styling CircularGauge#styling-circulargauge-background}{
|
||||
Styling CircularGauge's background}
|
||||
*/
|
||||
property Component background
|
||||
|
||||
/*!
|
||||
This component defines each individual tickmark. The position of each
|
||||
tickmark is already set; only the
|
||||
\l {Item::implicitWidth}{implicitWidth} and
|
||||
\l {Item::implicitHeight}{implicitHeight} need to be specified.
|
||||
|
||||
Each instance of this component has access to the following properties:
|
||||
|
||||
\table
|
||||
\row \li \c {readonly property int} \b styleData.index
|
||||
\li The index of this tickmark.
|
||||
\row \li \c {readonly property real} \b styleData.value
|
||||
\li The value that this tickmark represents.
|
||||
\endtable
|
||||
|
||||
To illustrate what these properties refer to, we can use the following
|
||||
example:
|
||||
|
||||
\snippet circulargauge-tickmark-indices-values.qml tickmarks
|
||||
|
||||
We've replaced the conventional \e line tickmarks with \l Text items
|
||||
and have hidden the tickmarkLabel component in order to make the
|
||||
association clearer:
|
||||
|
||||
\image circulargauge-tickmark-indices-values.png Tickmarks
|
||||
|
||||
The index property can be useful if you have another model that
|
||||
contains images to display for each index, for example.
|
||||
|
||||
The value property is useful for drawing lower and upper limits around
|
||||
the gauge to indicate the recommended value ranges. For example, speeds
|
||||
above 200 kilometers an hour in a car's speedometer could be indicated
|
||||
as dangerous using this property.
|
||||
|
||||
\sa {Styling CircularGauge#styling-circulargauge-tickmark}{
|
||||
Styling CircularGauge's tickmark}
|
||||
*/
|
||||
property Component tickmark: Rectangle {
|
||||
implicitWidth: outerRadius * 0.02
|
||||
antialiasing: true
|
||||
implicitHeight: outerRadius * 0.06
|
||||
color: "#c8c8c8"
|
||||
}
|
||||
|
||||
/*!
|
||||
This component defines each individual minor tickmark. The position of
|
||||
each minor tickmark is already set; only the
|
||||
\l {Item::implicitWidth}{implicitWidth} and
|
||||
\l {Item::implicitHeight}{implicitHeight} need to be specified.
|
||||
|
||||
Each instance of this component has access to the following properties:
|
||||
|
||||
\table
|
||||
\row \li \c {readonly property int} \b styleData.index
|
||||
\li The index of this tickmark.
|
||||
\row \li \c {readonly property real} \b styleData.value
|
||||
\li The value that this tickmark represents.
|
||||
\endtable
|
||||
|
||||
\sa {Styling CircularGauge#styling-circulargauge-minorTickmark}{
|
||||
Styling CircularGauge's minorTickmark}
|
||||
*/
|
||||
property Component minorTickmark: Rectangle {
|
||||
implicitWidth: outerRadius * 0.01
|
||||
antialiasing: true
|
||||
implicitHeight: outerRadius * 0.03
|
||||
color: "#c8c8c8"
|
||||
}
|
||||
|
||||
/*!
|
||||
This defines the text of each tickmark label on the gauge.
|
||||
|
||||
Each instance of this component has access to the following properties:
|
||||
|
||||
\table
|
||||
\row \li \c {readonly property int} \b styleData.index
|
||||
\li The index of this label.
|
||||
\row \li \c {readonly property real} \b styleData.value
|
||||
\li The value that this label represents.
|
||||
\endtable
|
||||
|
||||
\sa {Styling CircularGauge#styling-circulargauge-tickmarkLabel}{
|
||||
Styling CircularGauge's tickmarkLabel}
|
||||
*/
|
||||
property Component tickmarkLabel: Text {
|
||||
font.pixelSize: Math.max(6, __protectedScope.toPixels(0.12))
|
||||
text: styleData.value
|
||||
color: "#c8c8c8"
|
||||
antialiasing: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
/*!
|
||||
The needle that points to the gauge's current value.
|
||||
|
||||
This component is drawn below the \l foreground component.
|
||||
|
||||
The style expects the needle to be pointing up at a rotation of \c 0,
|
||||
in order for the rotation to be correct. For example:
|
||||
|
||||
\image circulargauge-needle.png CircularGauge's needle
|
||||
|
||||
When defining your own needle component, the only properties that the
|
||||
style requires you to set are the
|
||||
\l {Item::implicitWidth}{implicitWidth} and
|
||||
\l {Item::implicitHeight}{implicitHeight}.
|
||||
|
||||
Optionally, you can set \l {Item::x}{x} and \l {Item::y}{y} to change
|
||||
the needle's transform origin. Setting the \c x position can be useful
|
||||
for needle images where the needle is not centered exactly
|
||||
horizontally. Setting the \c y position allows you to make the base of
|
||||
the needle hang over the center of the gauge.
|
||||
|
||||
\sa {Styling CircularGauge#styling-circulargauge-needle}{
|
||||
Styling CircularGauge's needle}
|
||||
*/
|
||||
property Component needle: Item {
|
||||
implicitWidth: __protectedScope.toPixels(0.08)
|
||||
implicitHeight: 0.9 * outerRadius
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: "images/needle.png"
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The foreground of the gauge. This component is drawn above all others.
|
||||
|
||||
Like \l background, the foreground component fills the entire gauge.
|
||||
|
||||
By default, the knob of the gauge is defined here.
|
||||
|
||||
\sa {Styling CircularGauge#styling-circulargauge-foreground}{
|
||||
Styling CircularGauge's foreground}
|
||||
*/
|
||||
property Component foreground: Item {
|
||||
Image {
|
||||
source: "images/knob.png"
|
||||
anchors.centerIn: parent
|
||||
scale: {
|
||||
var idealHeight = __protectedScope.toPixels(0.2);
|
||||
var originalImageHeight = sourceSize.height;
|
||||
idealHeight / originalImageHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
id: panelItem
|
||||
implicitWidth: backgroundLoader.item ? backgroundLoader.implicitWidth : TextSingleton.implicitHeight * 16
|
||||
implicitHeight: backgroundLoader.item ? backgroundLoader.implicitHeight : TextSingleton.implicitHeight * 16
|
||||
|
||||
property alias background: backgroundLoader.item
|
||||
property alias circularTickmarkLabel: circularTickmarkLabel_
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
sourceComponent: circularGaugeStyle.background
|
||||
width: outerRadius * 2
|
||||
height: outerRadius * 2
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
CircularTickmarkLabel {
|
||||
id: circularTickmarkLabel_
|
||||
anchors.fill: backgroundLoader
|
||||
|
||||
minimumValue: control.minimumValue
|
||||
maximumValue: control.maximumValue
|
||||
stepSize: control.stepSize
|
||||
tickmarksVisible: control.tickmarksVisible
|
||||
minimumValueAngle: circularGaugeStyle.minimumValueAngle
|
||||
maximumValueAngle: circularGaugeStyle.maximumValueAngle
|
||||
tickmarkStepSize: circularGaugeStyle.tickmarkStepSize
|
||||
tickmarkInset: circularGaugeStyle.tickmarkInset
|
||||
minorTickmarkCount: circularGaugeStyle.minorTickmarkCount
|
||||
minorTickmarkInset: circularGaugeStyle.minorTickmarkInset
|
||||
labelInset: circularGaugeStyle.labelInset
|
||||
labelStepSize: circularGaugeStyle.labelStepSize
|
||||
|
||||
style: CircularTickmarkLabelStyle {
|
||||
tickmark: circularGaugeStyle.tickmark
|
||||
minorTickmark: circularGaugeStyle.minorTickmark
|
||||
tickmarkLabel: circularGaugeStyle.tickmarkLabel
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: needleLoader
|
||||
sourceComponent: circularGaugeStyle.needle
|
||||
transform: [
|
||||
Rotation {
|
||||
angle: needleRotation
|
||||
origin.x: needleLoader.width / 2
|
||||
origin.y: needleLoader.height
|
||||
},
|
||||
Translate {
|
||||
x: panelItem.width / 2 - needleLoader.width / 2
|
||||
y: panelItem.height / 2 - needleLoader.height
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: foreground
|
||||
sourceComponent: circularGaugeStyle.foreground
|
||||
anchors.fill: backgroundLoader
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Extras module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
import QtQuick.Extras.Private 1.0
|
||||
import QtQuick.Extras.Private.CppUtils 1.0
|
||||
|
||||
Style {
|
||||
id: circularTickmarkLabelStyle
|
||||
|
||||
/*!
|
||||
The distance from the center of the control to the outer edge.
|
||||
*/
|
||||
readonly property real outerRadius: Math.min(control.width, control.height) * 0.5
|
||||
|
||||
property QtObject __protectedScope: QtObject {
|
||||
/*!
|
||||
Converts a value expressed as a percentage of \l outerRadius to
|
||||
a pixel value.
|
||||
*/
|
||||
function toPixels(percentageOfOuterRadius) {
|
||||
return percentageOfOuterRadius * outerRadius;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
This component defines each individual tickmark. The position of each
|
||||
tickmark is already set; only the size needs to be specified.
|
||||
*/
|
||||
property Component tickmark: Rectangle {
|
||||
width: outerRadius * 0.02
|
||||
antialiasing: true
|
||||
height: outerRadius * 0.06
|
||||
color: "#c8c8c8"
|
||||
}
|
||||
|
||||
/*!
|
||||
This component defines each individual minor tickmark. The position of
|
||||
each minor tickmark is already set; only the size needs to be specified.
|
||||
*/
|
||||
property Component minorTickmark: Rectangle {
|
||||
width: outerRadius * 0.01
|
||||
antialiasing: true
|
||||
height: outerRadius * 0.03
|
||||
color: "#c8c8c8"
|
||||
}
|
||||
|
||||
/*!
|
||||
This defines the text of each tickmark label on the gauge.
|
||||
*/
|
||||
property Component tickmarkLabel: Text {
|
||||
font.pixelSize: Math.max(6, __protectedScope.toPixels(0.12))
|
||||
text: styleData.value
|
||||
color: "#c8c8c8"
|
||||
antialiasing: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
id: panelItem
|
||||
implicitWidth: 250
|
||||
implicitHeight: 250
|
||||
|
||||
function rangeUsed(count, stepSize) {
|
||||
return (((count - 1) * stepSize) / (control.maximumValue - control.minimumValue)) * control.angleRange;
|
||||
}
|
||||
|
||||
readonly property real tickmarkSectionSize: rangeUsed(control.tickmarkCount, control.tickmarkStepSize) / (control.tickmarkCount - 1)
|
||||
readonly property real tickmarkSectionValue: (control.maximumValue - control.minimumValue) / (control.tickmarkCount - 1)
|
||||
readonly property real minorTickmarkSectionSize: tickmarkSectionSize / (control.minorTickmarkCount + 1)
|
||||
readonly property real minorTickmarkSectionValue: tickmarkSectionValue / (control.minorTickmarkCount + 1)
|
||||
readonly property int totalMinorTickmarkCount: {
|
||||
// The size of each section within two major tickmarks, expressed as a percentage.
|
||||
var minorSectionPercentage = 1 / (control.minorTickmarkCount + 1);
|
||||
// The amount of major tickmarks not able to be displayed; will be 0 if they all fit.
|
||||
var tickmarksNotDisplayed = control.__tickmarkCount - control.tickmarkCount;
|
||||
var count = control.minorTickmarkCount * (control.tickmarkCount - 1);
|
||||
// We'll try to display as many minor tickmarks as we can to fill up the space.
|
||||
count + tickmarksNotDisplayed / minorSectionPercentage;
|
||||
}
|
||||
readonly property real labelSectionSize: rangeUsed(control.labelCount, control.labelStepSize) / (control.labelCount - 1)
|
||||
|
||||
function toPixels(percentageOfOuterRadius) {
|
||||
return percentageOfOuterRadius * outerRadius;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the angle of \a marker (in the range 0 ... n - 1, where n
|
||||
is the amount of markers) on the gauge where sections are of size
|
||||
tickmarkSectionSize.
|
||||
*/
|
||||
function tickmarkAngleFromIndex(tickmarkIndex) {
|
||||
return tickmarkIndex * tickmarkSectionSize + control.minimumValueAngle;
|
||||
}
|
||||
|
||||
function labelAngleFromIndex(labelIndex) {
|
||||
return labelIndex * labelSectionSize + control.minimumValueAngle;
|
||||
}
|
||||
|
||||
function labelPosFromIndex(index, labelWidth, labelHeight) {
|
||||
return MathUtils.centerAlongCircle(outerRadius, outerRadius, labelWidth, labelHeight,
|
||||
MathUtils.degToRadOffset(labelAngleFromIndex(index)),
|
||||
outerRadius - control.labelInset)
|
||||
}
|
||||
|
||||
function minorTickmarkAngleFromIndex(minorTickmarkIndex) {
|
||||
var baseAngle = tickmarkAngleFromIndex(Math.floor(minorTickmarkIndex / control.minorTickmarkCount));
|
||||
// + minorTickmarkSectionSize because we don't want the first minor tickmark to start on top of its "parent" tickmark.
|
||||
var relativeMinorAngle = (minorTickmarkIndex % control.minorTickmarkCount * minorTickmarkSectionSize) + minorTickmarkSectionSize;
|
||||
return baseAngle + relativeMinorAngle;
|
||||
}
|
||||
|
||||
function tickmarkValueFromIndex(majorIndex) {
|
||||
return (majorIndex * tickmarkSectionValue) + control.minimumValue;
|
||||
}
|
||||
|
||||
function tickmarkValueFromMinorIndex(minorIndex) {
|
||||
var majorIndex = Math.floor(minorIndex / control.minorTickmarkCount);
|
||||
var relativeMinorIndex = minorIndex % control.minorTickmarkCount;
|
||||
return tickmarkValueFromIndex(majorIndex) + ((relativeMinorIndex * minorTickmarkSectionValue) + minorTickmarkSectionValue);
|
||||
}
|
||||
|
||||
Loader {
|
||||
active: control.tickmarksVisible && tickmark != null
|
||||
width: outerRadius * 2
|
||||
height: outerRadius * 2
|
||||
anchors.centerIn: parent
|
||||
|
||||
sourceComponent: Repeater {
|
||||
id: tickmarkRepeater
|
||||
model: control.tickmarkCount
|
||||
delegate: Loader {
|
||||
id: tickmarkLoader
|
||||
objectName: "tickmark" + styleData.index
|
||||
x: tickmarkRepeater.width / 2
|
||||
y: tickmarkRepeater.height / 2
|
||||
|
||||
transform: [
|
||||
Translate {
|
||||
y: -outerRadius + control.tickmarkInset
|
||||
},
|
||||
Rotation {
|
||||
angle: panelItem.tickmarkAngleFromIndex(styleData.index) - __tickmarkWidthAsAngle / 2
|
||||
}
|
||||
]
|
||||
|
||||
sourceComponent: tickmark
|
||||
|
||||
property int __index: index
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias index: tickmarkLoader.__index
|
||||
readonly property real value: tickmarkValueFromIndex(index)
|
||||
}
|
||||
|
||||
readonly property real __tickmarkWidthAsAngle: MathUtils.radToDeg((width / (MathUtils.pi2 * outerRadius)) * MathUtils.pi2)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
active: control.tickmarksVisible && minorTickmark != null
|
||||
width: outerRadius * 2
|
||||
height: outerRadius * 2
|
||||
anchors.centerIn: parent
|
||||
|
||||
sourceComponent: Repeater {
|
||||
id: minorRepeater
|
||||
anchors.fill: parent
|
||||
model: totalMinorTickmarkCount
|
||||
delegate: Loader {
|
||||
id: minorTickmarkLoader
|
||||
objectName: "minorTickmark" + styleData.index
|
||||
x: minorRepeater.width / 2
|
||||
y: minorRepeater.height / 2
|
||||
transform: [
|
||||
Translate {
|
||||
y: -outerRadius + control.minorTickmarkInset
|
||||
},
|
||||
Rotation {
|
||||
angle: panelItem.minorTickmarkAngleFromIndex(styleData.index) - __minorTickmarkWidthAsAngle / 2
|
||||
}
|
||||
]
|
||||
|
||||
sourceComponent: minorTickmark
|
||||
|
||||
property int __index: index
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias index: minorTickmarkLoader.__index
|
||||
readonly property real value: tickmarkValueFromMinorIndex(index)
|
||||
}
|
||||
|
||||
readonly property real __minorTickmarkWidthAsAngle: MathUtils.radToDeg((width / (MathUtils.pi2 * outerRadius)) * MathUtils.pi2)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
id: labelLoader
|
||||
active: control.tickmarksVisible && tickmarkLabel != null
|
||||
width: outerRadius * 2
|
||||
height: outerRadius * 2
|
||||
anchors.centerIn: parent
|
||||
|
||||
sourceComponent: Item {
|
||||
id: labelItem
|
||||
width: outerRadius * 2
|
||||
height: outerRadius * 2
|
||||
anchors.centerIn: parent
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
function onMinimumValueChanged() { valueTextModel.update() }
|
||||
function onMaximumValueChanged() { valueTextModel.update() }
|
||||
function onTickmarkStepSizeChanged() { valueTextModel.update() }
|
||||
function onLabelStepSizeChanged() { valueTextModel.update() }
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: labelItemRepeater
|
||||
|
||||
Component.onCompleted: valueTextModel.update();
|
||||
|
||||
model: ListModel {
|
||||
id: valueTextModel
|
||||
|
||||
function update() {
|
||||
if (control.labelStepSize === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make bigger if it's too small and vice versa.
|
||||
// +1 because we want to show 11 values, with, for example: 0, 10, 20... 100.
|
||||
var difference = control.labelCount - count;
|
||||
if (difference > 0) {
|
||||
for (; difference > 0; --difference) {
|
||||
append({ value: 0 });
|
||||
}
|
||||
} else if (difference < 0) {
|
||||
for (; difference < 0; ++difference) {
|
||||
remove(count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
var index = 0;
|
||||
for (var value = control.minimumValue;
|
||||
value <= control.maximumValue && index < count;
|
||||
value += control.labelStepSize, ++index) {
|
||||
setProperty(index, "value", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate: Loader {
|
||||
id: tickmarkLabelDelegateLoader
|
||||
objectName: "labelDelegateLoader" + index
|
||||
sourceComponent: tickmarkLabel
|
||||
x: pos.x
|
||||
y: pos.y
|
||||
|
||||
readonly property point pos: panelItem.labelPosFromIndex(index, width, height);
|
||||
|
||||
readonly property int __index: index
|
||||
readonly property real __value: value
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property var value: index != -1 ? tickmarkLabelDelegateLoader.__value : 0
|
||||
readonly property alias index: tickmarkLabelDelegateLoader.__index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Window 2.1
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype ComboBoxStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.1
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for ComboBox.
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: cbStyle
|
||||
|
||||
/*!
|
||||
\qmlproperty enumeration renderType
|
||||
\since QtQuick.Controls.Styles 1.2
|
||||
|
||||
Override the default rendering type for the control.
|
||||
|
||||
Supported render types are:
|
||||
\list
|
||||
\li Text.QtRendering
|
||||
\li Text.NativeRendering
|
||||
\endlist
|
||||
|
||||
The default value is platform dependent.
|
||||
|
||||
\sa Text::renderType
|
||||
*/
|
||||
property int renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
|
||||
/*!
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
The font of the control.
|
||||
*/
|
||||
property font font
|
||||
|
||||
/*!
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
The text color.
|
||||
*/
|
||||
property color textColor: SystemPaletteSingleton.text(control.enabled)
|
||||
|
||||
/*!
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
The text highlight color, used behind selections.
|
||||
*/
|
||||
property color selectionColor: SystemPaletteSingleton.highlight(control.enabled)
|
||||
|
||||
/*!
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
The highlighted text color, used in selections.
|
||||
*/
|
||||
property color selectedTextColor: SystemPaletteSingleton.highlightedText(control.enabled)
|
||||
|
||||
/*! The \l ComboBox this style is attached to. */
|
||||
readonly property ComboBox control: __control
|
||||
|
||||
/*! The padding between the background and the label components. */
|
||||
padding { top: 4 ; left: 6 ; right: 6 ; bottom:4 }
|
||||
|
||||
/*! The size of the drop down button when the combobox is editable. */
|
||||
property int dropDownButtonWidth: Math.round(TextSingleton.implicitHeight)
|
||||
|
||||
/*! \internal Alias kept for backwards compatibility with a spelling mistake in 5.2.0) */
|
||||
property alias drowDownButtonWidth: cbStyle.dropDownButtonWidth
|
||||
|
||||
/*! This defines the background of the button. */
|
||||
property Component background: Item {
|
||||
implicitWidth: Math.round(TextSingleton.implicitHeight * 4.5)
|
||||
implicitHeight: Math.max(25, Math.round(TextSingleton.implicitHeight * 1.2))
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: control.pressed ? 0 : -1
|
||||
color: "#10000000"
|
||||
radius: baserect.radius
|
||||
}
|
||||
Rectangle {
|
||||
id: baserect
|
||||
gradient: Gradient {
|
||||
GradientStop {color: control.pressed ? "#bababa" : "#fefefe" ; position: 0}
|
||||
GradientStop {color: control.pressed ? "#ccc" : "#e3e3e3" ; position: 1}
|
||||
}
|
||||
radius: TextSingleton.implicitHeight * 0.16
|
||||
anchors.fill: parent
|
||||
border.color: control.activeFocus ? "#47b" : "#999"
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: parent.radius
|
||||
color: control.activeFocus ? "#47b" : "white"
|
||||
opacity: control.hovered || control.activeFocus ? 0.1 : 0
|
||||
Behavior on opacity {NumberAnimation{ duration: 100 }}
|
||||
}
|
||||
}
|
||||
Image {
|
||||
id: imageItem
|
||||
visible: control.menu !== null
|
||||
source: "images/arrow-down.png"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: dropDownButtonWidth / 2
|
||||
opacity: control.enabled ? 0.6 : 0.3
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component __editor: Item {
|
||||
implicitWidth: 100
|
||||
implicitHeight: Math.max(25, Math.round(TextSingleton.implicitHeight * 1.2))
|
||||
clip: true
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: 0
|
||||
color: "#44ffffff"
|
||||
radius: baserect.radius
|
||||
}
|
||||
Rectangle {
|
||||
id: baserect
|
||||
anchors.rightMargin: -radius
|
||||
anchors.bottomMargin: 1
|
||||
gradient: Gradient {
|
||||
GradientStop {color: "#e0e0e0" ; position: 0}
|
||||
GradientStop {color: "#fff" ; position: 0.1}
|
||||
GradientStop {color: "#fff" ; position: 1}
|
||||
}
|
||||
radius: TextSingleton.implicitHeight * 0.16
|
||||
anchors.fill: parent
|
||||
border.color: control.activeFocus ? "#47b" : "#999"
|
||||
}
|
||||
Rectangle {
|
||||
color: "#aaa"
|
||||
anchors.bottomMargin: 2
|
||||
anchors.topMargin: 1
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
width: 1
|
||||
}
|
||||
}
|
||||
|
||||
/*! This defines the label of the button. */
|
||||
property Component label: Item {
|
||||
implicitWidth: textitem.implicitWidth + 20
|
||||
baselineOffset: textitem.y + textitem.baselineOffset
|
||||
Text {
|
||||
id: textitem
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 4
|
||||
anchors.rightMargin: 10
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: control.currentText
|
||||
renderType: cbStyle.renderType
|
||||
font: cbStyle.font
|
||||
color: cbStyle.textColor
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
property bool popup: false
|
||||
property font font: cbStyle.font
|
||||
property color textColor: cbStyle.textColor
|
||||
property color selectionColor: cbStyle.selectionColor
|
||||
property color selectedTextColor: cbStyle.selectedTextColor
|
||||
property int dropDownButtonWidth: cbStyle.dropDownButtonWidth
|
||||
anchors.centerIn: parent
|
||||
anchors.fill: parent
|
||||
implicitWidth: backgroundLoader.implicitWidth
|
||||
implicitHeight: Math.max(labelLoader.implicitHeight + padding.top + padding.bottom, backgroundLoader.implicitHeight)
|
||||
baselineOffset: labelLoader.item ? padding.top + labelLoader.item.baselineOffset: 0
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: background
|
||||
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: editorLoader
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: dropDownButtonWidth + padding.right
|
||||
anchors.bottomMargin: -1
|
||||
sourceComponent: control.editable ? __editor : null
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: labelLoader
|
||||
sourceComponent: label
|
||||
visible: !control.editable
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: padding.left
|
||||
anchors.topMargin: padding.top
|
||||
anchors.rightMargin: padding.right
|
||||
anchors.bottomMargin: padding.bottom
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component __dropDownStyle: MenuStyle {
|
||||
font: cbStyle.font
|
||||
__labelColor: cbStyle.textColor
|
||||
__selectedLabelColor: cbStyle.selectedTextColor
|
||||
__selectedBackgroundColor: cbStyle.selectionColor
|
||||
__maxPopupHeight: 600
|
||||
__menuItemType: "comboboxitem"
|
||||
__scrollerStyle: ScrollViewStyle { }
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component __popupStyle: Style {
|
||||
property int __maxPopupHeight: 400
|
||||
property int submenuOverlap: 0
|
||||
property int submenuPopupDelay: 100
|
||||
|
||||
property Component frame: Rectangle {
|
||||
id: popupFrame
|
||||
border.color: "white"
|
||||
Text {
|
||||
text: "NOT IMPLEMENTED"
|
||||
color: "red"
|
||||
font {
|
||||
pixelSize: 10
|
||||
bold: true
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
rotation: -Math.atan2(popupFrame.height, popupFrame.width) * 180 / Math.PI
|
||||
}
|
||||
}
|
||||
|
||||
property Component menuItemPanel: Text {
|
||||
text: styleData.text
|
||||
}
|
||||
|
||||
property Component __scrollerStyle: null
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
The cursor handle.
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
|
||||
The parent of the handle is positioned to the top left corner of
|
||||
the cursor position. The interactive area is determined by the
|
||||
geometry of the handle delegate.
|
||||
|
||||
The following signals and read-only properties are available within the scope
|
||||
of the handle delegate:
|
||||
\table
|
||||
\row \li \b {styleData.activated()} [signal] \li Emitted when the handle is activated ie. the editor is clicked.
|
||||
\row \li \b {styleData.pressed} : bool \li Whether the handle is pressed.
|
||||
\row \li \b {styleData.position} : int \li The character position of the handle.
|
||||
\row \li \b {styleData.lineHeight} : real \li The height of the line the handle is on.
|
||||
\row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text.
|
||||
\endtable
|
||||
*/
|
||||
property Component __cursorHandle
|
||||
|
||||
/*! \internal
|
||||
The selection handle.
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
|
||||
The parent of the handle is positioned to the top left corner of
|
||||
the first selected character. The interactive area is determined
|
||||
by the geometry of the handle delegate.
|
||||
|
||||
The following signals and read-only properties are available within the scope
|
||||
of the handle delegate:
|
||||
\table
|
||||
\row \li \b {styleData.activated()} [signal] \li Emitted when the handle is activated ie. the editor is clicked.
|
||||
\row \li \b {styleData.pressed} : bool \li Whether the handle is pressed.
|
||||
\row \li \b {styleData.position} : int \li The character position of the handle.
|
||||
\row \li \b {styleData.lineHeight} : real \li The height of the line the handle is on.
|
||||
\row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text.
|
||||
\endtable
|
||||
*/
|
||||
property Component __selectionHandle
|
||||
|
||||
/*! \internal
|
||||
The cursor delegate.
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
*/
|
||||
property Component __cursorDelegate
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Extras module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
QtObject {
|
||||
property Item control
|
||||
|
||||
property color buttonColorUpTop: "#e3e3e3"
|
||||
property color buttonColorUpBottom: "#b3b3b3"
|
||||
property color buttonColorDownTop: "#d3d3d3"
|
||||
property color buttonColorDownBottom: "#939393"
|
||||
property color textColorUp: "#4e4e4e"
|
||||
property color textColorDown: "#303030"
|
||||
property color textRaisedColorUp: "#ffffff"
|
||||
property color textRaisedColorDown: "#e3e3e3"
|
||||
property color offColor: "#ff0000"
|
||||
property color offColorShine: "#ff6666"
|
||||
property color onColor: "#00cc00"
|
||||
property color onColorShine: "#66ff66"
|
||||
property color inactiveColor: "#1f1f1f"
|
||||
property color inactiveColorShine: "#666666"
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Extras module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Extras 1.4
|
||||
import QtQuick.Extras.Private.CppUtils 1.1
|
||||
|
||||
/*!
|
||||
\qmltype DelayButtonStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.5
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for DelayButton.
|
||||
|
||||
You can create a custom DelayButton by replacing the following delegates:
|
||||
\list
|
||||
\li \l foreground
|
||||
\li \l {ButtonStyle::}{label}
|
||||
\endlist
|
||||
*/
|
||||
|
||||
CircularButtonStyle {
|
||||
id: delayButtonStyle
|
||||
|
||||
/*!
|
||||
The \l DelayButton that this style is attached to.
|
||||
*/
|
||||
readonly property DelayButton control: __control
|
||||
|
||||
/*!
|
||||
The gradient of the progress bar around the button.
|
||||
*/
|
||||
property Gradient progressBarGradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: "#ff6666"
|
||||
}
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: "#ff0000"
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The color of the drop shadow under the progress bar.
|
||||
*/
|
||||
property color progressBarDropShadowColor: "#ff6666"
|
||||
|
||||
background: Item {
|
||||
implicitWidth: __buttonHelper.implicitWidth
|
||||
implicitHeight: __buttonHelper.implicitHeight
|
||||
|
||||
Canvas {
|
||||
id: backgroundCanvas
|
||||
anchors.fill: parent
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
function onPressedChanged() { backgroundCanvas.requestPaint() }
|
||||
function onCheckedChanged() { backgroundCanvas.requestPaint() }
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
__buttonHelper.paintBackground(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The foreground of the button.
|
||||
|
||||
The progress bar is drawn here.
|
||||
*/
|
||||
property Component foreground: Item {
|
||||
id: foregroundItem
|
||||
|
||||
state: "normal"
|
||||
states: [
|
||||
State {
|
||||
name: "normal"
|
||||
|
||||
PropertyChanges {
|
||||
target: foregroundItem
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "activated"
|
||||
}
|
||||
]
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
from: "normal"
|
||||
to: "activated"
|
||||
SequentialAnimation {
|
||||
loops: Animation.Infinite
|
||||
|
||||
NumberAnimation {
|
||||
target: foregroundItem
|
||||
property: "opacity"
|
||||
from: 0.8
|
||||
to: 0
|
||||
duration: 500
|
||||
easing.type: Easing.InOutSine
|
||||
}
|
||||
NumberAnimation {
|
||||
target: foregroundItem
|
||||
property: "opacity"
|
||||
from: 0
|
||||
to: 0.8
|
||||
duration: 500
|
||||
easing.type: Easing.InOutSine
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
function onActivated() { state = "activated" }
|
||||
function onCheckedChanged() { if (!control.checked) state = "normal" }
|
||||
}
|
||||
|
||||
CircularProgressBar {
|
||||
id: progressBar
|
||||
visible: false
|
||||
width: Math.min(parent.width, parent.height) + progressBarDropShadow.radius * 3 * 2
|
||||
height: width
|
||||
anchors.centerIn: parent
|
||||
antialiasing: true
|
||||
barWidth: __buttonHelper.outerArcLineWidth
|
||||
inset: progressBarDropShadow.radius * 3
|
||||
minimumValueAngle: -180
|
||||
maximumValueAngle: 180
|
||||
|
||||
progress: control.progress
|
||||
|
||||
// TODO: Add gradient property if/when we drop support for building with 5.1.
|
||||
function updateGradient() {
|
||||
clearStops();
|
||||
for (var i = 0; i < progressBarGradient.stops.length; ++i) {
|
||||
addStop(progressBarGradient.stops[i].position, progressBarGradient.stops[i].color);
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: updateGradient()
|
||||
|
||||
Connections {
|
||||
target: delayButtonStyle
|
||||
function onProgressBarGradientChanged() { progressBar.updateGradient() }
|
||||
}
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
id: progressBarDropShadow
|
||||
anchors.fill: progressBar
|
||||
// QTBUG-33747
|
||||
// cached: !control.pressed
|
||||
color: progressBarDropShadowColor
|
||||
source: progressBar
|
||||
}
|
||||
}
|
||||
|
||||
panel: Item {
|
||||
implicitWidth: backgroundLoader.implicitWidth
|
||||
implicitHeight: backgroundLoader.implicitHeight
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: background
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: foregroundLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: foreground
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: labelLoader
|
||||
sourceComponent: label
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: padding.left
|
||||
anchors.topMargin: padding.top
|
||||
anchors.rightMargin: padding.right
|
||||
anchors.bottomMargin: padding.bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,359 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Extras module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Controls.Private 1.0
|
||||
import QtQuick.Extras 1.4
|
||||
import QtQuick.Extras.Private 1.0
|
||||
import QtQuick.Extras.Private.CppUtils 1.0
|
||||
|
||||
/*!
|
||||
\qmltype DialStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.5
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for Dial.
|
||||
|
||||
You can create a custom dial by replacing the following delegates:
|
||||
\list
|
||||
\li \l background
|
||||
\endlist
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: dialStyle
|
||||
|
||||
/*!
|
||||
The \l Dial that this style is attached to.
|
||||
*/
|
||||
readonly property Dial control: __control
|
||||
|
||||
/*!
|
||||
The distance from the center of the dial to the outer edge of the dial.
|
||||
|
||||
This property is useful for determining the size of the various
|
||||
components of the style, in order to ensure that they are scaled
|
||||
proportionately when the dial is resized.
|
||||
*/
|
||||
readonly property real outerRadius: Math.min(control.height, control.width) / 2
|
||||
|
||||
/*!
|
||||
The distance in pixels from the outside of the dial (outerRadius)
|
||||
to the center of the handle.
|
||||
*/
|
||||
property real handleInset: (__tickmarkRadius * 4) + ((__handleRadius * 2) * 0.55)
|
||||
|
||||
/*!
|
||||
The interval at which tickmarks are displayed.
|
||||
|
||||
For example, if this property is set to \c 10,
|
||||
control.minimumValue to \c 0, and control.maximumValue to \c 100,
|
||||
the tickmarks displayed will be 0, 10, 20, etc., to 100, along
|
||||
the circumference of the dial.
|
||||
*/
|
||||
property real tickmarkStepSize: 1
|
||||
|
||||
/*!
|
||||
The distance in pixels from the outside of the dial (outerRadius) at
|
||||
which the outermost point of the tickmark line is drawn.
|
||||
*/
|
||||
property real tickmarkInset: 0
|
||||
|
||||
|
||||
/*!
|
||||
The amount of tickmarks displayed by the dial, calculated from
|
||||
\l tickmarkStepSize and the control's
|
||||
\l {Dial::minimumValue}{minimumValue} and
|
||||
\l {Dial::maximumValue}{maximumValue}.
|
||||
|
||||
\sa minorTickmarkCount
|
||||
*/
|
||||
readonly property int tickmarkCount: control.__panel.circularTickmarkLabel.tickmarkCount
|
||||
|
||||
/*!
|
||||
The amount of minor tickmarks between each tickmark.
|
||||
|
||||
\sa tickmarkCount
|
||||
*/
|
||||
property int minorTickmarkCount: 0
|
||||
|
||||
/*!
|
||||
The distance in pixels from the outside of the dial (outerRadius) at
|
||||
which the outermost point of the minor tickmark line is drawn.
|
||||
*/
|
||||
property real minorTickmarkInset: 0
|
||||
|
||||
/*!
|
||||
The distance in pixels from the outside of the dial (outerRadius) at
|
||||
which the center of the value marker text is drawn.
|
||||
*/
|
||||
property real labelInset: 0
|
||||
|
||||
/*!
|
||||
The interval at which tickmark labels are displayed.
|
||||
|
||||
For example, if this property is set to \c 10 (the default),
|
||||
control.minimumValue to \c 0, and control.maximumValue to \c 100, the
|
||||
tickmark labels displayed will be 0, 10, 20, etc., to 100,
|
||||
along the circumference of the dial.
|
||||
*/
|
||||
property real labelStepSize: tickmarkStepSize
|
||||
|
||||
/*!
|
||||
The amount of tickmark labels displayed by the dial, calculated from
|
||||
\l labelStepSize and the control's
|
||||
\l {Dial::minimumValue}{minimumValue} and
|
||||
\l {Dial::maximumValue}{maximumValue}.
|
||||
|
||||
\sa tickmarkCount, minorTickmarkCount
|
||||
*/
|
||||
readonly property int labelCount: control.__panel.circularTickmarkLabel.labelCount
|
||||
|
||||
/*! \qmlmethod real DialStyle::valueToAngle(real value)
|
||||
Returns \a value as an angle in degrees.
|
||||
|
||||
This function is useful for custom drawing or positioning of items in
|
||||
the style's components. For example, it can be used to calculate the
|
||||
angles at which to draw an arc around the dial indicating the safe
|
||||
range of values.
|
||||
*/
|
||||
function valueToAngle(value) {
|
||||
return control.__panel.circularTickmarkLabel.valueToAngle(value);
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
readonly property real __tickmarkRadius: outerRadius * 0.06
|
||||
|
||||
/*! \internal */
|
||||
readonly property real __handleRadius: outerRadius * 0.15
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
This property determines whether it is possible to change the value of
|
||||
the dial simply by pressing/tapping.
|
||||
|
||||
If \c false, the user must drag to rotate the dial and hence change the
|
||||
value.
|
||||
|
||||
This property is useful for touch devices, where it is easy to
|
||||
accidentally tap while flicking, for example.
|
||||
*/
|
||||
property bool __dragToSet: Settings.hasTouchScreen && Settings.isMobile
|
||||
|
||||
/*!
|
||||
The background of the dial.
|
||||
|
||||
The implicit size of the dial is taken from this component.
|
||||
*/
|
||||
property Component background: Item {
|
||||
id: backgroundItem
|
||||
implicitWidth: backgroundHelper.implicitWidth
|
||||
implicitHeight: backgroundHelper.implicitHeight
|
||||
|
||||
CircularButtonStyleHelper {
|
||||
id: backgroundHelper
|
||||
control: dialStyle.control
|
||||
property color zeroMarkerColor: "#a8a8a8"
|
||||
property color zeroMarkerColorTransparent: "transparent"
|
||||
property real zeroMarkerLength: outerArcLineWidth * 1.25
|
||||
property real zeroMarkerWidth: outerArcLineWidth * 0.3
|
||||
|
||||
smallestAxis: Math.min(backgroundItem.width, backgroundItem.height) - __tickmarkRadius * 4
|
||||
}
|
||||
|
||||
Canvas {
|
||||
id: backgroundCanvas
|
||||
anchors.fill: parent
|
||||
|
||||
readonly property real xCenter: width / 2
|
||||
readonly property real yCenter: height / 2
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
backgroundHelper.paintBackground(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The handle of the dial.
|
||||
|
||||
The handle is automatically positioned within the dial, based on the
|
||||
\l handleInset and the implicit width and height of the handle itself.
|
||||
*/
|
||||
property Component handle: Canvas {
|
||||
implicitWidth: __handleRadius * 2
|
||||
implicitHeight: __handleRadius * 2
|
||||
|
||||
HandleStyleHelper {
|
||||
id: handleHelper
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
handleHelper.paintHandle(ctx, 1, 1, width - 2, height - 2);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
This component defines each individual tickmark. The position of each
|
||||
tickmark is already set; only the
|
||||
\l {Item::implicitWidth}{implicitWidth} and
|
||||
\l {Item::implicitHeight}{implicitHeight} need to be specified.
|
||||
|
||||
Each instance of this component has access to the following properties:
|
||||
|
||||
\table
|
||||
\row \li \c {readonly property int} \b styleData.index
|
||||
\li The index of this tickmark.
|
||||
\row \li \c {readonly property real} \b styleData.value
|
||||
\li The value that this tickmark represents.
|
||||
\endtable
|
||||
*/
|
||||
property Component tickmark: Rectangle {
|
||||
implicitWidth: outerRadius * 0.015 + (styleData.index === 0 || styleData.index === tickmarkCount ? 1 : (styleData.index) / tickmarkCount) * __tickmarkRadius * 0.75
|
||||
implicitHeight: implicitWidth
|
||||
radius: height / 2
|
||||
color: styleData.index === 0 ? "transparent" : Qt.rgba(0, 0, 0, 0.266)
|
||||
antialiasing: true
|
||||
border.width: styleData.index === 0 ? Math.max(1, outerRadius * 0.0075) : 0
|
||||
border.color: Qt.rgba(0, 0, 0, 0.266)
|
||||
}
|
||||
|
||||
/*!
|
||||
This component defines each individual minor tickmark. The position of each
|
||||
minor tickmark is already set; only the
|
||||
\l {Item::implicitWidth}{implicitWidth} and
|
||||
\l {Item::implicitHeight}{implicitHeight} need to be specified.
|
||||
|
||||
Each instance of this component has access to the following properties:
|
||||
|
||||
\table
|
||||
\row \li \c {readonly property int} \b styleData.index
|
||||
\li The index of this tickmark.
|
||||
\row \li \c {readonly property real} \b styleData.value
|
||||
\li The value that this tickmark represents.
|
||||
\endtable
|
||||
|
||||
By default, no minor tickmark is defined.
|
||||
*/
|
||||
property Component minorTickmark
|
||||
|
||||
/*!
|
||||
This defines the text of each tickmark label on the dial.
|
||||
|
||||
Each instance of this component has access to the following properties:
|
||||
|
||||
\table
|
||||
\row \li \c {readonly property int} \b styleData.index
|
||||
\li The index of this label.
|
||||
\row \li \c {readonly property real} \b styleData.value
|
||||
\li The value that this label represents.
|
||||
\endtable
|
||||
|
||||
By default, no label is defined.
|
||||
*/
|
||||
property Component tickmarkLabel
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
implicitWidth: backgroundLoader.implicitWidth
|
||||
implicitHeight: backgroundLoader.implicitHeight
|
||||
|
||||
property alias background: backgroundLoader.item
|
||||
property alias circularTickmarkLabel: circularTickmarkLabel_
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
sourceComponent: dialStyle.background
|
||||
width: outerRadius * 2
|
||||
height: width
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: handleLoader
|
||||
sourceComponent: dialStyle.handle
|
||||
x: backgroundLoader.x + __pos.x - width / 2
|
||||
y: backgroundLoader.y + __pos.y - height / 2
|
||||
|
||||
readonly property point __pos: {
|
||||
var radians = 0;
|
||||
if (control.__wrap) {
|
||||
radians = (control.value - control.minimumValue) /
|
||||
(control.maximumValue - control.minimumValue) *
|
||||
(MathUtils.pi2) + backgroundHelper.zeroAngle;
|
||||
} else {
|
||||
radians = -(Math.PI * 8 - (control.value - control.minimumValue) * 10 *
|
||||
Math.PI / (control.maximumValue - control.minimumValue)) / 6;
|
||||
}
|
||||
|
||||
return MathUtils.centerAlongCircle(backgroundLoader.width / 2, backgroundLoader.height / 2,
|
||||
0, 0, radians, outerRadius - handleInset)
|
||||
}
|
||||
}
|
||||
|
||||
CircularTickmarkLabel {
|
||||
id: circularTickmarkLabel_
|
||||
anchors.fill: backgroundLoader
|
||||
|
||||
minimumValue: control.minimumValue
|
||||
maximumValue: control.maximumValue
|
||||
stepSize: control.stepSize
|
||||
tickmarksVisible: control.tickmarksVisible
|
||||
minimumValueAngle: -150
|
||||
maximumValueAngle: 150
|
||||
tickmarkStepSize: dialStyle.tickmarkStepSize
|
||||
tickmarkInset: dialStyle.tickmarkInset
|
||||
minorTickmarkCount: dialStyle.minorTickmarkCount
|
||||
minorTickmarkInset: dialStyle.minorTickmarkInset
|
||||
labelInset: dialStyle.labelInset
|
||||
labelStepSize: dialStyle.labelStepSize
|
||||
|
||||
style: CircularTickmarkLabelStyle {
|
||||
tickmark: dialStyle.tickmark
|
||||
minorTickmark: dialStyle.minorTickmark
|
||||
tickmarkLabel: dialStyle.tickmarkLabel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype FocusFrameStyle
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
*/
|
||||
Item {
|
||||
property int margin: -3
|
||||
}
|
||||
@@ -0,0 +1,544 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Extras module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Controls.Private 1.0
|
||||
import QtQuick.Extras 1.4
|
||||
import QtQuick.Extras.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype GaugeStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.5
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for Gauge.
|
||||
|
||||
You can create a custom gauge by replacing the following delegates:
|
||||
\list
|
||||
\li \l background
|
||||
\li valueBar
|
||||
\li tickmarkLabel
|
||||
\endlist
|
||||
|
||||
Below, you'll find an example of how to create a temperature gauge that
|
||||
changes color as its value increases:
|
||||
|
||||
\code
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Extras 1.4
|
||||
|
||||
Rectangle {
|
||||
width: 80
|
||||
height: 200
|
||||
|
||||
Timer {
|
||||
running: true
|
||||
repeat: true
|
||||
interval: 2000
|
||||
onTriggered: gauge.value = gauge.value == gauge.maximumValue ? 5 : gauge.maximumValue
|
||||
}
|
||||
|
||||
Gauge {
|
||||
id: gauge
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
|
||||
value: 5
|
||||
Behavior on value {
|
||||
NumberAnimation {
|
||||
duration: 1000
|
||||
}
|
||||
}
|
||||
|
||||
style: GaugeStyle {
|
||||
valueBar: Rectangle {
|
||||
implicitWidth: 16
|
||||
color: Qt.rgba(gauge.value / gauge.maximumValue, 0, 1 - gauge.value / gauge.maximumValue, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
\image gauge-temperature.png
|
||||
The gauge displaying values at various points during the animation.
|
||||
|
||||
\sa {Styling Gauge}
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: gaugeStyle
|
||||
|
||||
/*!
|
||||
The \l Gauge that this style is attached to.
|
||||
*/
|
||||
readonly property Gauge control: __control
|
||||
|
||||
/*!
|
||||
This property holds the value displayed by the gauge as a position in
|
||||
pixels.
|
||||
|
||||
It is useful for custom styling.
|
||||
*/
|
||||
readonly property real valuePosition: control.__panel.valuePosition
|
||||
|
||||
/*!
|
||||
The background of the gauge, displayed behind the \l valueBar.
|
||||
|
||||
By default, no background is defined.
|
||||
*/
|
||||
property Component background
|
||||
|
||||
/*!
|
||||
Each tickmark displayed by the gauge.
|
||||
|
||||
To set the size of the tickmarks, specify an
|
||||
\l {Item::implicitWidth}{implicitWidth} and
|
||||
\l {Item::implicitHeight}{implicitHeight}.
|
||||
|
||||
The widest tickmark will determine the space set aside for all
|
||||
tickmarks. For this reason, the \c implicitWidth of each tickmark
|
||||
should be greater than or equal to that of each minor tickmark. If you
|
||||
need minor tickmarks to have greater widths than the major tickmarks,
|
||||
set the larger width in a child item of the \l minorTickmark component.
|
||||
|
||||
For layouting reasons, each tickmark should have the same
|
||||
\c implicitHeight. If different heights are needed for individual
|
||||
tickmarks, specify those heights in a child item of the component.
|
||||
|
||||
In the example below, we decrease the height of the tickmarks:
|
||||
|
||||
\code
|
||||
tickmark: Item {
|
||||
implicitWidth: 18
|
||||
implicitHeight: 1
|
||||
|
||||
Rectangle {
|
||||
color: "#c8c8c8"
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 3
|
||||
anchors.rightMargin: 3
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
\image gauge-tickmark-example.png Gauge tickmark example
|
||||
|
||||
Each instance of this component has access to the following properties:
|
||||
|
||||
\table
|
||||
\row \li \c {readonly property int} \b styleData.index
|
||||
\li The index of this tickmark.
|
||||
\row \li \c {readonly property real} \b styleData.value
|
||||
\li The value that this tickmark represents.
|
||||
\row \li \c {readonly property real} \b styleData.valuePosition
|
||||
\li The value that this tickmark represents as a position in
|
||||
pixels, with 0 being at the bottom of the gauge.
|
||||
\endtable
|
||||
|
||||
\sa minorTickmark
|
||||
*/
|
||||
property Component tickmark: Item {
|
||||
implicitWidth: Math.round(TextSingleton.height * 1.1)
|
||||
implicitHeight: Math.max(2, Math.round(TextSingleton.height * 0.1))
|
||||
|
||||
Rectangle {
|
||||
color: "#c8c8c8"
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Math.round(TextSingleton.implicitHeight * 0.2)
|
||||
anchors.rightMargin: Math.round(TextSingleton.implicitHeight * 0.2)
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Each minor tickmark displayed by the gauge.
|
||||
|
||||
To set the size of the minor tickmarks, specify an
|
||||
\l {Item::implicitWidth}{implicitWidth} and
|
||||
\l {Item::implicitHeight}{implicitHeight}.
|
||||
|
||||
For layouting reasons, each minor tickmark should have the same
|
||||
\c implicitHeight. If different heights are needed for individual
|
||||
tickmarks, specify those heights in a child item of the component.
|
||||
|
||||
In the example below, we decrease the width of the minor tickmarks:
|
||||
|
||||
\code
|
||||
minorTickmark: Item {
|
||||
implicitWidth: 8
|
||||
implicitHeight: 1
|
||||
|
||||
Rectangle {
|
||||
color: "#cccccc"
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 2
|
||||
anchors.rightMargin: 4
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
\image gauge-minorTickmark-example.png Gauge minorTickmark example
|
||||
|
||||
Each instance of this component has access to the following property:
|
||||
|
||||
\table
|
||||
\row \li \c {readonly property int} \b styleData.index
|
||||
\li The index of this minor tickmark.
|
||||
\row \li \c {readonly property real} \b styleData.value
|
||||
\li The value that this minor tickmark represents.
|
||||
\row \li \c {readonly property real} \b styleData.valuePosition
|
||||
\li The value that this minor tickmark represents as a
|
||||
position in pixels, with 0 being at the bottom of the
|
||||
gauge.
|
||||
\endtable
|
||||
|
||||
\sa tickmark
|
||||
*/
|
||||
property Component minorTickmark: Item {
|
||||
implicitWidth: Math.round(TextSingleton.implicitHeight * 0.65)
|
||||
implicitHeight: Math.max(1, Math.round(TextSingleton.implicitHeight * 0.05))
|
||||
|
||||
Rectangle {
|
||||
color: "#c8c8c8"
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: control.__tickmarkAlignment === Qt.AlignBottom || control.__tickmarkAlignment === Qt.AlignRight
|
||||
? Math.max(3, Math.round(TextSingleton.implicitHeight * 0.2))
|
||||
: 0
|
||||
anchors.rightMargin: control.__tickmarkAlignment === Qt.AlignBottom || control.__tickmarkAlignment === Qt.AlignRight
|
||||
? 0
|
||||
: Math.max(3, Math.round(TextSingleton.implicitHeight * 0.2))
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
This defines the text of each tickmark label on the gauge.
|
||||
|
||||
Each instance of this component has access to the following properties:
|
||||
|
||||
\table
|
||||
\row \li \c {readonly property int} \b styleData.index
|
||||
\li The index of this label.
|
||||
\row \li \c {readonly property real} \b styleData.value
|
||||
\li The value that this label represents.
|
||||
\endtable
|
||||
*/
|
||||
property Component tickmarkLabel: Text {
|
||||
text: control.formatValue(styleData.value)
|
||||
font: control.font
|
||||
color: "#c8c8c8"
|
||||
antialiasing: true
|
||||
}
|
||||
|
||||
/*!
|
||||
The bar that represents the value of the gauge.
|
||||
|
||||
To height of the value bar is automatically resized according to
|
||||
\l {Gauge::value}{value}, and does not need to be specified.
|
||||
|
||||
When a custom valueBar is defined, its
|
||||
\l {Item::implicitWidth}{implicitWidth} property must be set.
|
||||
*/
|
||||
property Component valueBar: Rectangle {
|
||||
color: "#00bbff"
|
||||
implicitWidth: TextSingleton.implicitHeight
|
||||
}
|
||||
|
||||
/*!
|
||||
The bar that represents the foreground of the gauge.
|
||||
|
||||
This component is drawn above every other component.
|
||||
*/
|
||||
property Component foreground: Canvas {
|
||||
readonly property real xCenter: width / 2
|
||||
readonly property real yCenter: height / 2
|
||||
property real shineLength: height * 0.95
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
ctx.reset();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.rect(0, 0, width, height);
|
||||
|
||||
var gradient = ctx.createLinearGradient(0, yCenter, width, yCenter);
|
||||
|
||||
gradient.addColorStop(0, Qt.rgba(1, 1, 1, 0.08));
|
||||
gradient.addColorStop(1, Qt.rgba(1, 1, 1, 0.20));
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
id: panelComponent
|
||||
implicitWidth: control.orientation === Qt.Vertical ? tickmarkLabelBoundsWidth + rawBarWidth : TextSingleton.height * 14
|
||||
implicitHeight: control.orientation === Qt.Vertical ? TextSingleton.height * 14 : tickmarkLabelBoundsWidth + rawBarWidth
|
||||
|
||||
readonly property int tickmarkCount: (control.maximumValue - control.minimumValue) / control.tickmarkStepSize + 1
|
||||
readonly property real tickmarkSpacing: (tickmarkLabelBounds.height - tickmarkWidth * tickmarkCount) / (tickmarkCount - 1)
|
||||
|
||||
property real tickmarkLength: tickmarkColumn.width
|
||||
// Can't deduce this from the column, so we set it from within the first tickmark delegate loader.
|
||||
property real tickmarkWidth: 2
|
||||
|
||||
readonly property real tickmarkOffset: control.orientation === Qt.Vertical ? control.__hiddenText.height / 2 : control.__hiddenText.width / 2
|
||||
|
||||
readonly property real minorTickmarkStep: control.tickmarkStepSize / (control.minorTickmarkCount + 1);
|
||||
|
||||
/*!
|
||||
Returns the marker text that should be displayed based on
|
||||
\a markerPos (\c 0 to \c 1.0).
|
||||
*/
|
||||
function markerTextFromPos(markerPos) {
|
||||
return markerPos * (control.maximumValue - control.minimumValue) + control.minimumValue;
|
||||
}
|
||||
|
||||
readonly property real rawBarWidth: valueBarLoader.item.implicitWidth
|
||||
readonly property real barLength: (control.orientation === Qt.Vertical ? control.height : control.width) - (tickmarkOffset * 2 - 2)
|
||||
|
||||
readonly property real tickmarkLabelBoundsWidth: tickmarkLength + (control.orientation === Qt.Vertical ? control.__hiddenText.width : control.__hiddenText.height)
|
||||
readonly property int valuePosition: valueBarLoader.height
|
||||
|
||||
Item {
|
||||
id: container
|
||||
|
||||
width: control.orientation === Qt.Vertical ? parent.width : parent.height
|
||||
height: control.orientation === Qt.Vertical ? parent.height : parent.width
|
||||
rotation: control.orientation === Qt.Horizontal ? 90 : 0
|
||||
transformOrigin: Item.Center
|
||||
anchors.centerIn: parent
|
||||
|
||||
Item {
|
||||
id: valueBarItem
|
||||
|
||||
x: control.__tickmarkAlignment === Qt.AlignLeft || control.__tickmarkAlignment === Qt.AlignTop ? tickmarkLabelBounds.x + tickmarkLabelBounds.width : 0
|
||||
width: rawBarWidth
|
||||
height: barLength
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
sourceComponent: background
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: valueBarLoader
|
||||
sourceComponent: valueBar
|
||||
|
||||
readonly property real valueAsPercentage: (control.value - control.minimumValue) / (control.maximumValue - control.minimumValue)
|
||||
|
||||
y: Math.round(parent.height - height)
|
||||
height: Math.round(valueAsPercentage * parent.height)
|
||||
}
|
||||
}
|
||||
Item {
|
||||
id: tickmarkLabelBounds
|
||||
|
||||
x: control.__tickmarkAlignment === Qt.AlignLeft || control.__tickmarkAlignment === Qt.AlignTop ? 0 : valueBarItem.width
|
||||
width: tickmarkLabelBoundsWidth
|
||||
height: barLength
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
// We want our items to be laid out from bottom to top, but Column can't do that, so we flip
|
||||
// the whole item containing the tickmarks and labels vertically. Then, we flip each tickmark
|
||||
// and label back again.
|
||||
transform: Rotation {
|
||||
axis.x: 1
|
||||
axis.y: 0
|
||||
axis.z: 0
|
||||
origin.x: tickmarkLabelBounds.width / 2
|
||||
origin.y: tickmarkLabelBounds.height / 2
|
||||
angle: 180
|
||||
}
|
||||
|
||||
Column {
|
||||
id: tickmarkColumn
|
||||
x: control.__tickmarkAlignment === Qt.AlignRight || control.__tickmarkAlignment === Qt.AlignBottom ? 0 : tickmarkLabelBounds.width - width
|
||||
spacing: tickmarkSpacing
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Repeater {
|
||||
id: tickmarkRepeater
|
||||
model: tickmarkCount
|
||||
delegate: Loader {
|
||||
id: tickmarkDelegateLoader
|
||||
|
||||
sourceComponent: gaugeStyle.tickmark
|
||||
transform: Rotation {
|
||||
axis.x: 1
|
||||
axis.y: 0
|
||||
axis.z: 0
|
||||
origin.x: tickmarkDelegateLoader.width / 2
|
||||
origin.y: tickmarkDelegateLoader.height / 2
|
||||
angle: 180
|
||||
}
|
||||
|
||||
onHeightChanged: {
|
||||
if (index == 0)
|
||||
tickmarkWidth = height;
|
||||
}
|
||||
|
||||
readonly property int __index: index
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias index: tickmarkDelegateLoader.__index
|
||||
readonly property real value: (index / (tickmarkCount - 1)) * (control.maximumValue - control.minimumValue) + control.minimumValue
|
||||
readonly property int valuePosition: Math.round(tickmarkDelegateLoader.y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Doesn't need to be in a column, since we assume that the major tickmarks will always be longer than us.
|
||||
Repeater {
|
||||
id: minorTickmarkRepeater
|
||||
model: (tickmarkCount - 1) * control.minorTickmarkCount
|
||||
delegate: Loader {
|
||||
id: minorTickmarkDelegateLoader
|
||||
|
||||
x: control.__tickmarkAlignment === Qt.AlignRight || control.__tickmarkAlignment === Qt.AlignBottom ? 0 : tickmarkLabelBounds.width - width
|
||||
y: {
|
||||
var tickmarkWidthOffset = Math.floor(index / control.minorTickmarkCount) * tickmarkWidth + tickmarkWidth;
|
||||
var relativePosition = (index % control.minorTickmarkCount + 1) * (tickmarkSpacing / (control.minorTickmarkCount + 1));
|
||||
var clusterOffset = Math.floor(index / control.minorTickmarkCount) * tickmarkSpacing;
|
||||
// We assume that each minorTickmark's height is the same.
|
||||
return clusterOffset + tickmarkWidthOffset + relativePosition - height / 2;
|
||||
}
|
||||
|
||||
transform: Rotation {
|
||||
axis.x: 1
|
||||
axis.y: 0
|
||||
axis.z: 0
|
||||
origin.x: minorTickmarkDelegateLoader.width / 2
|
||||
origin.y: minorTickmarkDelegateLoader.height / 2
|
||||
angle: 180
|
||||
}
|
||||
|
||||
sourceComponent: gaugeStyle.minorTickmark
|
||||
|
||||
readonly property int __index: index
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias index: minorTickmarkDelegateLoader.__index
|
||||
readonly property real value: {
|
||||
var tickmarkIndex = Math.floor(index / control.minorTickmarkCount);
|
||||
return index * minorTickmarkStep + minorTickmarkStep * tickmarkIndex + minorTickmarkStep + control.minimumValue;
|
||||
}
|
||||
readonly property int valuePosition: Math.round(minorTickmarkDelegateLoader.y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: tickmarkLabelItem
|
||||
x: control.__tickmarkAlignment === Qt.AlignRight || control.__tickmarkAlignment === Qt.AlignBottom
|
||||
? tickmarkLength
|
||||
: tickmarkLabelBounds.width - tickmarkLength - width
|
||||
width: control.__hiddenText.width
|
||||
// Use the bar height instead of the container's, as the labels seem to be translated by 1 when we
|
||||
// flip the control vertically, and this fixes that.
|
||||
height: parent.height
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Repeater {
|
||||
id: tickmarkTextRepeater
|
||||
model: tickmarkCount
|
||||
delegate: Item {
|
||||
x: {
|
||||
if (control.orientation === Qt.Vertical)
|
||||
return 0;
|
||||
|
||||
// Align the text to the edge of the tickmarks.
|
||||
return ((width - height) / 2) * (control.__tickmarkAlignment === Qt.AlignBottom ? -1 : 1);
|
||||
}
|
||||
y: index * labelDistance - height / 2
|
||||
|
||||
width: control.__hiddenText.width
|
||||
height: control.__hiddenText.height
|
||||
|
||||
transformOrigin: Item.Center
|
||||
rotation: control.orientation === Qt.Vertical ? 0 : 90
|
||||
|
||||
readonly property real labelDistance: tickmarkLabelBounds.height / (tickmarkCount - 1)
|
||||
|
||||
Loader {
|
||||
id: tickmarkTextRepeaterDelegate
|
||||
|
||||
x: {
|
||||
if (control.orientation === Qt.Horizontal) {
|
||||
return parent.width / 2 - width / 2;
|
||||
}
|
||||
|
||||
return control.__tickmarkAlignment === Qt.AlignRight || control.__tickmarkAlignment === Qt.AlignBottom
|
||||
? 0
|
||||
: parent.width - width;
|
||||
}
|
||||
|
||||
transform: Rotation {
|
||||
axis.x: 1
|
||||
axis.y: 0
|
||||
axis.z: 0
|
||||
origin.x: tickmarkTextRepeaterDelegate.width / 2
|
||||
origin.y: tickmarkTextRepeaterDelegate.height / 2
|
||||
angle: 180
|
||||
}
|
||||
|
||||
sourceComponent: tickmarkLabel
|
||||
|
||||
readonly property int __index: index
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias index: tickmarkTextRepeaterDelegate.__index
|
||||
readonly property real value: markerTextFromPos(index / (tickmarkTextRepeater.count - 1))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
id: foregroundLoader
|
||||
sourceComponent: foreground
|
||||
anchors.fill: valueBarItem
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype GroupBoxStyle
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\ingroup controlsstyling
|
||||
\since 5.1
|
||||
*/
|
||||
Style {
|
||||
|
||||
/*! The \l GroupBox this style is attached to. */
|
||||
readonly property GroupBox control: __control
|
||||
|
||||
/*! The margin from the content item to the groupbox. */
|
||||
padding {
|
||||
top: (control.title.length > 0 || control.checkable ? TextSingleton.implicitHeight : 0) + 10
|
||||
left: 8
|
||||
right: 8
|
||||
bottom: 6
|
||||
}
|
||||
|
||||
/*! The title text color. */
|
||||
property color textColor: SystemPaletteSingleton.text(control.enabled)
|
||||
|
||||
/*! The check box. */
|
||||
property Component checkbox: Item {
|
||||
implicitWidth: 18
|
||||
implicitHeight: 18
|
||||
BorderImage {
|
||||
anchors.fill: parent
|
||||
source: "images/editbox.png"
|
||||
border.top: 6
|
||||
border.bottom: 6
|
||||
border.left: 6
|
||||
border.right: 6
|
||||
}
|
||||
Rectangle {
|
||||
height: 16
|
||||
width: 16
|
||||
antialiasing: true
|
||||
visible: control.checked
|
||||
color: "#666"
|
||||
radius: 1
|
||||
anchors.margins: 4
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 3
|
||||
anchors.bottomMargin: 5
|
||||
border.color: "#222"
|
||||
opacity: control.enabled ? 1 : 0.5
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
color: "transparent"
|
||||
border.color: "#33ffffff"
|
||||
}
|
||||
}
|
||||
BorderImage {
|
||||
anchors.fill: parent
|
||||
anchors.margins: -1
|
||||
source: "images/focusframe.png"
|
||||
visible: control.activeFocus
|
||||
border.left: 4
|
||||
border.right: 4
|
||||
border.top: 4
|
||||
border.bottom: 4
|
||||
}
|
||||
}
|
||||
|
||||
/*! The groupbox frame. */
|
||||
property Component panel: Item {
|
||||
anchors.fill: parent
|
||||
Loader {
|
||||
id: checkboxloader
|
||||
anchors.left: parent.left
|
||||
sourceComponent: control.checkable ? checkbox : null
|
||||
anchors.verticalCenter: label.verticalCenter
|
||||
width: item ? item.implicitWidth : 0
|
||||
}
|
||||
|
||||
Text {
|
||||
id: label
|
||||
anchors.top: parent.top
|
||||
anchors.left: checkboxloader.right
|
||||
anchors.margins: 4
|
||||
text: control.title
|
||||
color: textColor
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
}
|
||||
|
||||
BorderImage {
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: padding.top - 7
|
||||
source: "images/groupbox.png"
|
||||
border.left: 4
|
||||
border.right: 4
|
||||
border.top: 4
|
||||
border.bottom: 4
|
||||
visible: !control.flat
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Extras module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
import QtQuick.Extras 1.4
|
||||
|
||||
Style {
|
||||
id: handleStyle
|
||||
property alias handleColorTop: __helper.handleColorTop
|
||||
property alias handleColorBottom: __helper.handleColorBottom
|
||||
property alias handleColorBottomStop: __helper.handleColorBottomStop
|
||||
|
||||
HandleStyleHelper {
|
||||
id: __helper
|
||||
}
|
||||
|
||||
property Component handle: Item {
|
||||
implicitWidth: 50
|
||||
implicitHeight: 50
|
||||
|
||||
Canvas {
|
||||
id: handleCanvas
|
||||
anchors.fill: parent
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
__helper.paintHandle(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property Component panel: Item {
|
||||
Loader {
|
||||
id: handleLoader
|
||||
sourceComponent: handle
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Extras module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
|
||||
QtObject {
|
||||
id: handleStyleHelper
|
||||
|
||||
property color handleColorTop: "#969696"
|
||||
property color handleColorBottom: Qt.rgba(0.9, 0.9, 0.9, 0.298)
|
||||
property real handleColorBottomStop: 0.7
|
||||
|
||||
property color handleRingColorTop: "#b0b0b0"
|
||||
property color handleRingColorBottom: "transparent"
|
||||
|
||||
/*!
|
||||
If \a ctx is the only argument, this is equivalent to calling
|
||||
paintHandle(\c ctx, \c 0, \c 0, \c ctx.canvas.width, \c ctx.canvas.height).
|
||||
*/
|
||||
function paintHandle(ctx, handleX, handleY, handleWidth, handleHeight) {
|
||||
ctx.reset();
|
||||
|
||||
if (handleWidth < 0)
|
||||
return;
|
||||
|
||||
if (arguments.length == 1) {
|
||||
handleX = 0;
|
||||
handleY = 0;
|
||||
handleWidth = ctx.canvas.width;
|
||||
handleHeight = ctx.canvas.height;
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
var gradient = ctx.createRadialGradient(handleX, handleY, 0,
|
||||
handleX, handleY, handleWidth * 1.5);
|
||||
gradient.addColorStop(0, handleColorTop);
|
||||
gradient.addColorStop(handleColorBottomStop, handleColorBottom);
|
||||
ctx.ellipse(handleX, handleY, handleWidth, handleHeight);
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fill();
|
||||
|
||||
/* Draw the ring gradient around the handle. */
|
||||
// Clip first, so we only draw inside the ring.
|
||||
ctx.beginPath();
|
||||
ctx.ellipse(handleX, handleY, handleWidth, handleHeight);
|
||||
ctx.ellipse(handleX + 2, handleY + 2, handleWidth - 4, handleHeight - 4);
|
||||
ctx.clip();
|
||||
|
||||
ctx.beginPath();
|
||||
gradient = ctx.createLinearGradient(handleX + handleWidth / 2, handleY,
|
||||
handleX + handleWidth / 2, handleY + handleHeight);
|
||||
gradient.addColorStop(0, handleRingColorTop);
|
||||
gradient.addColorStop(1, handleRingColorBottom);
|
||||
ctx.ellipse(handleX, handleY, handleWidth, handleHeight);
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype MenuBarStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.3
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for MenuBar.
|
||||
|
||||
\note Styling menu bars may not be supported on platforms using native menu bars
|
||||
through their QPA plugin.
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: root
|
||||
|
||||
/*!
|
||||
\qmlmethod string MenuBarStyle::formatMnemonic(string text, bool underline = false)
|
||||
Returns a formatted string to render mnemonics for a given menu item \a text.
|
||||
|
||||
The mnemonic character is prefixed by an ampersand in the original string.
|
||||
|
||||
Passing \c true for \e underline will underline the mnemonic character (e.g.,
|
||||
\c formatMnemonic("&File", true) will return \c "<u>F</u>ile"). Passing \c false
|
||||
for \a underline will return the plain text form (e.g., \c formatMnemonic("&File", false)
|
||||
will return \c "File").
|
||||
|
||||
\sa Label
|
||||
*/
|
||||
function formatMnemonic(text, underline) {
|
||||
return underline ? StyleHelpers.stylizeMnemonics(text) : StyleHelpers.removeMnemonics(text)
|
||||
}
|
||||
|
||||
/*! The background for the full menu bar.
|
||||
|
||||
The background will be extended to the full containing window width.
|
||||
Its height will always fit all of the menu bar items. The final size
|
||||
will include the paddings.
|
||||
*/
|
||||
property Component background: Rectangle {
|
||||
color: "#dcdcdc"
|
||||
implicitHeight: 20
|
||||
}
|
||||
|
||||
/*! The menu bar item.
|
||||
|
||||
\target styleData properties
|
||||
This item has to be configured using the \b styleData object which is in scope,
|
||||
and contains the following read-only properties:
|
||||
\table
|
||||
\row \li \b {styleData.index} : int \li The index of the menu item in its menu.
|
||||
\row \li \b {styleData.selected} : bool \li \c true if the menu item is selected.
|
||||
\row \li \b {styleData.open} : bool \li \c true when the pull down menu is open.
|
||||
\row \li \b {styleData.text} : string \li The menu bar item's text.
|
||||
\row \li \b {styleData.underlineMnemonic} : bool \li When \c true, the style should underline the menu item's label mnemonic.
|
||||
\endtable
|
||||
|
||||
*/
|
||||
property Component itemDelegate: Rectangle {
|
||||
implicitWidth: text.width + 12
|
||||
implicitHeight: text.height + 4
|
||||
color: styleData.enabled && styleData.open ? "#49d" : "transparent"
|
||||
|
||||
Text {
|
||||
id: text
|
||||
font: root.font
|
||||
text: formatMnemonic(styleData.text, styleData.underlineMnemonic)
|
||||
anchors.centerIn: parent
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
color: styleData.open ? "white" : SystemPaletteSingleton.windowText(control.enabled && styleData.enabled)
|
||||
}
|
||||
}
|
||||
|
||||
/*! The style component for the menubar's own menus and their submenus.
|
||||
|
||||
\sa {MenuStyle}
|
||||
*/
|
||||
property Component menuStyle: MenuStyle {
|
||||
font: root.font
|
||||
}
|
||||
|
||||
/*!
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
The font of the control.
|
||||
*/
|
||||
property font font
|
||||
|
||||
/*! \internal */
|
||||
property bool __isNative: true
|
||||
}
|
||||
@@ -0,0 +1,477 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Window 2.1
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype MenuStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.3
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for Menu.
|
||||
|
||||
\target styleData properties
|
||||
The \b styleData object contains the following read-only properties:
|
||||
\table
|
||||
\row \li \b {styleData.index} : int \li The index of the menu item in its menu.
|
||||
\row \li \b {styleData.type} : enumeration \li The type of menu item. See below for possible values.
|
||||
\row \li \b {styleData.selected} : bool \li \c true if the menu item is selected.
|
||||
\row \li \b {styleData.pressed} : bool \li \c true if the menu item is pressed. Available since 5.4.
|
||||
\row \li \b {styleData.text} : string \li The menu item's text, or title if it's a submenu.
|
||||
\row \li \b {styleData.underlineMnemonic} : bool \li Whether the style should underline the menu item's label mnemonic.
|
||||
\row \li \b {styleData.shortcut} : string \li The text for the menu item's shortcut.
|
||||
\row \li \b {styleData.iconSource} : url \li The source URL to the menu item's icon. Undefined if it has no icon.
|
||||
\row \li \b {styleData.enabled} : bool \li \c true if the menu item is enabled.
|
||||
\row \li \b {styleData.checkable} : bool \li \c true if the menu item is checkable.
|
||||
\row \li \b {styleData.exclusive} : bool \li \c true if the menu item is checkable, and it's part of an \l ExclusiveGroup.
|
||||
\row \li \b {styleData.checked} : bool \li \c true if the menu item is checkable and currently checked.
|
||||
\row \li \b {styleData.scrollerDirection} : enumeration \li If the menu item is a scroller, its pointing direction.
|
||||
Valid values are \c Qt.UpArrow, \c Qt.DownArrow, and \c Qt.NoArrow.
|
||||
\endtable
|
||||
|
||||
The valid values for \b {styleData.type} are:
|
||||
\list
|
||||
\li MenuItemType.Item
|
||||
\li MenuItemType.Menu
|
||||
\li MenuItemType.Separator
|
||||
\li MenuItemType.ScrollIndicator
|
||||
\endlist
|
||||
|
||||
\note Styling menus may not be supported on platforms using native menus
|
||||
through their QPA plugin.
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: styleRoot
|
||||
|
||||
padding {
|
||||
top: 1
|
||||
bottom: 1
|
||||
left: 1
|
||||
right: 1
|
||||
}
|
||||
|
||||
/*! The amount of pixels by which a submenu popup overlaps horizontally its parent menu. */
|
||||
property int submenuOverlap: 1
|
||||
|
||||
/*! The number of milliseconds to wait before opening a submenu. */
|
||||
property int submenuPopupDelay: 200
|
||||
|
||||
/*!
|
||||
\qmlmethod string MenuStyle::formatMnemonic(string text, bool underline = false)
|
||||
Returns a rich-text string to render mnemonics for a given menu item \a text.
|
||||
|
||||
The mnemonic character is prefixed by an ampersand in the original string.
|
||||
|
||||
Passing \c true for \a underline will underline the mnemonic character (e.g.,
|
||||
\c formatMnemonic("&Open...", true) will return \c "<u>O</u>pen..."). Passing \c false
|
||||
for \a underline will return the plain text form (e.g., \c formatMnemonic("&Open...", false)
|
||||
will return \c "Open...").
|
||||
|
||||
\sa Label
|
||||
*/
|
||||
function formatMnemonic(text, underline) {
|
||||
return underline ? StyleHelpers.stylizeMnemonics(text) : StyleHelpers.removeMnemonics(text)
|
||||
}
|
||||
|
||||
/*! The background frame for the menu popup.
|
||||
|
||||
The \l Menu will resize the frame to its contents plus the padding.
|
||||
*/
|
||||
property Component frame: Rectangle {
|
||||
color: styleRoot.__backgroundColor
|
||||
border { width: 1; color: styleRoot.__borderColor }
|
||||
}
|
||||
|
||||
/*! \qmlproperty Object MenuStyle::itemDelegate
|
||||
|
||||
The object containing the menu item subcontrol components. These subcontrols are used
|
||||
for normal menu items only, i.e. not for separators or scroll indicators.
|
||||
|
||||
The subcontrols are:
|
||||
|
||||
\list
|
||||
\li \b {itemDelegate.background} : Component
|
||||
|
||||
The menu item background component.
|
||||
|
||||
Its appearance generally changes with \l {styleData properties} {styleData.selected}
|
||||
and \l {styleData properties} {styleData.enabled}.
|
||||
|
||||
The default implementation shows only when the item is enabled and selected. It remains
|
||||
invisible otherwise.
|
||||
|
||||
\li \b {itemDelegate.label} : Component
|
||||
|
||||
Component for the actual text label.
|
||||
|
||||
The text itself is fetched from \l {styleData properties} {styleData.text}, and its appearance should depend
|
||||
on \l {styleData properties} {styleData.enabled} and \l {styleData properties} {styleData.selected}.
|
||||
|
||||
If \l {styleData properties} {styleData.underlineMnemonic} is true, the label should underline its mnemonic
|
||||
character. \l formatMnemonic provides the default formatting.
|
||||
|
||||
\li \b {itemDelegate.submenuIndicator} : Component
|
||||
|
||||
It indicates that the current menu item is a submenu.
|
||||
|
||||
Only used when \l {styleData properties} {styleData.type} equals \c MenuItemType.Menu.
|
||||
|
||||
\li \b {itemDelegate.shortcut} : Component
|
||||
|
||||
Displays the shortcut attached to the menu item.
|
||||
|
||||
Only used when \l {styleData properties} {styleData.shortcut} is not empty.
|
||||
|
||||
\li \b {itemDelegate.checkmarkIndicator} : Component
|
||||
|
||||
Will be used when \l {styleData properties} {styleData.checkable} is \c true and its appearance
|
||||
may depend on \l {styleData properties} {styleData.exclusive}, i.e., whether it will behave like a
|
||||
checkbox or a radio button. Use \l {styleData properties} {styleData.checked} for the checked state.
|
||||
\endlist
|
||||
|
||||
\note This property cannot be overwritten although all of the subcontrol properties can.
|
||||
*/
|
||||
property alias itemDelegate: internalMenuItem
|
||||
|
||||
MenuItemSubControls {
|
||||
id: internalMenuItem
|
||||
|
||||
background: Rectangle {
|
||||
visible: styleData.selected && styleData.enabled
|
||||
gradient: Gradient {
|
||||
id: selectedGradient
|
||||
GradientStop { color: Qt.lighter(__selectedBackgroundColor, 1.3); position: -0.2 }
|
||||
GradientStop { color: __selectedBackgroundColor; position: 1.4 }
|
||||
}
|
||||
|
||||
border.width: 1
|
||||
border.color: Qt.darker(__selectedBackgroundColor, 1)
|
||||
antialiasing: true
|
||||
}
|
||||
|
||||
label: Text {
|
||||
text: formatMnemonic(styleData.text, styleData.underlineMnemonic)
|
||||
color: __currentTextColor
|
||||
font: styleRoot.font
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
}
|
||||
|
||||
submenuIndicator: Text {
|
||||
text: __mirrored ? "\u25c2" : "\u25b8" // BLACK LEFT/RIGHT-POINTING SMALL TRIANGLE
|
||||
font: styleRoot.font
|
||||
color: __currentTextColor
|
||||
style: styleData.selected ? Text.Normal : Text.Raised
|
||||
styleColor: Qt.lighter(color, 4)
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
}
|
||||
|
||||
shortcut: Text {
|
||||
text: styleData.shortcut
|
||||
font {
|
||||
bold: styleRoot.font.bold
|
||||
capitalization: styleRoot.font.capitalization
|
||||
family: styleRoot.font.family
|
||||
italic: styleRoot.font.italic
|
||||
letterSpacing: styleRoot.font.letterSpacing
|
||||
pixelSize: styleRoot.font.pixelSize * 0.9
|
||||
strikeout: styleRoot.font.strikeout
|
||||
underline: styleRoot.font.underline
|
||||
weight: styleRoot.font.weight
|
||||
wordSpacing: styleRoot.font.wordSpacing
|
||||
}
|
||||
color: __currentTextColor
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
}
|
||||
|
||||
checkmarkIndicator: Loader {
|
||||
sourceComponent: styleData.exclusive ? exclusiveCheckMark : nonExclusiveCheckMark
|
||||
Component {
|
||||
id: exclusiveCheckMark
|
||||
Rectangle {
|
||||
x: 1
|
||||
width: 10
|
||||
height: 10
|
||||
color: "white"
|
||||
border.color: "gray"
|
||||
antialiasing: true
|
||||
radius: height/2
|
||||
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
visible: styleData.checked
|
||||
width: 4
|
||||
height: 4
|
||||
color: "#666"
|
||||
border.color: "#222"
|
||||
antialiasing: true
|
||||
radius: height/2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: nonExclusiveCheckMark
|
||||
BorderImage {
|
||||
width: 12
|
||||
height: 12
|
||||
source: "images/editbox.png"
|
||||
border.top: 6
|
||||
border.bottom: 6
|
||||
border.left: 6
|
||||
border.right: 6
|
||||
|
||||
Rectangle {
|
||||
antialiasing: true
|
||||
visible: styleData.checked
|
||||
color: "#666"
|
||||
radius: 1
|
||||
anchors.margins: 4
|
||||
anchors.fill: parent
|
||||
border.color: "#222"
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
color: "transparent"
|
||||
border.color: "#33ffffff"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! Component for the separator menu item.
|
||||
|
||||
Will be used when \l {styleData properties} {styleData.type} equals \c MenuItemType.Separator.
|
||||
*/
|
||||
property Component separator: Item {
|
||||
implicitHeight: styleRoot.font.pixelSize / 2
|
||||
Rectangle {
|
||||
width: parent.width - 2
|
||||
height: 1
|
||||
x: 1
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: "darkgray"
|
||||
}
|
||||
}
|
||||
|
||||
/*! Component for the scroll indicator menu item.
|
||||
|
||||
Will be used when \l {styleData properties} {styleData.type} equals \c MenuItemType.ScrollIndicator.
|
||||
Its appearance should follow \l {styleData properties} {styleData.scrollerDirection}.
|
||||
|
||||
This is the item added at the top and bottom of the menu popup when its contents won't fit the screen
|
||||
to indicate more content is available in the direction of the arrow.
|
||||
*/
|
||||
property Component scrollIndicator: Image {
|
||||
anchors.centerIn: parent
|
||||
source: styleData.scrollerDirection === Qt.UpArrow ? "images/arrow-up.png" : "images/arrow-down.png"
|
||||
}
|
||||
|
||||
/*!
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
The font of the control.
|
||||
*/
|
||||
property font font
|
||||
|
||||
/*! \internal */
|
||||
property string __menuItemType: "menuitem"
|
||||
|
||||
/*! \internal
|
||||
The menu popup frame background color.
|
||||
|
||||
This is set to be a uniform background. If you want a gradient or a pixmap,
|
||||
you should override \l frame.
|
||||
|
||||
\sa frame, borderColor
|
||||
*/
|
||||
property color __backgroundColor: "#dcdcdc"
|
||||
|
||||
/*! \internal
|
||||
The menu popup frame border color.
|
||||
|
||||
The border width is set to 1 pixel. Override \l frame if you want a larger border.
|
||||
|
||||
\sa frame, backgroundColor
|
||||
*/
|
||||
property color __borderColor: "darkgray"
|
||||
|
||||
/*! \internal
|
||||
The maximum height for a popup before it will show scrollers.
|
||||
*/
|
||||
property int __maxPopupHeight: 600
|
||||
|
||||
/*! \internal
|
||||
The menu item background color when selected.
|
||||
|
||||
This property is provided for convenience and only sets the color.
|
||||
It does not change the style in any other way.
|
||||
*/
|
||||
property color __selectedBackgroundColor: "#49d"
|
||||
|
||||
/*! \internal
|
||||
The menu item label color.
|
||||
|
||||
When set, keyboard shorcuts get the same color as the item's text.
|
||||
|
||||
\sa selectedLabelColor, disabledLabelColor
|
||||
*/
|
||||
property color __labelColor: "#444"
|
||||
|
||||
/*! \internal
|
||||
The menu item label color when selected.
|
||||
|
||||
\sa labelColor, selectedLabelColor
|
||||
*/
|
||||
property color __selectedLabelColor: "white"
|
||||
|
||||
/*! \internal
|
||||
The menu item label color when disabled.
|
||||
|
||||
\sa labelColor, disabledLabelColor
|
||||
*/
|
||||
property color __disabledLabelColor: "gray"
|
||||
|
||||
|
||||
/*! \internal */
|
||||
readonly property bool __mirrored: Qt.application.layoutDirection === Qt.RightToLeft
|
||||
|
||||
/*! \internal
|
||||
The margin between the frame and the menu item label's left side.
|
||||
|
||||
Generally, this should be large enough to fit optional checkmarks on
|
||||
the label's left side.
|
||||
*/
|
||||
property int __leftLabelMargin: 18
|
||||
|
||||
/*! \internal
|
||||
The margin between the menu item label's right side and the frame. */
|
||||
property int __rightLabelMargin: 12
|
||||
|
||||
/*! \internal
|
||||
The minimum spacing between the menu item label's text right side and any
|
||||
element located on its right (submenu indicator or shortcut).
|
||||
*/
|
||||
property int __minRightLabelSpacing: 28
|
||||
|
||||
/*! \internal */
|
||||
property Component __scrollerStyle: null
|
||||
|
||||
/*! \internal
|
||||
The menu item contents itself.
|
||||
|
||||
The default implementation uses \l MenuItemStyle.
|
||||
*/
|
||||
property Component menuItemPanel: Item {
|
||||
id: panel
|
||||
|
||||
property QtObject __styleData: styleData
|
||||
/*! \internal
|
||||
The current color of the text label.
|
||||
|
||||
Use this if you're overriding e.g. \l shortcutIndicator to keep the color matched
|
||||
with \l label, or to derive new colors from it.
|
||||
*/
|
||||
property color currentTextColor: !styleData.enabled ? __disabledLabelColor :
|
||||
styleData.selected ? __selectedLabelColor : __labelColor
|
||||
|
||||
implicitWidth: Math.max((parent ? parent.width : 0),
|
||||
Math.round(__leftLabelMargin + labelLoader.width + __rightLabelMargin +
|
||||
(rightIndicatorLoader.active ? __minRightLabelSpacing + rightIndicatorLoader.width : 0)))
|
||||
implicitHeight: Math.round(styleData.type === MenuItemType.Separator ? separatorLoader.implicitHeight :
|
||||
!!styleData.scrollerDirection ? styleRoot.font.pixelSize * 0.75 : labelLoader.height + 4)
|
||||
|
||||
Loader {
|
||||
property alias styleData: panel.__styleData
|
||||
property alias __currentTextColor: panel.currentTextColor
|
||||
anchors.fill: parent
|
||||
sourceComponent: itemDelegate.background
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: separatorLoader
|
||||
property alias styleData: panel.__styleData
|
||||
property alias __currentTextColor: panel.currentTextColor
|
||||
anchors.fill: parent
|
||||
sourceComponent: separator
|
||||
active: styleData.type === MenuItemType.Separator
|
||||
}
|
||||
|
||||
Loader {
|
||||
property alias styleData: panel.__styleData
|
||||
property alias __currentTextColor: panel.currentTextColor
|
||||
x: __mirrored ? parent.width - width - 4 : 4
|
||||
anchors.verticalCenterOffset: -1
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
active: __menuItemType === "menuitem" && styleData.checkable
|
||||
sourceComponent: itemDelegate.checkmarkIndicator
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: labelLoader
|
||||
readonly property real offset: __menuItemType === "menuitem" ? __leftLabelMargin : 6
|
||||
property alias styleData: panel.__styleData
|
||||
property alias __currentTextColor: panel.currentTextColor
|
||||
x: __mirrored ? parent.width - width - offset : offset
|
||||
y: 1
|
||||
active: styleData.type !== MenuItemType.Separator
|
||||
sourceComponent: itemDelegate.label
|
||||
baselineOffset: item ? item.baselineOffset : 0.0
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: rightIndicatorLoader
|
||||
property alias styleData: panel.__styleData
|
||||
property alias __currentTextColor: panel.currentTextColor
|
||||
active: styleData.type === MenuItemType.Menu || styleData.shortcut !== ""
|
||||
sourceComponent: styleData.type === MenuItemType.Menu ? itemDelegate.submenuIndicator : itemDelegate.shortcut
|
||||
LayoutMirroring.enabled: __mirrored
|
||||
baselineOffset: item ? item.baselineOffset : 0.0
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: 6
|
||||
baseline: !styleData.isSubmenu ? labelLoader.baseline : undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,404 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Extras module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Controls.Private 1.0
|
||||
import QtQuick.Extras 1.4
|
||||
import QtQuick.Extras.Private 1.0
|
||||
import QtQuick.Extras.Private.CppUtils 1.0
|
||||
|
||||
/*!
|
||||
\qmltype PieMenuStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.5
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for PieMenu.
|
||||
|
||||
PieMenuStyle is a style for PieMenu that draws each section of the menu as a
|
||||
filled "slice".
|
||||
|
||||
You can create a custom pie menu by replacing the following delegates:
|
||||
\list
|
||||
\li \l background
|
||||
\li \l cancel
|
||||
\li \l menuItem
|
||||
\li \l title
|
||||
\endlist
|
||||
|
||||
To customize the appearance of each menuItem without having to define your
|
||||
own, you can use the \l backgroundColor and \l selectionColor properties.
|
||||
To customize the drop shadow, use the \l shadowColor, \l shadowRadius and
|
||||
\l shadowSpread properties.
|
||||
|
||||
Icons that are too large for the section that they are in will be scaled
|
||||
down appropriately.
|
||||
|
||||
To style individual sections of the menu, use the menuItem component:
|
||||
\code
|
||||
PieMenuStyle {
|
||||
shadowRadius: 0
|
||||
|
||||
menuItem: Item {
|
||||
id: item
|
||||
rotation: -90 + sectionCenterAngle(styleData.index)
|
||||
|
||||
Rectangle {
|
||||
width: parent.height * 0.2
|
||||
height: width
|
||||
color: "darkorange"
|
||||
radius: width / 2
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Text {
|
||||
id: textItem
|
||||
text: control.menuItems[styleData.index].text
|
||||
anchors.centerIn: parent
|
||||
color: control.currentIndex === styleData.index ? "red" : "white"
|
||||
rotation: -item.rotation
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
\image piemenu-menuitem-example.png A custom PieMenu
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: pieMenuStyle
|
||||
|
||||
/*!
|
||||
The \l PieMenu that this style is attached to.
|
||||
*/
|
||||
readonly property PieMenu control: __control
|
||||
|
||||
/*! The background color. */
|
||||
property color backgroundColor: Qt.rgba(0.6, 0.6, 0.6, 0.66)
|
||||
|
||||
/*! The selection color. */
|
||||
property color selectionColor: "#eee"
|
||||
|
||||
/*!
|
||||
The shadow color.
|
||||
|
||||
\sa DropShadow
|
||||
*/
|
||||
property color shadowColor: Qt.rgba(0, 0, 0, 0.26)
|
||||
|
||||
/*!
|
||||
The shadow radius.
|
||||
|
||||
\sa DropShadow
|
||||
*/
|
||||
property real shadowRadius: 10
|
||||
|
||||
/*!
|
||||
The shadow spread.
|
||||
|
||||
\sa DropShadow
|
||||
*/
|
||||
property real shadowSpread: 0.3
|
||||
|
||||
/*!
|
||||
The distance from the center of the menu to the outer edge of the menu.
|
||||
|
||||
\sa cancelRadius
|
||||
*/
|
||||
readonly property real radius: Math.min(control.width, control.height) * 0.5
|
||||
|
||||
/*!
|
||||
The radius of the area that is used to cancel the menu.
|
||||
|
||||
\sa radius
|
||||
*/
|
||||
property real cancelRadius: radius * 0.4
|
||||
|
||||
/*!
|
||||
The angle (in degrees) at which the first menu item will be drawn.
|
||||
|
||||
The absolute range formed by \a startAngle and \l endAngle must be
|
||||
less than or equal to \c 360 degrees.
|
||||
|
||||
Menu items are displayed clockwise when \a startAngle is less than
|
||||
\l endAngle, otherwise they are displayed anti-clockwise.
|
||||
|
||||
\sa endAngle
|
||||
*/
|
||||
property real startAngle: -90
|
||||
|
||||
/*!
|
||||
The angle (in degrees) at which the last menu item will be drawn.
|
||||
|
||||
The absolute range formed by \l startAngle and \a endAngle must be
|
||||
less than or equal to \c 360 degrees.
|
||||
|
||||
Menu items are displayed clockwise when \l startAngle is less than
|
||||
\a endAngle, otherwise they are displayed anti-clockwise.
|
||||
|
||||
\sa startAngle
|
||||
*/
|
||||
property real endAngle: 90
|
||||
|
||||
/*!
|
||||
\qmlmethod real PieMenuStyle::sectionStartAngle(int itemIndex)
|
||||
Returns the start of the section at \a itemIndex as an angle in degrees.
|
||||
*/
|
||||
function sectionStartAngle(itemIndex) {
|
||||
return MathUtils.radToDegOffset(control.__protectedScope.sectionStartAngle(itemIndex));
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod real PieMenuStyle::sectionCenterAngle(int itemIndex)
|
||||
Returns the center of the section at \a itemIndex as an angle in
|
||||
degrees.
|
||||
*/
|
||||
function sectionCenterAngle(itemIndex) {
|
||||
return MathUtils.radToDegOffset(control.__protectedScope.sectionCenterAngle(itemIndex));
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod real PieMenuStyle::sectionEndAngle(int itemIndex)
|
||||
Returns the end of the section at \a itemIndex as an angle in degrees.
|
||||
*/
|
||||
function sectionEndAngle(itemIndex) {
|
||||
return MathUtils.radToDegOffset(control.__protectedScope.sectionEndAngle(itemIndex));
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
The distance in pixels from the center of each menu item's icon to the
|
||||
center of the menu. A higher value means that the icons will be further
|
||||
from the center of the menu.
|
||||
*/
|
||||
readonly property real __iconOffset: cancelRadius + ((radius - cancelRadius) / 2)
|
||||
|
||||
/*! \internal */
|
||||
readonly property real __selectableRadius: radius - cancelRadius
|
||||
|
||||
/*! \internal */
|
||||
property int __implicitWidth: Math.round(TextSingleton.implicitHeight * 12.5)
|
||||
|
||||
/*! \internal */
|
||||
property int __implicitHeight: __implicitWidth
|
||||
|
||||
/*!
|
||||
The background of the menu.
|
||||
|
||||
By default, there is no background defined.
|
||||
*/
|
||||
property Component background
|
||||
|
||||
/*!
|
||||
The cancel component of the menu.
|
||||
|
||||
This is an area in the center of the menu that closes the menu when
|
||||
clicked.
|
||||
|
||||
By default, it is not visible.
|
||||
*/
|
||||
property Component cancel: null
|
||||
|
||||
/*!
|
||||
The component that displays the text of the currently selected menu
|
||||
item, or the title if there is no current item.
|
||||
|
||||
The current item's text is available via the \c styleData.text
|
||||
property.
|
||||
*/
|
||||
property Component title: Text {
|
||||
font.pointSize: 20
|
||||
text: styleData.text
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: "#ccc"
|
||||
antialiasing: true
|
||||
}
|
||||
|
||||
/*!
|
||||
This component defines each section of the pie menu.
|
||||
|
||||
This component covers the width and height of the control.
|
||||
|
||||
No mouse events are propagated to this component, which means that
|
||||
controls like Button will not function when used within it. You can
|
||||
check if the mouse is over this section by comparing
|
||||
\c control.currentIndex to \c styleData.index.
|
||||
|
||||
Each instance of this component has access to the following properties:
|
||||
|
||||
\table
|
||||
\row \li \c {readonly property int} \b styleData.index
|
||||
\li The index of this menu item.
|
||||
\row \li \c {readonly property bool} \b styleData.hovered
|
||||
\li \c true if this menu item is under the mouse.
|
||||
\row \li \c {readonly property bool} \b styleData.pressed
|
||||
\li \c true if the mouse is pressed down on this menu item.
|
||||
\endtable
|
||||
*/
|
||||
property Component menuItem: Item {
|
||||
id: actionRootDelegateItem
|
||||
|
||||
function drawRingSection(ctx, x, y, section, r, ringWidth, ringColor) {
|
||||
ctx.fillStyle = ringColor;
|
||||
|
||||
// Draw one section.
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x,y);
|
||||
|
||||
// Canvas draws 0 degrees at 3 o'clock, whereas we want it to draw it at 12.
|
||||
var start = control.__protectedScope.sectionStartAngle(section);
|
||||
var end = control.__protectedScope.sectionEndAngle(section);
|
||||
ctx.arc(x, y, r, start, end, start > end);
|
||||
ctx.fill();
|
||||
|
||||
// Either change this to the background color, or use the global composition.
|
||||
ctx.fillStyle = "black";
|
||||
ctx.globalCompositeOperation = "destination-out";
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, y);
|
||||
ctx.arc(x, y, ringWidth, 0, Math.PI * 2);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
|
||||
// If using the global composition method, make sure to change it back to default.
|
||||
ctx.globalCompositeOperation = "source-over";
|
||||
}
|
||||
|
||||
Canvas {
|
||||
id: actionCanvas
|
||||
anchors.fill: parent
|
||||
property color currentColor: control.currentIndex === styleData.index ? selectionColor : backgroundColor
|
||||
|
||||
Connections {
|
||||
target: pieMenuStyle
|
||||
function onStartAngleChanged() { actionCanvas.requestPaint() }
|
||||
function onEndAngleChanged() { actionCanvas.requestPaint() }
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
function onCurrentIndexChanged() { actionCanvas.requestPaint() }
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
ctx.reset();
|
||||
drawRingSection(ctx, width / 2, height / 2, styleData.index, radius, cancelRadius, currentColor);
|
||||
}
|
||||
}
|
||||
|
||||
readonly property var __styleData: styleData
|
||||
|
||||
PieMenuIcon {
|
||||
control: pieMenuStyle.control
|
||||
styleData: __styleData
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
implicitWidth: __implicitWidth
|
||||
implicitHeight: __implicitHeight
|
||||
|
||||
property alias titleItem: titleLoader.item
|
||||
|
||||
Item {
|
||||
id: itemgroup
|
||||
anchors.fill: parent
|
||||
visible: false
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
sourceComponent: background
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: cancelLoader
|
||||
sourceComponent: cancel
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: menuItemRepeater
|
||||
model: control.__protectedScope.visibleItems
|
||||
|
||||
delegate: Loader {
|
||||
id: menuItemLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: menuItem
|
||||
|
||||
readonly property int __index: index
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias index: menuItemLoader.__index
|
||||
readonly property bool hovered: control.currentIndex === index
|
||||
readonly property bool pressed: control.__protectedScope.pressedIndex === index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DropShadow {
|
||||
id: dropShadow
|
||||
anchors.fill: itemgroup
|
||||
spread: shadowSpread
|
||||
samples: shadowRadius * 2 + 1
|
||||
transparentBorder: true
|
||||
color: shadowColor
|
||||
source: itemgroup
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: titleLoader
|
||||
sourceComponent: title
|
||||
x: parent.x + parent.width / 2 - width / 2
|
||||
y: -height - 10
|
||||
|
||||
property QtObject styleData: QtObject {
|
||||
property string text: control.currentIndex !== -1
|
||||
? control.__protectedScope.visibleItems[control.currentIndex].text
|
||||
: control.title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype ProgressBarStyle
|
||||
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.1
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for ProgressBar.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
ProgressBar {
|
||||
value: slider.value
|
||||
style: ProgressBarStyle {
|
||||
background: Rectangle {
|
||||
radius: 2
|
||||
color: "lightgray"
|
||||
border.color: "gray"
|
||||
border.width: 1
|
||||
implicitWidth: 200
|
||||
implicitHeight: 24
|
||||
}
|
||||
progress: Rectangle {
|
||||
color: "lightsteelblue"
|
||||
border.color: "steelblue"
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
Note that the example above is somewhat simplified and will not animate
|
||||
an indeterminate progress bar. The following snippet demonstrates
|
||||
how you can incorporate a custom animation for the indeterminate
|
||||
state as well.
|
||||
|
||||
\code
|
||||
progress: Rectangle {
|
||||
border.color: "steelblue"
|
||||
color: "lightsteelblue"
|
||||
|
||||
// Indeterminate animation by animating alternating stripes:
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
visible: control.indeterminate
|
||||
clip: true
|
||||
Row {
|
||||
Repeater {
|
||||
Rectangle {
|
||||
color: index % 2 ? "steelblue" : "lightsteelblue"
|
||||
width: 20 ; height: control.height
|
||||
}
|
||||
model: control.width / 20 + 2
|
||||
}
|
||||
XAnimator on x {
|
||||
from: 0 ; to: -40
|
||||
loops: Animation.Infinite
|
||||
running: control.indeterminate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: progressBarStyle
|
||||
|
||||
/*! The \l ProgressBar this style is attached to. */
|
||||
readonly property ProgressBar control: __control
|
||||
|
||||
/*! A value in the range [0-1] indicating the current progress. */
|
||||
readonly property real currentProgress: control.indeterminate ? 1.0 :
|
||||
control.value / control.maximumValue
|
||||
|
||||
/*! This property holds the visible contents of the progress bar
|
||||
You can access the Slider through the \c control property.
|
||||
|
||||
For convenience, you can also access the readonly property \c styleData.progress
|
||||
which provides the current progress as a \c real in the range [0-1]
|
||||
*/
|
||||
padding { top: 0 ; left: 0 ; right: 0 ; bottom: 0 }
|
||||
|
||||
/*! \qmlproperty Component ProgressBarStyle::progress
|
||||
The progress component for this style.
|
||||
*/
|
||||
property Component progress: Item {
|
||||
property color progressColor: "#49d"
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
Rectangle {
|
||||
id: base
|
||||
anchors.fill: parent
|
||||
radius: TextSingleton.implicitHeight * 0.16
|
||||
antialiasing: true
|
||||
gradient: Gradient {
|
||||
GradientStop {color: Qt.lighter(progressColor, 1.3) ; position: 0}
|
||||
GradientStop {color: progressColor ; position: 1.4}
|
||||
}
|
||||
border.width: 1
|
||||
border.color: Qt.darker(progressColor, 1.2)
|
||||
Rectangle {
|
||||
color: "transparent"
|
||||
radius: 1.5
|
||||
clip: true
|
||||
antialiasing: true
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
border.color: Qt.rgba(1,1,1,0.1)
|
||||
Image {
|
||||
visible: control.indeterminate
|
||||
height: parent.height
|
||||
NumberAnimation on x {
|
||||
from: -39
|
||||
to: 0
|
||||
running: control.indeterminate
|
||||
duration: 800
|
||||
loops: Animation.Infinite
|
||||
}
|
||||
fillMode: Image.Tile
|
||||
width: parent.width + 25
|
||||
source: "images/progress-indeterminate.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
height: parent.height - 2
|
||||
width: 1
|
||||
y: 1
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 1
|
||||
color: Qt.rgba(1,1,1,0.1)
|
||||
visible: splitter.visible
|
||||
}
|
||||
Rectangle {
|
||||
id: splitter
|
||||
height: parent.height - 2
|
||||
width: 1
|
||||
y: 1
|
||||
anchors.right: parent.right
|
||||
color: Qt.darker(progressColor, 1.2)
|
||||
property int offset: currentProgress * control.width
|
||||
visible: offset > base.radius && offset < control.width - base.radius + 1
|
||||
}
|
||||
}
|
||||
|
||||
/*! \qmlproperty Component ProgressBarStyle::background
|
||||
The background component for this style.
|
||||
|
||||
\note The implicitWidth and implicitHeight of the background component
|
||||
must be set.
|
||||
*/
|
||||
property Component background: Item {
|
||||
implicitWidth: 200
|
||||
implicitHeight: Math.max(17, Math.round(TextSingleton.implicitHeight * 0.7))
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: control.pressed ? 0 : -1
|
||||
color: "#44ffffff"
|
||||
radius: baserect.radius
|
||||
}
|
||||
Rectangle {
|
||||
id: baserect
|
||||
gradient: Gradient {
|
||||
GradientStop {color: "#eee" ; position: 0}
|
||||
GradientStop {color: "#fff" ; position: 0.1}
|
||||
GradientStop {color: "#fff" ; position: 1}
|
||||
}
|
||||
radius: TextSingleton.implicitHeight * 0.16
|
||||
anchors.fill: parent
|
||||
border.color: control.activeFocus ? "#47b" : "#999"
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: parent.radius
|
||||
color: control.activeFocus ? "#47b" : "white"
|
||||
opacity: control.hovered || control.activeFocus ? 0.1 : 0
|
||||
Behavior on opacity {NumberAnimation{ duration: 100 }}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! \qmlproperty Component ProgressBarStyle::panel
|
||||
The panel component for this style.
|
||||
*/
|
||||
property Component panel: Item{
|
||||
property bool horizontal: control.orientation == Qt.Horizontal
|
||||
implicitWidth: horizontal ? backgroundLoader.implicitWidth : backgroundLoader.implicitHeight
|
||||
implicitHeight: horizontal ? backgroundLoader.implicitHeight : backgroundLoader.implicitWidth
|
||||
|
||||
Item {
|
||||
width: horizontal ? parent.width : parent.height
|
||||
height: !horizontal ? parent.width : parent.height
|
||||
y: horizontal ? 0 : width
|
||||
rotation: horizontal ? 0 : -90
|
||||
transformOrigin: Item.TopLeft
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: background
|
||||
}
|
||||
|
||||
Loader {
|
||||
sourceComponent: progressBarStyle.progress
|
||||
anchors.topMargin: padding.top
|
||||
anchors.leftMargin: padding.left
|
||||
anchors.rightMargin: padding.right
|
||||
anchors.bottomMargin: padding.bottom
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.bottom: parent.bottom
|
||||
width: currentProgress * (parent.width - padding.left - padding.right)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype RadioButtonStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.1
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for RadioButton.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
RadioButton {
|
||||
text: "Radio Button"
|
||||
style: RadioButtonStyle {
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 16
|
||||
implicitHeight: 16
|
||||
radius: 9
|
||||
border.color: control.activeFocus ? "darkblue" : "gray"
|
||||
border.width: 1
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
visible: control.checked
|
||||
color: "#555"
|
||||
radius: 9
|
||||
anchors.margins: 4
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: radiobuttonStyle
|
||||
|
||||
/*! The \l RadioButton this style is attached to. */
|
||||
readonly property RadioButton control: __control
|
||||
|
||||
/*! This defines the text label. */
|
||||
property Component label: Item {
|
||||
implicitWidth: text.implicitWidth + 2
|
||||
implicitHeight: text.implicitHeight
|
||||
baselineOffset: text.y + text.baselineOffset
|
||||
Rectangle {
|
||||
anchors.fill: text
|
||||
anchors.margins: -1
|
||||
anchors.leftMargin: -3
|
||||
anchors.rightMargin: -3
|
||||
visible: control.activeFocus
|
||||
height: 6
|
||||
radius: 3
|
||||
color: "#224f9fef"
|
||||
border.color: "#47b"
|
||||
opacity: 0.6
|
||||
}
|
||||
Text {
|
||||
id: text
|
||||
text: StyleHelpers.stylizeMnemonics(control.text)
|
||||
anchors.centerIn: parent
|
||||
color: SystemPaletteSingleton.text(control.enabled)
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
}
|
||||
}
|
||||
|
||||
/*! The background under indicator and label. */
|
||||
property Component background
|
||||
|
||||
/*! The spacing between indicator and label. */
|
||||
property int spacing: Math.round(TextSingleton.implicitHeight/4)
|
||||
|
||||
/*! This defines the indicator button. */
|
||||
property Component indicator: Rectangle {
|
||||
width: Math.round(TextSingleton.implicitHeight)
|
||||
height: width
|
||||
gradient: Gradient {
|
||||
GradientStop {color: "#eee" ; position: 0}
|
||||
GradientStop {color: control.pressed ? "#eee" : "#fff" ; position: 0.4}
|
||||
GradientStop {color: "#fff" ; position: 1}
|
||||
}
|
||||
border.color: control.activeFocus ? "#16c" : "gray"
|
||||
antialiasing: true
|
||||
radius: height/2
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: Math.round(parent.width * 0.5)
|
||||
height: width
|
||||
gradient: Gradient {
|
||||
GradientStop {color: "#999" ; position: 0}
|
||||
GradientStop {color: "#555" ; position: 1}
|
||||
}
|
||||
border.color: "#222"
|
||||
antialiasing: true
|
||||
radius: height/2
|
||||
Behavior on opacity {NumberAnimation {duration: 80}}
|
||||
opacity: control.checked ? control.enabled ? 1 : 0.5 : 0
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
implicitWidth: Math.max(backgroundLoader.implicitWidth, row.implicitWidth + padding.left + padding.right)
|
||||
implicitHeight: Math.max(backgroundLoader.implicitHeight, labelLoader.implicitHeight + padding.top + padding.bottom,indicatorLoader.implicitHeight + padding.top + padding.bottom)
|
||||
baselineOffset: labelLoader.item ? padding.top + labelLoader.item.baselineOffset : 0
|
||||
|
||||
Loader {
|
||||
id:backgroundLoader
|
||||
sourceComponent: background
|
||||
anchors.fill: parent
|
||||
}
|
||||
Row {
|
||||
id: row
|
||||
anchors.fill: parent
|
||||
|
||||
anchors.leftMargin: padding.left
|
||||
anchors.rightMargin: padding.right
|
||||
anchors.topMargin: padding.top
|
||||
anchors.bottomMargin: padding.bottom
|
||||
|
||||
spacing: radiobuttonStyle.spacing
|
||||
Loader {
|
||||
id: indicatorLoader
|
||||
sourceComponent: indicator
|
||||
}
|
||||
Loader {
|
||||
id: labelLoader
|
||||
sourceComponent: label
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,406 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype ScrollViewStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.1
|
||||
\ingroup viewsstyling
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for ScrollView.
|
||||
*/
|
||||
Style {
|
||||
id: root
|
||||
|
||||
/*! The \l ScrollView this style is attached to. */
|
||||
readonly property ScrollView control: __control
|
||||
|
||||
/*! This property controls the frame border padding of the scrollView. */
|
||||
padding {left: 1; top: 1; right: 1; bottom: 1}
|
||||
|
||||
/*! This Component paints the corner area between scroll bars */
|
||||
property Component corner: Rectangle { color: "#ccc" }
|
||||
|
||||
/*! This component determines if the flickable should reposition itself at the
|
||||
mouse location when clicked. */
|
||||
property bool scrollToClickedPosition: true
|
||||
|
||||
/*! This property holds whether the scroll bars are transient. Transient scroll bars
|
||||
appear when the content is scrolled and disappear when they are no longer needed.
|
||||
|
||||
The default value is platform dependent. */
|
||||
property bool transientScrollBars: Settings.isMobile && Settings.hasTouchScreen
|
||||
|
||||
/*! This Component paints the frame around scroll bars. */
|
||||
property Component frame: Rectangle {
|
||||
color: control["backgroundVisible"] ? "white": "transparent"
|
||||
border.color: "#999"
|
||||
border.width: 1
|
||||
radius: 1
|
||||
visible: control.frameVisible
|
||||
}
|
||||
|
||||
/*! This is the minimum extent of the scroll bar handle.
|
||||
|
||||
The default value is \c 30.
|
||||
*/
|
||||
|
||||
property int minimumHandleLength: 30
|
||||
|
||||
/*! This property controls the edge overlap
|
||||
between the handle and the increment/decrement buttons.
|
||||
|
||||
The default value is \c 30.
|
||||
*/
|
||||
|
||||
property int handleOverlap: 1
|
||||
|
||||
/*! This component controls the appearance of the
|
||||
scroll bar background.
|
||||
|
||||
You can access the following state properties:
|
||||
|
||||
\table
|
||||
\row \li property bool \b styleData.hovered
|
||||
\row \li property bool \b styleData.horizontal
|
||||
\endtable
|
||||
*/
|
||||
|
||||
property Component scrollBarBackground: Item {
|
||||
property bool sticky: false
|
||||
property bool hovered: styleData.hovered
|
||||
implicitWidth: Math.round(TextSingleton.implicitHeight)
|
||||
implicitHeight: Math.round(TextSingleton.implicitHeight)
|
||||
clip: true
|
||||
opacity: transientScrollBars ? 0.5 : 1.0
|
||||
visible: !Settings.hasTouchScreen && (!transientScrollBars || sticky)
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#ddd"
|
||||
border.color: "#aaa"
|
||||
anchors.rightMargin: styleData.horizontal ? -2 : -1
|
||||
anchors.leftMargin: styleData.horizontal ? -2 : 0
|
||||
anchors.topMargin: styleData.horizontal ? 0 : -2
|
||||
anchors.bottomMargin: styleData.horizontal ? -1 : -2
|
||||
}
|
||||
onHoveredChanged: if (hovered) sticky = true
|
||||
onVisibleChanged: if (!visible) sticky = false
|
||||
}
|
||||
|
||||
/*! This component controls the appearance of the
|
||||
scroll bar handle.
|
||||
|
||||
You can access the following state properties:
|
||||
|
||||
\table
|
||||
\row \li property bool \b styleData.hovered
|
||||
\row \li property bool \b styleData.pressed
|
||||
\row \li property bool \b styleData.horizontal
|
||||
\endtable
|
||||
*/
|
||||
|
||||
property Component handle: Item {
|
||||
property bool sticky: false
|
||||
property bool hovered: __activeControl !== "none"
|
||||
implicitWidth: Math.round(TextSingleton.implicitHeight) + 1
|
||||
implicitHeight: Math.round(TextSingleton.implicitHeight) + 1
|
||||
BorderImage {
|
||||
id: img
|
||||
opacity: styleData.pressed && !transientScrollBars ? 0.5 : styleData.hovered ? 1 : 0.8
|
||||
source: "images/scrollbar-handle-" + (transientScrollBars ? "transient" : styleData.horizontal ? "horizontal" : "vertical") + ".png"
|
||||
border.left: transientScrollBars ? 5 : 2
|
||||
border.top: transientScrollBars ? 5 : 2
|
||||
border.right: transientScrollBars ? 5 : 2
|
||||
border.bottom: transientScrollBars ? 5 : 2
|
||||
anchors.top: !styleData.horizontal ? parent.top : undefined
|
||||
anchors.margins: transientScrollBars ? 2 : 0
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.left: styleData.horizontal ? parent.left : undefined
|
||||
width: !styleData.horizontal && transientScrollBars ? sticky ? 13 : 10 : parent.width
|
||||
height: styleData.horizontal && transientScrollBars ? sticky ? 13 : 10 : parent.height
|
||||
Behavior on width { enabled: !styleData.horizontal && transientScrollBars; NumberAnimation { duration: 100 } }
|
||||
Behavior on height { enabled: styleData.horizontal && transientScrollBars; NumberAnimation { duration: 100 } }
|
||||
}
|
||||
onHoveredChanged: if (hovered) sticky = true
|
||||
onVisibleChanged: if (!visible) sticky = false
|
||||
}
|
||||
|
||||
/*! This component controls the appearance of the
|
||||
scroll bar increment button.
|
||||
|
||||
You can access the following state properties:
|
||||
|
||||
\table
|
||||
\row \li property bool \b styleData.hovered
|
||||
\row \li property bool \b styleData.pressed
|
||||
\row \li property bool \b styleData.horizontal
|
||||
\endtable
|
||||
*/
|
||||
property Component incrementControl: Rectangle {
|
||||
visible: !transientScrollBars
|
||||
implicitWidth: transientScrollBars ? 0 : Math.round(TextSingleton.implicitHeight)
|
||||
implicitHeight: transientScrollBars ? 0 : Math.round(TextSingleton.implicitHeight)
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: -1
|
||||
anchors.rightMargin: -1
|
||||
border.color: "#aaa"
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
color: "transparent"
|
||||
border.color: "#44ffffff"
|
||||
}
|
||||
Image {
|
||||
source: styleData.horizontal ? "images/arrow-right.png" : "images/arrow-down.png"
|
||||
anchors.centerIn: parent
|
||||
opacity: control.enabled ? 0.6 : 0.5
|
||||
}
|
||||
gradient: Gradient {
|
||||
GradientStop {color: styleData.pressed ? "lightgray" : "white" ; position: 0}
|
||||
GradientStop {color: styleData.pressed ? "lightgray" : "lightgray" ; position: 1}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! This component controls the appearance of the
|
||||
scroll bar decrement button.
|
||||
|
||||
You can access the following state properties:
|
||||
|
||||
\table
|
||||
\row \li property bool \b styleData.hovered
|
||||
\row \li property bool \b styleData.pressed
|
||||
\row \li property bool \b styleData.horizontal
|
||||
\endtable
|
||||
*/
|
||||
property Component decrementControl: Rectangle {
|
||||
visible: !transientScrollBars
|
||||
implicitWidth: transientScrollBars ? 0 : Math.round(TextSingleton.implicitHeight)
|
||||
implicitHeight: transientScrollBars ? 0 : Math.round(TextSingleton.implicitHeight)
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: styleData.horizontal ? 0 : -1
|
||||
anchors.leftMargin: styleData.horizontal ? -1 : 0
|
||||
anchors.bottomMargin: styleData.horizontal ? -1 : 0
|
||||
anchors.rightMargin: styleData.horizontal ? 0 : -1
|
||||
color: "lightgray"
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
color: "transparent"
|
||||
border.color: "#44ffffff"
|
||||
}
|
||||
Image {
|
||||
source: styleData.horizontal ? "images/arrow-left.png" : "images/arrow-up.png"
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: styleData.horizontal ? 0 : -1
|
||||
anchors.horizontalCenterOffset: styleData.horizontal ? -1 : 0
|
||||
opacity: control.enabled ? 0.6 : 0.5
|
||||
}
|
||||
gradient: Gradient {
|
||||
GradientStop {color: styleData.pressed ? "lightgray" : "white" ; position: 0}
|
||||
GradientStop {color: styleData.pressed ? "lightgray" : "lightgray" ; position: 1}
|
||||
}
|
||||
border.color: "#aaa"
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component __scrollbar: Item {
|
||||
id: panel
|
||||
property string activeControl: "none"
|
||||
property bool scrollToClickPosition: true
|
||||
property bool isTransient: transientScrollBars
|
||||
|
||||
property bool on: false
|
||||
property bool raised: false
|
||||
property bool sunken: __styleData.upPressed | __styleData.downPressed | __styleData.handlePressed
|
||||
|
||||
states: State {
|
||||
name: "out"
|
||||
when: isTransient
|
||||
&& (!__stickyScrollbars || !flickableItem.moving)
|
||||
&& panel.activeControl === "none"
|
||||
&& !panel.on
|
||||
&& !panel.raised
|
||||
PropertyChanges { target: panel; opacity: 0 }
|
||||
}
|
||||
|
||||
transitions: Transition {
|
||||
to: "out"
|
||||
SequentialAnimation {
|
||||
PauseAnimation { duration: root.__scrollBarFadeDelay }
|
||||
NumberAnimation { properties: "opacity"; duration: root.__scrollBarFadeDuration }
|
||||
PropertyAction { target: panel; property: "visible"; value: false }
|
||||
}
|
||||
}
|
||||
|
||||
implicitWidth: __styleData.horizontal ? 200 : bg.implicitWidth
|
||||
implicitHeight: __styleData.horizontal ? bg.implicitHeight : 200
|
||||
|
||||
function pixelMetric(arg) {
|
||||
if (arg === "scrollbarExtent")
|
||||
return (__styleData.horizontal ? bg.height : bg.width);
|
||||
return 0;
|
||||
}
|
||||
|
||||
function styleHint(arg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function hitTest(argX, argY) {
|
||||
if (itemIsHit(handleControl, argX, argY))
|
||||
return "handle"
|
||||
else if (itemIsHit(incrementLoader, argX, argY))
|
||||
return "up";
|
||||
else if (itemIsHit(decrementLoader, argX, argY))
|
||||
return "down";
|
||||
else if (itemIsHit(bg, argX, argY)) {
|
||||
if (__styleData.horizontal && argX < handleControl.x || !__styleData.horizontal && argY < handleControl.y)
|
||||
return "upPage"
|
||||
else
|
||||
return "downPage"
|
||||
}
|
||||
|
||||
return "none";
|
||||
}
|
||||
|
||||
function subControlRect(arg) {
|
||||
if (arg === "handle") {
|
||||
return Qt.rect(handleControl.x, handleControl.y, handleControl.width, handleControl.height);
|
||||
} else if (arg === "groove") {
|
||||
if (__styleData.horizontal) {
|
||||
return Qt.rect(incrementLoader.width - handleOverlap,
|
||||
0,
|
||||
__control.width - (incrementLoader.width + decrementLoader.width - handleOverlap * 2),
|
||||
__control.height);
|
||||
} else {
|
||||
return Qt.rect(0,
|
||||
incrementLoader.height - handleOverlap,
|
||||
__control.width,
|
||||
__control.height - (incrementLoader.height + decrementLoader.height - handleOverlap * 2));
|
||||
}
|
||||
}
|
||||
return Qt.rect(0,0,0,0);
|
||||
}
|
||||
|
||||
function itemIsHit(argItem, argX, argY) {
|
||||
var pos = argItem.mapFromItem(__control, argX, argY);
|
||||
return (pos.x >= 0 && pos.x <= argItem.width && pos.y >= 0 && pos.y <= argItem.height);
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: incrementLoader
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
sourceComponent: decrementControl
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property bool hovered: activeControl === "up"
|
||||
readonly property bool pressed: __styleData.upPressed
|
||||
readonly property bool horizontal: __styleData.horizontal
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: bg
|
||||
anchors.top: __styleData.horizontal ? undefined : incrementLoader.bottom
|
||||
anchors.bottom: __styleData.horizontal ? undefined : decrementLoader.top
|
||||
anchors.left: __styleData.horizontal ? incrementLoader.right : undefined
|
||||
anchors.right: __styleData.horizontal ? decrementLoader.left : undefined
|
||||
sourceComponent: scrollBarBackground
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property bool horizontal: __styleData.horizontal
|
||||
readonly property bool hovered: activeControl !== "none"
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: decrementLoader
|
||||
anchors.bottom: __styleData.horizontal ? undefined : parent.bottom
|
||||
anchors.right: __styleData.horizontal ? parent.right : undefined
|
||||
sourceComponent: incrementControl
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property bool hovered: activeControl === "down"
|
||||
readonly property bool pressed: __styleData.downPressed
|
||||
readonly property bool horizontal: __styleData.horizontal
|
||||
}
|
||||
}
|
||||
|
||||
property var flickableItem: control.flickableItem
|
||||
property int extent: Math.max(minimumHandleLength, __styleData.horizontal ?
|
||||
Math.min(1, ((flickableItem && flickableItem.contentWidth > 0.0) ? flickableItem.width/flickableItem.contentWidth : 1)) * bg.width :
|
||||
Math.min(1, ((flickableItem && flickableItem.contentHeight > 0.0) ? flickableItem.height/flickableItem.contentHeight : 1)) * bg.height)
|
||||
readonly property real range: __control.maximumValue - __control.minimumValue
|
||||
readonly property real begin: __control.value - __control.minimumValue
|
||||
|
||||
Loader {
|
||||
id: handleControl
|
||||
height: __styleData.horizontal ? implicitHeight : extent
|
||||
width: __styleData.horizontal ? extent : implicitWidth
|
||||
anchors.top: bg.top
|
||||
anchors.left: bg.left
|
||||
anchors.topMargin: __styleData.horizontal || range === 0 ? 0 : -handleOverlap + (2 * begin * (bg.height + (2 * handleOverlap) - extent) + range) / (2 * range)
|
||||
anchors.leftMargin: __styleData.horizontal && range !== 0 ? -handleOverlap + (2 * begin * (bg.width + (2 * handleOverlap) - extent) + range) / (2 * range) : 0
|
||||
sourceComponent: handle
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property bool hovered: activeControl === "handle"
|
||||
readonly property bool pressed: __styleData.handlePressed
|
||||
readonly property bool horizontal: __styleData.horizontal
|
||||
}
|
||||
readonly property alias __activeControl: panel.activeControl
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property bool __externalScrollBars: false
|
||||
/*! \internal */
|
||||
property int __scrollBarSpacing: 4
|
||||
/*! \internal */
|
||||
property int __scrollBarFadeDelay: 450
|
||||
/*! \internal */
|
||||
property int __scrollBarFadeDuration: 200
|
||||
/*! \internal */
|
||||
property bool __stickyScrollbars: false
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype SliderStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.1
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for Slider.
|
||||
|
||||
The slider style allows you to create a custom appearance for
|
||||
a \l Slider control.
|
||||
|
||||
The implicit size of the slider is calculated based on the
|
||||
maximum implicit size of the \c background and \c handle
|
||||
delegates combined.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
Slider {
|
||||
anchors.centerIn: parent
|
||||
style: SliderStyle {
|
||||
groove: Rectangle {
|
||||
implicitWidth: 200
|
||||
implicitHeight: 8
|
||||
color: "gray"
|
||||
radius: 8
|
||||
}
|
||||
handle: Rectangle {
|
||||
anchors.centerIn: parent
|
||||
color: control.pressed ? "white" : "lightgray"
|
||||
border.color: "gray"
|
||||
border.width: 2
|
||||
implicitWidth: 34
|
||||
implicitHeight: 34
|
||||
radius: 12
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
Style {
|
||||
id: styleitem
|
||||
|
||||
/*! The \l Slider this style is attached to. */
|
||||
readonly property Slider control: __control
|
||||
|
||||
padding { top: 0 ; left: 0 ; right: 0 ; bottom: 0 }
|
||||
|
||||
/*! This property holds the item for the slider handle.
|
||||
You can access the slider through the \c control property
|
||||
*/
|
||||
property Component handle: Item{
|
||||
implicitWidth: implicitHeight
|
||||
implicitHeight: TextSingleton.implicitHeight * 1.2
|
||||
|
||||
FastGlow {
|
||||
source: handle
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: -1
|
||||
anchors.topMargin: 1
|
||||
smooth: true
|
||||
color: "#11000000"
|
||||
spread: 0.8
|
||||
transparentBorder: true
|
||||
blur: 0.1
|
||||
|
||||
}
|
||||
Rectangle {
|
||||
id: handle
|
||||
anchors.fill: parent
|
||||
|
||||
radius: width/2
|
||||
gradient: Gradient {
|
||||
GradientStop { color: control.pressed ? "#e0e0e0" : "#fff" ; position: 1 }
|
||||
GradientStop { color: "#eee" ; position: 0 }
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
radius: width/2
|
||||
border.color: "#99ffffff"
|
||||
color: control.activeFocus ? "#224f7fbf" : "transparent"
|
||||
}
|
||||
border.color: control.activeFocus ? "#47b" : "#777"
|
||||
}
|
||||
|
||||
}
|
||||
/*! This property holds the background groove of the slider.
|
||||
|
||||
You can access the handle position through the \c styleData.handlePosition property.
|
||||
*/
|
||||
property Component groove: Item {
|
||||
property color fillColor: "#49d"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
implicitWidth: Math.round(TextSingleton.implicitHeight * 4.5)
|
||||
implicitHeight: Math.max(6, Math.round(TextSingleton.implicitHeight * 0.3))
|
||||
Rectangle {
|
||||
radius: height/2
|
||||
anchors.fill: parent
|
||||
border.width: 1
|
||||
border.color: "#888"
|
||||
gradient: Gradient {
|
||||
GradientStop { color: "#bbb" ; position: 0 }
|
||||
GradientStop { color: "#ccc" ; position: 0.6 }
|
||||
GradientStop { color: "#ccc" ; position: 1 }
|
||||
}
|
||||
}
|
||||
Item {
|
||||
clip: true
|
||||
width: styleData.handlePosition
|
||||
height: parent.height
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
border.color: Qt.darker(fillColor, 1.2)
|
||||
radius: height/2
|
||||
gradient: Gradient {
|
||||
GradientStop {color: Qt.lighter(fillColor, 1.3) ; position: 0}
|
||||
GradientStop {color: fillColor ; position: 1.4}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! This property holds the tick mark labels.
|
||||
\since QtQuick.Controls.Styles 1.1
|
||||
|
||||
Every tickmark that should be drawn must be defined within this
|
||||
component, so it is common to use a \l Repeater, for example.
|
||||
|
||||
You can access the handle width through the \c styleData.handleWidth property.
|
||||
*/
|
||||
property Component tickmarks: Repeater {
|
||||
id: repeater
|
||||
model: control.stepSize > 0 ? 1 + (control.maximumValue - control.minimumValue) / control.stepSize : 0
|
||||
Rectangle {
|
||||
color: "#777"
|
||||
width: 1 ; height: 3
|
||||
y: repeater.height
|
||||
x: styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1))
|
||||
}
|
||||
}
|
||||
|
||||
/*! This property holds the slider style panel.
|
||||
|
||||
Note that it is generally not recommended to override this.
|
||||
*/
|
||||
property Component panel: Item {
|
||||
id: root
|
||||
property int handleWidth: handleLoader.width
|
||||
property int handleHeight: handleLoader.height
|
||||
|
||||
property bool horizontal : control.orientation === Qt.Horizontal
|
||||
property int horizontalSize: grooveLoader.implicitWidth + padding.left + padding.right
|
||||
property int verticalSize: Math.max(handleLoader.implicitHeight, grooveLoader.implicitHeight) + padding.top + padding.bottom
|
||||
|
||||
implicitWidth: horizontal ? horizontalSize : verticalSize
|
||||
implicitHeight: horizontal ? verticalSize : horizontalSize
|
||||
|
||||
y: horizontal ? 0 : height
|
||||
rotation: horizontal ? 0 : -90
|
||||
transformOrigin: Item.TopLeft
|
||||
|
||||
Item {
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
Loader {
|
||||
id: grooveLoader
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property int handlePosition: handleLoader.x + handleLoader.width/2
|
||||
}
|
||||
x: padding.left
|
||||
sourceComponent: groove
|
||||
width: (horizontal ? parent.width : parent.height) - padding.left - padding.right
|
||||
y: Math.round(padding.top + (Math.round(horizontal ? parent.height : parent.width - padding.top - padding.bottom) - grooveLoader.item.height)/2)
|
||||
}
|
||||
Loader {
|
||||
id: tickMarkLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: control.tickmarksEnabled ? tickmarks : null
|
||||
property QtObject styleData: QtObject { readonly property int handleWidth: control.__panel.handleWidth }
|
||||
}
|
||||
Loader {
|
||||
id: handleLoader
|
||||
sourceComponent: handle
|
||||
anchors.verticalCenter: grooveLoader.verticalCenter
|
||||
x: Math.round((control.__handlePos - control.minimumValue) / (control.maximumValue - control.minimumValue) * ((horizontal ? root.width : root.height) - item.width))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype SpinBoxStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.2
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for SpinBox.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
SpinBox {
|
||||
style: SpinBoxStyle{
|
||||
background: Rectangle {
|
||||
implicitWidth: 100
|
||||
implicitHeight: 20
|
||||
border.color: "gray"
|
||||
radius: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: spinboxStyle
|
||||
|
||||
/*! The \l SpinBox this style is attached to. */
|
||||
readonly property SpinBox control: __control
|
||||
|
||||
/*! The content margins of the text field. */
|
||||
padding { top: 1 ; left: Math.round(styleData.contentHeight/2) ; right: Math.max(22, Math.round(styleData.contentHeight)) ; bottom: 0 }
|
||||
/*! \qmlproperty enumeration horizontalAlignment
|
||||
|
||||
This property defines the default text aligment.
|
||||
|
||||
The supported values are:
|
||||
\list
|
||||
\li Qt.AlignLeft
|
||||
\li Qt.AlignHCenter
|
||||
\li Qt.AlignRight
|
||||
\endlist
|
||||
|
||||
The default value is Qt.AlignRight
|
||||
*/
|
||||
property int horizontalAlignment: Qt.AlignRight
|
||||
|
||||
/*! The text color. */
|
||||
property color textColor: SystemPaletteSingleton.text(control.enabled)
|
||||
|
||||
/*! The text highlight color, used behind selections. */
|
||||
property color selectionColor: SystemPaletteSingleton.highlight(control.enabled)
|
||||
|
||||
/*! The highlighted text color, used in selections. */
|
||||
property color selectedTextColor: SystemPaletteSingleton.highlightedText(control.enabled)
|
||||
|
||||
/*!
|
||||
\qmlproperty enumeration renderType
|
||||
|
||||
Override the default rendering type for the control.
|
||||
|
||||
Supported render types are:
|
||||
\list
|
||||
\li Text.QtRendering
|
||||
\li Text.NativeRendering
|
||||
\endlist
|
||||
|
||||
The default value is platform dependent.
|
||||
|
||||
\sa Text::renderType
|
||||
*/
|
||||
property int renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
|
||||
/*!
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
The font of the control.
|
||||
*/
|
||||
property font font
|
||||
|
||||
/*! The button used to increment the value. */
|
||||
property Component incrementControl: Item {
|
||||
implicitWidth: padding.right
|
||||
Image {
|
||||
source: "images/arrow-up.png"
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: 1
|
||||
opacity: control.enabled ? (styleData.upPressed ? 1 : 0.6) : 0.5
|
||||
}
|
||||
}
|
||||
|
||||
/*! The button used to decrement the value. */
|
||||
property Component decrementControl: Item {
|
||||
implicitWidth: padding.right
|
||||
Image {
|
||||
source: "images/arrow-down.png"
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -2
|
||||
opacity: control.enabled ? (styleData.downPressed ? 1 : 0.6) : 0.5
|
||||
}
|
||||
}
|
||||
|
||||
/*! The background of the SpinBox. */
|
||||
property Component background: Item {
|
||||
implicitHeight: Math.max(25, Math.round(styleData.contentHeight * 1.2))
|
||||
implicitWidth: styleData.contentWidth + padding.left + padding.right
|
||||
baselineOffset: control.__baselineOffset
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: -1
|
||||
color: "#44ffffff"
|
||||
radius: baserect.radius
|
||||
}
|
||||
Rectangle {
|
||||
id: baserect
|
||||
gradient: Gradient {
|
||||
GradientStop {color: "#eee" ; position: 0}
|
||||
GradientStop {color: "#fff" ; position: 0.1}
|
||||
GradientStop {color: "#fff" ; position: 1}
|
||||
}
|
||||
radius: control.font.pixelSize * 0.16
|
||||
anchors.fill: parent
|
||||
border.color: control.activeFocus ? "#47b" : "#999"
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
id: styleitem
|
||||
implicitWidth: backgroundLoader.implicitWidth
|
||||
implicitHeight: backgroundLoader.implicitHeight
|
||||
baselineOffset: backgroundLoader.item ? backgroundLoader.item.baselineOffset : 0
|
||||
|
||||
property font font: spinboxStyle.font
|
||||
|
||||
property color foregroundColor: spinboxStyle.textColor
|
||||
property color selectionColor: spinboxStyle.selectionColor
|
||||
property color selectedTextColor: spinboxStyle.selectedTextColor
|
||||
|
||||
property var margins: spinboxStyle.padding
|
||||
|
||||
property rect upRect: Qt.rect(width - incrementControlLoader.implicitWidth, 0, incrementControlLoader.implicitWidth, height / 2 + 1)
|
||||
property rect downRect: Qt.rect(width - decrementControlLoader.implicitWidth, height / 2, decrementControlLoader.implicitWidth, height / 2)
|
||||
|
||||
property int horizontalAlignment: spinboxStyle.horizontalAlignment
|
||||
property int verticalAlignment: Qt.AlignVCenter
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: background
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: incrementControlLoader
|
||||
x: upRect.x
|
||||
y: upRect.y
|
||||
width: upRect.width
|
||||
height: upRect.height
|
||||
sourceComponent: incrementControl
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: decrementControlLoader
|
||||
x: downRect.x
|
||||
y: downRect.y
|
||||
width: downRect.width
|
||||
height: downRect.height
|
||||
sourceComponent: decrementControl
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
The cursor handle.
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
|
||||
The parent of the handle is positioned to the top left corner of
|
||||
the cursor position. The interactive area is determined by the
|
||||
geometry of the handle delegate.
|
||||
|
||||
The following signals and read-only properties are available within the scope
|
||||
of the handle delegate:
|
||||
\table
|
||||
\row \li \b {styleData.activated()} [signal] \li Emitted when the handle is activated ie. the editor is clicked.
|
||||
\row \li \b {styleData.pressed} : bool \li Whether the handle is pressed.
|
||||
\row \li \b {styleData.position} : int \li The character position of the handle.
|
||||
\row \li \b {styleData.lineHeight} : real \li The height of the line the handle is on.
|
||||
\row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text.
|
||||
\endtable
|
||||
*/
|
||||
property Component __cursorHandle
|
||||
|
||||
/*! \internal
|
||||
The selection handle.
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
|
||||
The parent of the handle is positioned to the top left corner of
|
||||
the first selected character. The interactive area is determined
|
||||
by the geometry of the handle delegate.
|
||||
|
||||
The following signals and read-only properties are available within the scope
|
||||
of the handle delegate:
|
||||
\table
|
||||
\row \li \b {styleData.activated()} [signal] \li Emitted when the handle is activated ie. the editor is clicked.
|
||||
\row \li \b {styleData.pressed} : bool \li Whether the handle is pressed.
|
||||
\row \li \b {styleData.position} : int \li The character position of the handle.
|
||||
\row \li \b {styleData.lineHeight} : real \li The height of the line the handle is on.
|
||||
\row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text.
|
||||
\endtable
|
||||
*/
|
||||
property Component __selectionHandle
|
||||
|
||||
/*! \internal
|
||||
The cursor delegate.
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
*/
|
||||
property Component __cursorDelegate
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype StatusBarStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\ingroup controlsstyling
|
||||
\since 5.2
|
||||
\brief Provides custom styling for StatusBar.
|
||||
|
||||
The status bar can be defined by overriding the background component and
|
||||
setting the content padding.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
StatusBar {
|
||||
style: StatusBarStyle {
|
||||
padding {
|
||||
left: 8
|
||||
right: 8
|
||||
top: 3
|
||||
bottom: 3
|
||||
}
|
||||
background: Rectangle {
|
||||
implicitHeight: 16
|
||||
implicitWidth: 200
|
||||
gradient: Gradient{
|
||||
GradientStop{color: "#eee" ; position: 0}
|
||||
GradientStop{color: "#ccc" ; position: 1}
|
||||
}
|
||||
Rectangle {
|
||||
anchors.top: parent.top
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: "#999"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
|
||||
Style {
|
||||
|
||||
/*! The content padding inside the status bar. */
|
||||
padding {
|
||||
left: 3
|
||||
right: 3
|
||||
top: 3
|
||||
bottom: 2
|
||||
}
|
||||
|
||||
/*! This defines the background of the status bar. */
|
||||
property Component background: Rectangle {
|
||||
implicitHeight: 16
|
||||
implicitWidth: 200
|
||||
|
||||
gradient: Gradient{
|
||||
GradientStop{color: "#eee" ; position: 0}
|
||||
GradientStop{color: "#ccc" ; position: 1}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.top: parent.top
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: "#999"
|
||||
}
|
||||
}
|
||||
|
||||
/*! This defines the panel of the status bar. */
|
||||
property Component panel: Loader {
|
||||
sourceComponent: background
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Extras module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls.Private 1.0
|
||||
import QtQuick.Extras 1.4
|
||||
|
||||
/*!
|
||||
\qmltype StatusIndicatorStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.5
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for StatusIndicatorStyle.
|
||||
|
||||
You can create a custom status indicator by defining the \l indicator
|
||||
component.
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: pieMenuStyle
|
||||
|
||||
/*!
|
||||
The \l StatusIndicator that this style is attached to.
|
||||
*/
|
||||
readonly property StatusIndicator control: __control
|
||||
|
||||
/*!
|
||||
The color that instances of
|
||||
\l [QtQuickExtras]{StatusIndicator} will have.
|
||||
The \l [QtQuickExtras]{StatusIndicator::}{color}
|
||||
property in \l [QtQuickExtras]{StatusIndicator}
|
||||
will override this property when set.
|
||||
*/
|
||||
property color color: "red"
|
||||
|
||||
/*!
|
||||
This defines the indicator in both its on and off status.
|
||||
*/
|
||||
property Component indicator: Item {
|
||||
readonly property real shineStep: 0.05
|
||||
readonly property real smallestAxis: Math.min(control.width, control.height)
|
||||
readonly property real outerRecessPercentage: 0.11
|
||||
readonly property color offColor: Qt.rgba(0.13, 0.13, 0.13)
|
||||
readonly property color baseColor: control.active ? control.color : offColor
|
||||
|
||||
implicitWidth: TextSingleton.implicitHeight * 2
|
||||
implicitHeight: implicitWidth
|
||||
|
||||
Canvas {
|
||||
id: backgroundCanvas
|
||||
width: Math.min(parent.width, parent.height)
|
||||
// height: width --- QTBUG-42878
|
||||
height: Math.min(parent.width, parent.height)
|
||||
anchors.centerIn: parent
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
function onActiveChanged() { backgroundCanvas.requestPaint() }
|
||||
function onColorChanged() { backgroundCanvas.requestPaint() }
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
ctx.reset();
|
||||
|
||||
// Draw the semi-transparent background.
|
||||
ctx.beginPath();
|
||||
var gradient = ctx.createLinearGradient(width / 2, 0, width / 2, height * 0.75);
|
||||
gradient.addColorStop(0.0, Qt.rgba(0, 0, 0, control.active ? 0.1 : 0.25));
|
||||
gradient.addColorStop(1.0, control.active ? Qt.rgba(0, 0, 0, 0.1) : Qt.rgba(0.74, 0.74, 0.74, 0.25));
|
||||
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.ellipse(0, 0, width, height);
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: shadowGuard
|
||||
anchors.fill: backgroundCanvas
|
||||
anchors.margins: -shadow.radius
|
||||
|
||||
Canvas {
|
||||
id: colorCanvas
|
||||
anchors.fill: parent
|
||||
anchors.margins: shadow.radius
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
function onActiveChanged() { colorCanvas.requestPaint() }
|
||||
function onColorChanged() { colorCanvas.requestPaint() }
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
ctx.reset();
|
||||
|
||||
// Draw the actual color within the circle.
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = baseColor;
|
||||
var recess = smallestAxis * outerRecessPercentage;
|
||||
ctx.ellipse(recess, recess, width - recess * 2, height - recess * 2);
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
id: shadow
|
||||
source: shadowGuard
|
||||
color: control.color
|
||||
cached: true
|
||||
anchors.fill: shadowGuard
|
||||
visible: control.active
|
||||
}
|
||||
|
||||
Canvas {
|
||||
id: foregroundCanvas
|
||||
anchors.fill: backgroundCanvas
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
function onActiveChanged() { foregroundCanvas.requestPaint() }
|
||||
function onColorChanged() { foregroundCanvas.requestPaint() }
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
ctx.reset();
|
||||
|
||||
// Draw the first shine.
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = Qt.rgba(1, 1, 1, 0.03);
|
||||
var recessPercentage = outerRecessPercentage + shineStep * 0.65;
|
||||
var recess = smallestAxis * recessPercentage;
|
||||
ctx.ellipse(recess, recess, width - recess * 2, height - recess * 2);
|
||||
ctx.fill();
|
||||
|
||||
// Draw the second, inner shine.
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = Qt.rgba(1, 1, 1, 0.06);
|
||||
recessPercentage += shineStep;
|
||||
recess = smallestAxis * recessPercentage;
|
||||
ctx.ellipse(recess, recess, width - recess * 2, height - recess * 2);
|
||||
ctx.fill();
|
||||
|
||||
// Now draw the final arced shine that goes over the first and second shines.
|
||||
// First, clip the entire shine area.
|
||||
ctx.beginPath();
|
||||
recessPercentage -= shineStep;
|
||||
recess = smallestAxis * recessPercentage;
|
||||
ctx.ellipse(recess, recess, width - recess * 2, height - recess * 2);
|
||||
ctx.clip();
|
||||
|
||||
if (!control.active) {
|
||||
// Then, clip the bottom area out of the shine.
|
||||
ctx.ellipse(recess, height * 0.425, width - recess * 2, height - recess * 2);
|
||||
ctx.clip();
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
var gradient;
|
||||
if (!control.active) {
|
||||
// Draw the shine arc.
|
||||
gradient = ctx.createLinearGradient(width / 2, height * 0.2, width / 2, height * 0.65);
|
||||
gradient.addColorStop(0.0, Qt.rgba(1, 1, 1, 0.05));
|
||||
gradient.addColorStop(1.0, "transparent");
|
||||
} else {
|
||||
// Draw the radial shine.
|
||||
gradient = ctx.createRadialGradient(width / 2, height / 2, 0, width / 2, height / 2, width * 0.5 /* (same as height) */);
|
||||
gradient.addColorStop(0.0, Qt.lighter(baseColor, 1.4));
|
||||
gradient.addColorStop(1.0, "transparent");
|
||||
}
|
||||
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.ellipse(recess, recess, width - recess * 2, height - recess * 2);
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
implicitWidth: indicatorLoader.implicitWidth
|
||||
implicitHeight: indicatorLoader.implicitHeight
|
||||
|
||||
Loader {
|
||||
id: indicatorLoader
|
||||
width: Math.max(1, parent.width)
|
||||
height: Math.max(1, parent.height)
|
||||
anchors.centerIn: parent
|
||||
sourceComponent: indicator
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype SwitchStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.2
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for Switch.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
Switch {
|
||||
style: SwitchStyle {
|
||||
groove: Rectangle {
|
||||
implicitWidth: 100
|
||||
implicitHeight: 20
|
||||
radius: 9
|
||||
border.color: control.activeFocus ? "darkblue" : "gray"
|
||||
border.width: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
Style {
|
||||
id: switchstyle
|
||||
|
||||
/*! The content padding. */
|
||||
padding {
|
||||
top: 0
|
||||
left: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
}
|
||||
|
||||
/*! This defines the switch handle. */
|
||||
property Component handle: Rectangle {
|
||||
opacity: control.enabled ? 1.0 : 0.5
|
||||
implicitWidth: Math.round((parent.parent.width - padding.left - padding.right)/2)
|
||||
implicitHeight: control.height - padding.top - padding.bottom
|
||||
|
||||
border.color: control.activeFocus ? Qt.darker(highlight, 2) : Qt.darker(button, 2)
|
||||
property color bg: control.activeFocus ? Qt.darker(highlight, 1.2) : button
|
||||
property color highlight: SystemPaletteSingleton.highlight(control.enabled)
|
||||
property color button: SystemPaletteSingleton.button(control.enabled)
|
||||
gradient: Gradient {
|
||||
GradientStop {color: Qt.lighter(bg, 1.4) ; position: 0}
|
||||
GradientStop {color: bg ; position: 1}
|
||||
}
|
||||
|
||||
radius: 2
|
||||
}
|
||||
|
||||
/*! This property holds the background groove of the switch. */
|
||||
property Component groove: Rectangle {
|
||||
property color shadow: control.checked ? Qt.darker(highlight, 1.2): "#999"
|
||||
property color bg: control.checked ? highlight:"#bbb"
|
||||
property color highlight: SystemPaletteSingleton.highlight(control.enabled)
|
||||
|
||||
implicitWidth: Math.round(implicitHeight * 3)
|
||||
implicitHeight: Math.max(16, Math.round(TextSingleton.implicitHeight))
|
||||
|
||||
border.color: "gray"
|
||||
color: "red"
|
||||
|
||||
radius: 2
|
||||
Behavior on shadow {ColorAnimation{ duration: 80 }}
|
||||
Behavior on bg {ColorAnimation{ duration: 80 }}
|
||||
gradient: Gradient {
|
||||
GradientStop {color: shadow; position: 0}
|
||||
GradientStop {color: bg ; position: 0.2}
|
||||
GradientStop {color: bg ; position: 1}
|
||||
}
|
||||
Rectangle {
|
||||
color: "#44ffffff"
|
||||
height: 1
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: -1
|
||||
width: parent.width - 2
|
||||
x: 1
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
|
||||
implicitWidth: Math.round(grooveLoader.width + padding.left + padding.right)
|
||||
implicitHeight: grooveLoader.implicitHeight + padding.top + padding.bottom
|
||||
|
||||
property var __handle: handleLoader
|
||||
property int min: padding.left
|
||||
property int max: grooveLoader.width - handleLoader.width - padding.right
|
||||
|
||||
Loader {
|
||||
id: grooveLoader
|
||||
y: padding.top
|
||||
x: padding.left
|
||||
|
||||
sourceComponent: groove
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
|
||||
Loader {
|
||||
id: handleLoader
|
||||
|
||||
z:1
|
||||
|
||||
x: control.checked ? max : min
|
||||
|
||||
anchors.top: grooveLoader.top
|
||||
anchors.bottom: grooveLoader.bottom
|
||||
anchors.topMargin: padding.top
|
||||
anchors.bottomMargin: padding.bottom
|
||||
|
||||
Behavior on x {
|
||||
id: behavior
|
||||
enabled: handleLoader.status === Loader.Ready
|
||||
NumberAnimation {
|
||||
duration: 150
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
sourceComponent: handle
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype TabViewStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.1
|
||||
\ingroup viewsstyling
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for TabView.
|
||||
|
||||
\qml
|
||||
TabView {
|
||||
id: frame
|
||||
anchors.fill: parent
|
||||
anchors.margins: 4
|
||||
Tab { title: "Tab 1" }
|
||||
Tab { title: "Tab 2" }
|
||||
Tab { title: "Tab 3" }
|
||||
|
||||
style: TabViewStyle {
|
||||
frameOverlap: 1
|
||||
tab: Rectangle {
|
||||
color: styleData.selected ? "steelblue" :"lightsteelblue"
|
||||
border.color: "steelblue"
|
||||
implicitWidth: Math.max(text.width + 4, 80)
|
||||
implicitHeight: 20
|
||||
radius: 2
|
||||
Text {
|
||||
id: text
|
||||
anchors.centerIn: parent
|
||||
text: styleData.title
|
||||
color: styleData.selected ? "white" : "black"
|
||||
}
|
||||
}
|
||||
frame: Rectangle { color: "steelblue" }
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
*/
|
||||
|
||||
Style {
|
||||
|
||||
/*! The \l ScrollView this style is attached to. */
|
||||
readonly property TabView control: __control
|
||||
|
||||
/*! This property holds whether the user can move the tabs.
|
||||
Tabs are not movable by default. */
|
||||
property bool tabsMovable: false
|
||||
|
||||
/*! This property holds the horizontal alignment of
|
||||
the tab buttons. Supported values are:
|
||||
\list
|
||||
\li Qt.AlignLeft (default)
|
||||
\li Qt.AlignHCenter
|
||||
\li Qt.AlignRight
|
||||
\endlist
|
||||
*/
|
||||
property int tabsAlignment: Qt.AlignLeft
|
||||
|
||||
/*! This property holds the amount of overlap there are between
|
||||
individual tab buttons. */
|
||||
property int tabOverlap: 1
|
||||
|
||||
/*! This property holds the amount of overlap there are between
|
||||
individual tab buttons and the frame. */
|
||||
property int frameOverlap: 2
|
||||
|
||||
/*! This defines the tab frame. */
|
||||
property Component frame: Rectangle {
|
||||
color: "#dcdcdc"
|
||||
border.color: "#aaa"
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
border.color: "#66ffffff"
|
||||
anchors.margins: 1
|
||||
}
|
||||
}
|
||||
|
||||
/*! This defines the tab. You can access the tab state through the
|
||||
\c styleData property, with the following properties:
|
||||
|
||||
\table
|
||||
\row \li readonly property int \b styleData.index \li This is the current tab index.
|
||||
\row \li readonly property bool \b styleData.selected \li This is the active tab.
|
||||
\row \li readonly property string \b styleData.title \li Tab title text.
|
||||
\row \li readonly property bool \b styleData.nextSelected \li The next tab is selected.
|
||||
\row \li readonly property bool \b styleData.previousSelected \li The previous tab is selected.
|
||||
\row \li readonly property bool \b styleData.pressed \li The tab is being pressed. (since QtQuick.Controls.Styles 1.3)
|
||||
\row \li readonly property bool \b styleData.hovered \li The tab is being hovered.
|
||||
\row \li readonly property bool \b styleData.enabled \li The tab is enabled. (since QtQuick.Controls.Styles 1.2)
|
||||
\row \li readonly property bool \b styleData.activeFocus \li The tab button has keyboard focus.
|
||||
\row \li readonly property bool \b styleData.availableWidth \li The available width for the tabs.
|
||||
\row \li readonly property bool \b styleData.totalWidth \li The total width of the tabs. (since QtQuick.Controls.Styles 1.2)
|
||||
\endtable
|
||||
*/
|
||||
property Component tab: Item {
|
||||
scale: control.tabPosition === Qt.TopEdge ? 1 : -1
|
||||
|
||||
property int totalOverlap: tabOverlap * (control.count - 1)
|
||||
property real maxTabWidth: control.count > 0 ? (styleData.availableWidth + totalOverlap) / control.count : 0
|
||||
|
||||
implicitWidth: Math.round(Math.min(maxTabWidth, textitem.implicitWidth + 20))
|
||||
implicitHeight: Math.round(textitem.implicitHeight + 10)
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: styleData.selected ? 0 : 2
|
||||
BorderImage {
|
||||
anchors.fill: parent
|
||||
source: styleData.selected ? "images/tab_selected.png" : "images/tab.png"
|
||||
border.top: 6
|
||||
border.bottom: 6
|
||||
border.left: 6
|
||||
border.right: 6
|
||||
anchors.topMargin: styleData.selected ? 0 : 1
|
||||
}
|
||||
}
|
||||
Text {
|
||||
id: textitem
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 4
|
||||
anchors.rightMargin: 4
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: styleData.title
|
||||
elide: Text.ElideMiddle
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
scale: control.tabPosition === Qt.TopEdge ? 1 : -1
|
||||
color: SystemPaletteSingleton.text(styleData.enabled)
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: textitem.paintedWidth + 6
|
||||
height: textitem.paintedHeight + 4
|
||||
visible: (styleData.activeFocus && styleData.selected)
|
||||
radius: 3
|
||||
color: "#224f9fef"
|
||||
border.color: "#47b"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! This defines the left corner. */
|
||||
property Component leftCorner: null
|
||||
|
||||
/*! This defines the right corner. */
|
||||
property Component rightCorner: null
|
||||
|
||||
/*! This defines the tab bar background. */
|
||||
property Component tabBar: null
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
|
||||
BasicTableViewStyle {
|
||||
id: root
|
||||
|
||||
readonly property TableView control: __control
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype TextAreaStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.2
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for TextArea.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
TextArea {
|
||||
style: TextAreaStyle {
|
||||
textColor: "#333"
|
||||
selectionColor: "steelblue"
|
||||
selectedTextColor: "#eee"
|
||||
backgroundColor: "#eee"
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
|
||||
ScrollViewStyle {
|
||||
id: style
|
||||
|
||||
/*! The \l TextArea this style is attached to. */
|
||||
readonly property TextArea control: __control
|
||||
|
||||
/*! The current font. */
|
||||
property font font
|
||||
|
||||
/*! The text color. */
|
||||
property color textColor: SystemPaletteSingleton.text(control.enabled)
|
||||
|
||||
/*! The text highlight color, used behind selections. */
|
||||
property color selectionColor: SystemPaletteSingleton.highlight(control.enabled)
|
||||
|
||||
/*! The highlighted text color, used in selections. */
|
||||
property color selectedTextColor: SystemPaletteSingleton.highlightedText(control.enabled)
|
||||
|
||||
/*! The background color. */
|
||||
property color backgroundColor: control.backgroundVisible ? SystemPaletteSingleton.base(control.enabled) : "transparent"
|
||||
|
||||
/*!
|
||||
\qmlproperty enumeration renderType
|
||||
|
||||
Override the default rendering type for the control.
|
||||
|
||||
Supported render types are:
|
||||
\list
|
||||
\li Text.QtRendering
|
||||
\li Text.NativeRendering
|
||||
\endlist
|
||||
|
||||
The default value is platform dependent.
|
||||
|
||||
\sa Text::renderType
|
||||
*/
|
||||
property int renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
|
||||
/*! The default margin, in pixels, around the text in the TextArea.
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
\sa TextArea::textMargin */
|
||||
property real textMargin: 4
|
||||
|
||||
/*! \internal
|
||||
The cursor handle.
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
|
||||
The parent of the handle is positioned to the top left corner of
|
||||
the cursor position. The interactive area is determined by the
|
||||
geometry of the handle delegate.
|
||||
|
||||
The following signals and read-only properties are available within the scope
|
||||
of the handle delegate:
|
||||
\table
|
||||
\row \li \b {styleData.activated()} [signal] \li Emitted when the handle is activated ie. the editor is clicked.
|
||||
\row \li \b {styleData.pressed} : bool \li Whether the handle is pressed.
|
||||
\row \li \b {styleData.position} : int \li The character position of the handle.
|
||||
\row \li \b {styleData.lineHeight} : real \li The height of the line the handle is on.
|
||||
\row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text.
|
||||
\endtable
|
||||
*/
|
||||
property Component __cursorHandle
|
||||
|
||||
/*! \internal
|
||||
The selection handle.
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
|
||||
The parent of the handle is positioned to the top left corner of
|
||||
the first selected character. The interactive area is determined
|
||||
by the geometry of the handle delegate.
|
||||
|
||||
The following signals and read-only properties are available within the scope
|
||||
of the handle delegate:
|
||||
\table
|
||||
\row \li \b {styleData.activated()} [signal] \li Emitted when the handle is activated ie. the editor is clicked.
|
||||
\row \li \b {styleData.pressed} : bool \li Whether the handle is pressed.
|
||||
\row \li \b {styleData.position} : int \li The character position of the handle.
|
||||
\row \li \b {styleData.lineHeight} : real \li The height of the line the handle is on.
|
||||
\row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text.
|
||||
\endtable
|
||||
*/
|
||||
property Component __selectionHandle
|
||||
|
||||
/*! \internal
|
||||
The cursor delegate.
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
*/
|
||||
property Component __cursorDelegate
|
||||
|
||||
/*! \internal
|
||||
The delegate for the cut/copy/paste menu.
|
||||
\since QtQuick.Controls.Styles 1.4
|
||||
*/
|
||||
property Component __editMenu
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype TextFieldStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.1
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for TextField.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
TextField {
|
||||
style: TextFieldStyle {
|
||||
textColor: "black"
|
||||
background: Rectangle {
|
||||
radius: 2
|
||||
implicitWidth: 100
|
||||
implicitHeight: 24
|
||||
border.color: "#333"
|
||||
border.width: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: style
|
||||
|
||||
/*! The \l TextField this style is attached to. */
|
||||
readonly property TextField control: __control
|
||||
|
||||
/*! The content margins of the text field. */
|
||||
padding { top: 4 ; left: Math.round(control.__contentHeight/3) ; right: control.__contentHeight/3 ; bottom: 4 }
|
||||
|
||||
/*! The current font. */
|
||||
property font font
|
||||
|
||||
/*! The text color. */
|
||||
property color textColor: SystemPaletteSingleton.text(control.enabled)
|
||||
|
||||
/*! The text highlight color, used behind selections. */
|
||||
property color selectionColor: SystemPaletteSingleton.highlight(control.enabled)
|
||||
|
||||
/*! The highlighted text color, used in selections. */
|
||||
property color selectedTextColor: SystemPaletteSingleton.highlightedText(control.enabled)
|
||||
|
||||
/*!
|
||||
\qmlproperty string passwordCharacter
|
||||
\since QtQuick.Controls.Styles 1.4
|
||||
|
||||
The password character that is displayed when echoMode
|
||||
on the TextField is set to TextInput.Password or
|
||||
TextInput.PasswordEchoOnEdit.
|
||||
*/
|
||||
property string passwordCharacter: Qt.styleHints.passwordMaskCharacter
|
||||
|
||||
/*!
|
||||
\qmlproperty enumeration renderType
|
||||
\since QtQuick.Controls.Styles 1.1
|
||||
|
||||
Override the default rendering type for the control.
|
||||
|
||||
Supported render types are:
|
||||
\list
|
||||
\li Text.QtRendering
|
||||
\li Text.NativeRendering
|
||||
\endlist
|
||||
|
||||
The default value is platform dependent.
|
||||
|
||||
\sa Text::renderType
|
||||
*/
|
||||
property int renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
|
||||
/*! The placeholder text color, used when the text field is empty.
|
||||
\since QtQuick.Controls.Styles 1.1
|
||||
*/
|
||||
property color placeholderTextColor: Qt.rgba(0, 0, 0, 0.5)
|
||||
|
||||
/*! The background of the text field. */
|
||||
property Component background: Item {
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: -1
|
||||
color: "#44ffffff"
|
||||
radius: baserect.radius
|
||||
}
|
||||
Rectangle {
|
||||
id: baserect
|
||||
gradient: Gradient {
|
||||
GradientStop {color: "#e0e0e0" ; position: 0}
|
||||
GradientStop {color: "#fff" ; position: 0.1}
|
||||
GradientStop {color: "#fff" ; position: 1}
|
||||
}
|
||||
radius: control.__contentHeight * 0.16
|
||||
anchors.fill: parent
|
||||
border.color: control.activeFocus ? "#47b" : "#999"
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
anchors.fill: parent
|
||||
|
||||
property int topMargin: padding.top
|
||||
property int leftMargin: padding.left
|
||||
property int rightMargin: padding.right
|
||||
property int bottomMargin: padding.bottom
|
||||
|
||||
property color textColor: style.textColor
|
||||
property color selectionColor: style.selectionColor
|
||||
property color selectedTextColor: style.selectedTextColor
|
||||
|
||||
implicitWidth: backgroundLoader.implicitWidth || Math.round(control.__contentHeight * 8)
|
||||
implicitHeight: backgroundLoader.implicitHeight || Math.max(25, Math.round(control.__contentHeight * 1.2))
|
||||
baselineOffset: padding.top + control.__baselineOffset
|
||||
|
||||
property color placeholderTextColor: style.placeholderTextColor
|
||||
property font font: style.font
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
sourceComponent: background
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
The cursor handle.
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
|
||||
The parent of the handle is positioned to the top left corner of
|
||||
the cursor position. The interactive area is determined by the
|
||||
geometry of the handle delegate.
|
||||
|
||||
The following signals and read-only properties are available within the scope
|
||||
of the handle delegate:
|
||||
\table
|
||||
\row \li \b {styleData.activated()} [signal] \li Emitted when the handle is activated ie. the editor is clicked.
|
||||
\row \li \b {styleData.pressed} : bool \li Whether the handle is pressed.
|
||||
\row \li \b {styleData.position} : int \li The character position of the handle.
|
||||
\row \li \b {styleData.lineHeight} : real \li The height of the line the handle is on.
|
||||
\row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text.
|
||||
\endtable
|
||||
*/
|
||||
property Component __cursorHandle
|
||||
|
||||
/*! \internal
|
||||
The selection handle.
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
|
||||
The parent of the handle is positioned to the top left corner of
|
||||
the first selected character. The interactive area is determined
|
||||
by the geometry of the handle delegate.
|
||||
|
||||
The following signals and read-only properties are available within the scope
|
||||
of the handle delegate:
|
||||
\table
|
||||
\row \li \b {styleData.activated()} [signal] \li Emitted when the handle is activated ie. the editor is clicked.
|
||||
\row \li \b {styleData.pressed} : bool \li Whether the handle is pressed.
|
||||
\row \li \b {styleData.position} : int \li The character position of the handle.
|
||||
\row \li \b {styleData.lineHeight} : real \li The height of the line the handle is on.
|
||||
\row \li \b {styleData.hasSelection} : bool \li Whether the editor has selected text.
|
||||
\endtable
|
||||
*/
|
||||
property Component __selectionHandle
|
||||
|
||||
/*! \internal
|
||||
The cursor delegate.
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
*/
|
||||
property Component __cursorDelegate
|
||||
|
||||
/*! \internal
|
||||
The delegate for the cut/copy/paste menu.
|
||||
\since QtQuick.Controls.Styles 1.4
|
||||
*/
|
||||
property Component __editMenu
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Extras module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Extras 1.4
|
||||
import QtQuick.Extras.Private 1.0
|
||||
import QtQuick.Extras.Private.CppUtils 1.0
|
||||
|
||||
/*!
|
||||
\qmltype ToggleButtonStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.5
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for ToggleButton.
|
||||
|
||||
You can create a custom toggle button by replacing the same delegates that
|
||||
\l {ButtonStyle} provides.
|
||||
*/
|
||||
|
||||
CircularButtonStyle {
|
||||
id: circularButtonStyle
|
||||
|
||||
/*!
|
||||
The \l ToggleButton that this style is attached to.
|
||||
*/
|
||||
readonly property ToggleButton control: __control
|
||||
|
||||
/*!
|
||||
The gradient that is displayed on the inactive state indicator. The
|
||||
inactive state indicator will be the checked gradient when the button
|
||||
is unchecked, and the unchecked gradient when the button is checked.
|
||||
|
||||
\sa checkedGradient, uncheckedGradient
|
||||
*/
|
||||
property Gradient inactiveGradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: commonStyleHelper.inactiveColor
|
||||
}
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: commonStyleHelper.inactiveColorShine
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The gradient that is displayed on the checked state indicator.
|
||||
|
||||
\sa uncheckedGradient, inactiveGradient
|
||||
*/
|
||||
property Gradient checkedGradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: commonStyleHelper.onColor
|
||||
}
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: commonStyleHelper.onColorShine
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The gradient that is displayed on the unchecked state indicator.
|
||||
|
||||
\sa checkedGradient, inactiveGradient
|
||||
*/
|
||||
property Gradient uncheckedGradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: commonStyleHelper.offColor
|
||||
}
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: commonStyleHelper.offColorShine
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The color that is used for the drop shadow below the checked state
|
||||
indicator.
|
||||
|
||||
\sa uncheckedDropShadowColor
|
||||
*/
|
||||
property color checkedDropShadowColor: commonStyleHelper.onColor
|
||||
|
||||
/*!
|
||||
The color that is used for the drop shadow below the checked state
|
||||
indicator.
|
||||
|
||||
\sa checkedDropShadowColor
|
||||
*/
|
||||
property color uncheckedDropShadowColor: commonStyleHelper.offColor
|
||||
|
||||
CommonStyleHelper {
|
||||
id: commonStyleHelper
|
||||
}
|
||||
|
||||
background: Item {
|
||||
implicitWidth: __buttonHelper.implicitWidth
|
||||
implicitHeight: __buttonHelper.implicitHeight
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
function onPressedChanged() {
|
||||
backgroundCanvas.requestPaint();
|
||||
}
|
||||
|
||||
function onCheckedChanged() {
|
||||
uncheckedCanvas.requestPaint();
|
||||
checkedCanvas.requestPaint();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: circularButtonStyle
|
||||
|
||||
function onCheckedGradientChanged() { checkedCanvas.requestPaint() }
|
||||
function onCheckedDropShadowColorChanged() { checkedCanvas.requestPaint() }
|
||||
function onUncheckedGradientChanged() { uncheckedCanvas.requestPaint() }
|
||||
function onUncheckedDropShadowColorChanged() { uncheckedCanvas.requestPaint() }
|
||||
function onInactiveGradientChanged() {
|
||||
checkedCanvas.requestPaint();
|
||||
uncheckedCanvas.requestPaint();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: circularButtonStyle.checkedGradient
|
||||
function onUpdated() { checkedCanvas.requestPaint() }
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: circularButtonStyle.uncheckedGradient
|
||||
function onUpdated() { uncheckedCanvas.requestPaint() }
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: circularButtonStyle.inactiveGradient
|
||||
function onUpdated() {
|
||||
uncheckedCanvas.requestPaint();
|
||||
checkedCanvas.requestPaint();
|
||||
}
|
||||
}
|
||||
|
||||
Canvas {
|
||||
id: backgroundCanvas
|
||||
anchors.fill: parent
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
__buttonHelper.paintBackground(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
Canvas {
|
||||
id: uncheckedCanvas
|
||||
anchors.fill: parent
|
||||
anchors.margins: -(__buttonHelper.radius * 3)
|
||||
visible: control.checked
|
||||
|
||||
readonly property real xCenter: width / 2
|
||||
readonly property real yCenter: height / 2
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
ctx.reset();
|
||||
|
||||
/* Draw unchecked indicator */
|
||||
ctx.beginPath();
|
||||
ctx.lineWidth = __buttonHelper.outerArcLineWidth - __buttonHelper.innerArcLineWidth;
|
||||
ctx.arc(xCenter, yCenter, __buttonHelper.outerArcRadius + __buttonHelper.innerArcLineWidth / 2,
|
||||
MathUtils.degToRad(180), MathUtils.degToRad(270), false);
|
||||
var gradient = ctx.createLinearGradient(xCenter, yCenter + __buttonHelper.radius,
|
||||
xCenter, yCenter - __buttonHelper.radius);
|
||||
var relevantGradient = control.checked ? inactiveGradient : uncheckedGradient;
|
||||
for (var i = 0; i < relevantGradient.stops.length; ++i) {
|
||||
gradient.addColorStop(relevantGradient.stops[i].position, relevantGradient.stops[i].color);
|
||||
}
|
||||
ctx.strokeStyle = gradient;
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
Canvas {
|
||||
id: checkedCanvas
|
||||
anchors.fill: parent
|
||||
anchors.margins: -(__buttonHelper.radius * 3)
|
||||
visible: !control.checked
|
||||
|
||||
readonly property real xCenter: width / 2
|
||||
readonly property real yCenter: height / 2
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
ctx.reset();
|
||||
|
||||
/* Draw checked indicator */
|
||||
ctx.beginPath();
|
||||
ctx.lineWidth = __buttonHelper.outerArcLineWidth - __buttonHelper.innerArcLineWidth;
|
||||
ctx.arc(xCenter, yCenter, __buttonHelper.outerArcRadius + __buttonHelper.innerArcLineWidth / 2,
|
||||
MathUtils.degToRad(270), MathUtils.degToRad(0), false);
|
||||
var gradient = ctx.createLinearGradient(xCenter, yCenter + __buttonHelper.radius,
|
||||
xCenter, yCenter - __buttonHelper.radius);
|
||||
var relevantGradient = control.checked ? checkedGradient : inactiveGradient;
|
||||
for (var i = 0; i < relevantGradient.stops.length; ++i) {
|
||||
gradient.addColorStop(relevantGradient.stops[i].position, relevantGradient.stops[i].color);
|
||||
}
|
||||
ctx.strokeStyle = gradient;
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
id: uncheckedDropShadow
|
||||
anchors.fill: uncheckedCanvas
|
||||
cached: true
|
||||
color: uncheckedDropShadowColor
|
||||
source: uncheckedCanvas
|
||||
visible: !control.checked
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
id: checkedDropShadow
|
||||
anchors.fill: checkedCanvas
|
||||
cached: true
|
||||
color: checkedDropShadowColor
|
||||
source: checkedCanvas
|
||||
visible: control.checked
|
||||
}
|
||||
}
|
||||
|
||||
panel: Item {
|
||||
implicitWidth: backgroundLoader.implicitWidth
|
||||
implicitHeight: backgroundLoader.implicitHeight
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: background
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: labelLoader
|
||||
sourceComponent: label
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: padding.left
|
||||
anchors.topMargin: padding.top
|
||||
anchors.rightMargin: padding.right
|
||||
anchors.bottomMargin: padding.bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype ToolBarStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\ingroup controlsstyling
|
||||
\since 5.2
|
||||
\brief Provides custom styling for ToolBar.
|
||||
|
||||
The tool bar can be defined by overriding the background component and
|
||||
setting the content padding.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
ToolBar {
|
||||
style: ToolBarStyle {
|
||||
padding {
|
||||
left: 8
|
||||
right: 8
|
||||
top: 3
|
||||
bottom: 3
|
||||
}
|
||||
background: Rectangle {
|
||||
implicitWidth: 100
|
||||
implicitHeight: 40
|
||||
border.color: "#999"
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0 ; color: "#fff" }
|
||||
GradientStop { position: 1 ; color: "#eee" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
|
||||
Style {
|
||||
|
||||
/*! The content padding inside the tool bar. */
|
||||
padding {
|
||||
left: 6
|
||||
right: 6
|
||||
top: 3
|
||||
bottom: 3
|
||||
}
|
||||
|
||||
/*! This defines the background of the tool bar. */
|
||||
property Component background: Item {
|
||||
implicitHeight: 40
|
||||
implicitWidth: 200
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
gradient: Gradient{
|
||||
GradientStop{color: "#eee" ; position: 0}
|
||||
GradientStop{color: "#ccc" ; position: 1}
|
||||
}
|
||||
Rectangle {
|
||||
anchors.bottom: parent.bottom
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: "#999"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! This defines the menu button appearance on platforms
|
||||
that have a unified tool bar and menu bar.
|
||||
|
||||
\since QtQuick.Controls.Styles 1.3
|
||||
|
||||
The following read-only properties are available within the scope
|
||||
of the menu button delegate:
|
||||
\table
|
||||
\row \li \b {styleData.pressed} : bool \li Whether the button is pressed.
|
||||
\row \li \b {styleData.hovered} : bool \li Whether the button is hovered.
|
||||
\row \li \b {styleData.activeFocus} : bool \li Whether the button has active focus.
|
||||
\endtable
|
||||
*/
|
||||
property Component menuButton: null
|
||||
|
||||
/*! This defines the panel of the tool bar. */
|
||||
property Component panel: Loader {
|
||||
sourceComponent: background
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype ToolButtonStyle
|
||||
\internal
|
||||
\ingroup controlsstyling
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
*/
|
||||
Style {
|
||||
readonly property ToolButton control: __control
|
||||
property Component panel: Item {
|
||||
id: styleitem
|
||||
implicitWidth: (hasIcon ? icon.width : Math.max(label.implicitWidth + frame.border.left + frame.border.right, 36))
|
||||
+ (arrow.visible ? 10 : 0)
|
||||
implicitHeight: hasIcon ? icon.height : Math.max(label.implicitHeight, 36)
|
||||
|
||||
readonly property bool hasIcon: icon.status === Image.Ready || icon.status === Image.Loading
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
visible: control.pressed || (control.checkable && control.checked)
|
||||
color: "lightgray"
|
||||
radius:4
|
||||
border.color: "#aaa"
|
||||
}
|
||||
Item {
|
||||
anchors.left: parent.left
|
||||
anchors.right: arrow.left
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
clip: true
|
||||
Text {
|
||||
id: label
|
||||
visible: !hasIcon
|
||||
anchors.centerIn: parent
|
||||
text: StyleHelpers.stylizeMnemonics(control.text)
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
}
|
||||
Image {
|
||||
id: icon
|
||||
anchors.centerIn: parent
|
||||
source: control.iconSource
|
||||
}
|
||||
}
|
||||
|
||||
BorderImage {
|
||||
id: frame
|
||||
anchors.fill: parent
|
||||
anchors.margins: -1
|
||||
anchors.topMargin: -2
|
||||
anchors.rightMargin: 0
|
||||
source: "images/focusframe.png"
|
||||
visible: control.activeFocus
|
||||
border.left: 4
|
||||
border.right: 4
|
||||
border.top: 4
|
||||
border.bottom: 4
|
||||
}
|
||||
|
||||
Image {
|
||||
id: arrow
|
||||
visible: control.menu !== null
|
||||
source: visible ? "images/arrow-down.png" : ""
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: visible ? 3 : 0
|
||||
opacity: control.enabled ? 0.7 : 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
BasicTableViewStyle {
|
||||
id: root
|
||||
|
||||
readonly property TreeView control: __control
|
||||
|
||||
property int indentation: 16
|
||||
|
||||
property Component branchDelegate: Item {
|
||||
width: indentation
|
||||
height: 16
|
||||
Text {
|
||||
visible: styleData.column === 0 && styleData.hasChildren
|
||||
text: styleData.isExpanded ? "\u25bc" : "\u25b6"
|
||||
color: !control.activeFocus || styleData.selected ? styleData.textColor : "#666"
|
||||
font.pointSize: 10
|
||||
renderType: Text.NativeRendering
|
||||
style: Text.PlainText
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: 2
|
||||
}
|
||||
}
|
||||
|
||||
__branchDelegate: branchDelegate
|
||||
__indentation: indentation
|
||||
}
|
||||
@@ -0,0 +1,334 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Quick Extras module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Controls.Private 1.0
|
||||
import QtQuick.Extras 1.4
|
||||
import QtQuick.Extras.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype TumblerStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.5
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for Tumbler.
|
||||
|
||||
You can create a custom tumbler by replacing the following delegates:
|
||||
\list
|
||||
\li \l background
|
||||
\li \l foreground
|
||||
\li \l separator
|
||||
\li \l delegate
|
||||
\li \l highlight
|
||||
\li \l frame
|
||||
\endlist
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: tumblerStyle
|
||||
|
||||
padding.left: __padding
|
||||
padding.right: __padding
|
||||
padding.top: __padding
|
||||
padding.bottom: __padding
|
||||
|
||||
/*!
|
||||
The \l Tumbler that this style is attached to.
|
||||
*/
|
||||
readonly property Tumbler control: __control
|
||||
|
||||
/*!
|
||||
\obsolete
|
||||
|
||||
This property holds the spacing between each delegate.
|
||||
|
||||
This property has no effect.
|
||||
*/
|
||||
property real spacing: 0
|
||||
|
||||
/*!
|
||||
This property holds the amount of items visible in each column.
|
||||
|
||||
This value should be an odd number.
|
||||
*/
|
||||
property int visibleItemCount: 3
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
TODO: how do we handle differing padding values?
|
||||
*/
|
||||
readonly property real __padding: Math.max(6, Math.round(TextSingleton.implicitHeight * 0.4))
|
||||
/*! \internal */
|
||||
property real __delegateHeight: 0
|
||||
/*! \internal */
|
||||
property real __separatorWidth: 0
|
||||
|
||||
/*!
|
||||
The background of the tumbler.
|
||||
*/
|
||||
property Component background: Rectangle {
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.00; color: "#acacac" }
|
||||
GradientStop { position: 0.12; color: "#d5d5d5" }
|
||||
GradientStop { position: 0.24; color: "#e8e8e8" }
|
||||
GradientStop { position: 0.39; color: "#ffffff" }
|
||||
GradientStop { position: 0.61; color: "#ffffff" }
|
||||
GradientStop { position: 0.76; color: "#e8e8e8" }
|
||||
GradientStop { position: 0.88; color: "#d5d5d5" }
|
||||
GradientStop { position: 1.00; color: "#acacac" }
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The foreground of the tumbler.
|
||||
*/
|
||||
property Component foreground: Item {
|
||||
clip: true
|
||||
|
||||
Rectangle {
|
||||
id: rect
|
||||
anchors.fill: parent
|
||||
// Go one pixel larger than our parent so that we can hide our one pixel frame
|
||||
// that the shadow is created from.
|
||||
anchors.margins: -1
|
||||
color: "transparent"
|
||||
border.color: "black"
|
||||
visible: false
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
anchors.fill: rect
|
||||
source: rect
|
||||
samples: 15
|
||||
spread: 0.45
|
||||
cached: true
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The separator between each column.
|
||||
|
||||
The \l {Item::}{implicitWidth} property must be set, and should be the
|
||||
same value for each separator.
|
||||
*/
|
||||
property Component separator: Canvas {
|
||||
implicitWidth: Math.max(10, Math.round(TextSingleton.implicitHeight * 0.4))
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d");
|
||||
ctx.reset();
|
||||
|
||||
ctx.fillStyle = "#11000000";
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
ctx.fillStyle = "#11000000";
|
||||
ctx.fillRect(width * 0.2, 0, width * 0.6, height);
|
||||
ctx.fillStyle = "#66000000";
|
||||
ctx.fillRect(width * 0.4, 0, width * 0.2, height);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The foreground of each column.
|
||||
|
||||
In terms of stacking order, this component is displayed above the
|
||||
delegate and highlight components, but below the foreground component.
|
||||
|
||||
\table
|
||||
\row \li \c {readonly property int} \b styleData.column
|
||||
\li The index of the column that contains this item.
|
||||
\row \li \c {readonly property bool} \b styleData.activeFocus
|
||||
\li \c true if the column that contains this item has active focus.
|
||||
|
||||
\endtable
|
||||
|
||||
Delegates for items in specific columns can be defined using
|
||||
TumblerColumn's \l {TumblerColumn::columnForeground}{columnForeground}
|
||||
property, which will be used instead of this component.
|
||||
*/
|
||||
property Component columnForeground
|
||||
|
||||
/*!
|
||||
The frame around the tumbler.
|
||||
|
||||
The \l {Item::}{implicitWidth} property must be set, and should be the
|
||||
same value for each separator.
|
||||
*/
|
||||
property Component frame: Canvas {
|
||||
onPaint: {
|
||||
// workaround for QTBUG-40792
|
||||
var ctx = getContext("2d");
|
||||
ctx.reset();
|
||||
|
||||
var cornerRadius = Math.max(2, Math.round(TextSingleton.implicitHeight * 0.2));
|
||||
var outerLineWidth = Math.max(1, Math.round(TextSingleton.implicitHeight * 0.05));
|
||||
var innerLineWidth = __padding - outerLineWidth;
|
||||
|
||||
ctx.save();
|
||||
ctx.lineWidth = outerLineWidth;
|
||||
ctx.beginPath();
|
||||
ctx.roundedRect(0, 0, width, height, cornerRadius, cornerRadius);
|
||||
ctx.roundedRect(outerLineWidth, outerLineWidth, width - outerLineWidth * 2, height - outerLineWidth * 2,
|
||||
cornerRadius - outerLineWidth, cornerRadius - outerLineWidth);
|
||||
ctx.clip();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.rect(0, 0, width, height);
|
||||
var gradient = ctx.createLinearGradient(width / 2, 0, width / 2, height);
|
||||
gradient.addColorStop(0, "#33b3b3b3");
|
||||
gradient.addColorStop(1, "#4ce6e6e6");
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
|
||||
// The inner stroke must account for its corner radius.
|
||||
cornerRadius -= outerLineWidth;
|
||||
|
||||
ctx.save();
|
||||
ctx.lineWidth = innerLineWidth;
|
||||
ctx.beginPath();
|
||||
ctx.roundedRect(outerLineWidth, outerLineWidth, width - outerLineWidth * 2, height - outerLineWidth * 2,
|
||||
cornerRadius, cornerRadius);
|
||||
ctx.roundedRect(outerLineWidth + innerLineWidth, outerLineWidth + innerLineWidth,
|
||||
width - outerLineWidth * 2 - innerLineWidth * 2, height - outerLineWidth * 2 - innerLineWidth * 2,
|
||||
cornerRadius - innerLineWidth, cornerRadius - innerLineWidth);
|
||||
ctx.clip();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.rect(0, 0, width, height);
|
||||
gradient = ctx.createLinearGradient(width / 2, 0, width / 2, height);
|
||||
gradient.addColorStop(0, "#4c666666");
|
||||
gradient.addColorStop(1, "#40cccccc");
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The delegate provides a template defining each item instantiated in the
|
||||
column. Each instance of this component has access to the following properties:
|
||||
|
||||
\table
|
||||
\row \li \c {readonly property int} \b styleData.index
|
||||
\li The index of this delegate in the model.
|
||||
\row \li \c {readonly property int} \b styleData.column
|
||||
\li The index of the column that contains this item.
|
||||
\row \li \c {readonly property real} \b styleData.value
|
||||
\li The value for this delegate from the model.
|
||||
\row \li \c {readonly property bool} \b styleData.current
|
||||
\li \c true if this delegate is the current item.
|
||||
\row \li \c {readonly property real} \b styleData.displacement
|
||||
\li \c A value from \c {-visibleItemCount / 2} to
|
||||
\c {visibleItemCount / 2} which represents how far away
|
||||
this item is from being the current item, with \c 0 being
|
||||
completely current.
|
||||
|
||||
For example, the item below will be 40% opaque when
|
||||
it is not the current item, and transition to 100%
|
||||
opacity when it becomes the current item:
|
||||
|
||||
\code
|
||||
delegate: Text {
|
||||
text: styleData.value
|
||||
opacity: 0.4 + Math.max(0, 1 - Math.abs(styleData.displacement)) * 0.6
|
||||
}
|
||||
\endcode
|
||||
\row \li \c {readonly property bool} \b styleData.activeFocus
|
||||
\li \c true if the column that contains this item has active focus.
|
||||
|
||||
\endtable
|
||||
|
||||
Properties of the model are also available depending upon the type of
|
||||
\l {qml-data-models}{Data Model}.
|
||||
|
||||
Delegates for items in specific columns can be defined using
|
||||
TumblerColumn's \l {TumblerColumn::delegate}{delegate} property, which
|
||||
will be used instead of this delegate.
|
||||
|
||||
The \l {Item::}{implicitHeight} property must be set, and it must be
|
||||
the same for each delegate.
|
||||
*/
|
||||
property Component delegate: Item {
|
||||
implicitHeight: (control.height - padding.top - padding.bottom) / tumblerStyle.visibleItemCount
|
||||
|
||||
Text {
|
||||
id: label
|
||||
text: styleData.value
|
||||
color: "#666666"
|
||||
opacity: 0.4 + Math.max(0, 1 - Math.abs(styleData.displacement)) * 0.6
|
||||
font.pixelSize: Math.round(TextSingleton.font.pixelSize * 1.25)
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The delegate for the highlight of each column.
|
||||
|
||||
Delegates for the highlight of specific columns can be defined using
|
||||
TumblerColumn's \l {TumblerColumn::highlight}{highlight} property,
|
||||
which will be used instead of this delegate.
|
||||
|
||||
Each instance of this component has access to the following properties:
|
||||
|
||||
\table
|
||||
\row \li \c {readonly property int} \b styleData.index
|
||||
\li The index of this column in the tumbler.
|
||||
\row \li \c {readonly property int} \b styleData.columnIndex
|
||||
\li The index of the column that contains this highlight.
|
||||
\row \li \c {readonly property bool} \b styleData.activeFocus
|
||||
\li \c true if the column that contains this highlight has active focus.
|
||||
\endtable
|
||||
*/
|
||||
property Component highlight
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
implicitWidth: {
|
||||
var w = (__separatorWidth * (control.columnCount - 1)) + tumblerStyle.padding.left + tumblerStyle.padding.right;
|
||||
for (var i = 0; i < control.columnCount; ++i)
|
||||
w += control.getColumn(i).width;
|
||||
return w;
|
||||
}
|
||||
implicitHeight: TextSingleton.implicitHeight * 10 + tumblerStyle.padding.top + tumblerStyle.padding.bottom
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 99 B |
|
After Width: | Height: | Size: 138 B |
|
After Width: | Height: | Size: 98 B |
|
After Width: | Height: | Size: 139 B |
|
After Width: | Height: | Size: 99 B |
|
After Width: | Height: | Size: 148 B |
|
After Width: | Height: | Size: 112 B |
|
After Width: | Height: | Size: 155 B |