This commit is contained in:
Sven Riwoldt
2024-10-19 12:31:37 +02:00
commit f7f8c52455
10176 changed files with 1619386 additions and 0 deletions

View File

@@ -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
}
}
}

View File

@@ -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)
}

View File

@@ -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)
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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()
}

View File

@@ -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) }
}]
}

View File

@@ -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
}

View File

@@ -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
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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
}
}
]
}

View File

@@ -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
}
}
}

View File

@@ -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]);
}
}
}
}

View File

@@ -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;
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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)
}
}

View File

@@ -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();
}

View File

@@ -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);
}
}
}
}

View File

@@ -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"
}
}

View File

@@ -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)
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}
}
}

View File

@@ -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()
}
}

View File

@@ -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
}

View File

@@ -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 }
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}

View File

@@ -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]
}

View File

@@ -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
}
}

View File

@@ -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
}

View File

@@ -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 }
}

View File

@@ -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)
}
}
}
}

View File

@@ -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
}
}

View File

@@ -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()
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}
}

View File

@@ -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 {
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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
}
}
}

View File

@@ -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; }
}

View File

@@ -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 }
}
}

View File

@@ -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))
}
}
}
}

View File

@@ -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()
}

View File

@@ -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)
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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"]
}

View File

@@ -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
}

View File

@@ -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
}]
}

View File

@@ -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
}
}
}

View File

@@ -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
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}
}
}
}
}
}

View File

@@ -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
}
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}
}
}
}
}

View File

@@ -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
}

View File

@@ -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"
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}
}

View File

@@ -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
}

View File

@@ -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
}
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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();
}
}

View File

@@ -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
}

View File

@@ -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
}
}
}
}

View File

@@ -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
}
}
}
}

View File

@@ -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)
}
}
}
}

View File

@@ -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
}
}
}
}

View File

@@ -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
}

View File

@@ -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))
}
}
}
}

View File

@@ -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
}

View File

@@ -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
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}

View File

@@ -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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Some files were not shown because too many files have changed in this diff Show More