summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@theqtcompany.com>2015-02-12 13:55:22 +0100
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2015-02-13 12:01:33 +0000
commit6f15c206b069ed0fcf48a285bfcc4ad636927df0 (patch)
tree6150e262bc2d049219981a4cb1e1deeeeed5d636
parentd28a02aec9a1632f2263d9276099454b33fb6741 (diff)
downloadqtquickcontrols-6f15c206b069ed0fcf48a285bfcc4ad636927df0.tar.gz
Import Qt Quick Extras (the former Qt Quick Enterprise Controls)
Change-Id: I59c5c97c564f707da4ce617e25e13ff8124f7d4b Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
-rw-r--r--.gitignore6
-rw-r--r--examples/examples.pro1
-rw-r--r--examples/quick/extras/dashboard/dashboard.pro18
-rw-r--r--examples/quick/extras/dashboard/dashboard.qrc13
-rw-r--r--examples/quick/extras/dashboard/fonts/DejaVuSans.ttfbin0 -> 720856 bytes
-rw-r--r--examples/quick/extras/dashboard/images/fuel-icon.pngbin0 -> 666 bytes
-rw-r--r--examples/quick/extras/dashboard/images/temperature-icon.pngbin0 -> 3302 bytes
-rw-r--r--examples/quick/extras/dashboard/main.cpp55
-rw-r--r--examples/quick/extras/dashboard/qml/DashboardGaugeStyle.qml164
-rw-r--r--examples/quick/extras/dashboard/qml/IconGaugeStyle.qml124
-rw-r--r--examples/quick/extras/dashboard/qml/TachometerStyle.qml116
-rw-r--r--examples/quick/extras/dashboard/qml/TurnIndicator.qml105
-rw-r--r--examples/quick/extras/dashboard/qml/ValueSource.qml320
-rw-r--r--examples/quick/extras/dashboard/qml/dashboard.qml175
-rw-r--r--examples/quick/extras/extras.pro5
-rw-r--r--examples/quick/extras/flat/Content.qml707
-rw-r--r--examples/quick/extras/flat/SettingsIcon.qml118
-rw-r--r--examples/quick/extras/flat/flat.pro16
-rw-r--r--examples/quick/extras/flat/flat.qrc16
-rw-r--r--examples/quick/extras/flat/images/piemenu-bw-normal.pngbin0 -> 1716 bytes
-rw-r--r--examples/quick/extras/flat/images/piemenu-bw-pressed.pngbin0 -> 1394 bytes
-rw-r--r--examples/quick/extras/flat/images/piemenu-image-bw.jpgbin0 -> 1065560 bytes
-rw-r--r--examples/quick/extras/flat/images/piemenu-image-rgb.jpgbin0 -> 1152261 bytes
-rw-r--r--examples/quick/extras/flat/images/piemenu-image-sepia.jpgbin0 -> 1513238 bytes
-rw-r--r--examples/quick/extras/flat/images/piemenu-rgb-normal.pngbin0 -> 1665 bytes
-rw-r--r--examples/quick/extras/flat/images/piemenu-rgb-pressed.pngbin0 -> 1571 bytes
-rw-r--r--examples/quick/extras/flat/images/piemenu-sepia-normal.pngbin0 -> 1410 bytes
-rw-r--r--examples/quick/extras/flat/images/piemenu-sepia-pressed.pngbin0 -> 1386 bytes
-rw-r--r--examples/quick/extras/flat/main.cpp55
-rw-r--r--examples/quick/extras/flat/main.qml480
-rw-r--r--examples/quick/extras/gallery/fonts/LICENSE.txt202
-rw-r--r--examples/quick/extras/gallery/fonts/OpenSans-Regular.ttfbin0 -> 217360 bytes
-rw-r--r--examples/quick/extras/gallery/gallery.pro31
-rw-r--r--examples/quick/extras/gallery/gallery.qrc36
-rw-r--r--examples/quick/extras/gallery/images/background-light.pngbin0 -> 46832 bytes
-rw-r--r--examples/quick/extras/gallery/images/background.pngbin0 -> 45497 bytes
-rw-r--r--examples/quick/extras/gallery/images/center-light.pngbin0 -> 2113 bytes
-rw-r--r--examples/quick/extras/gallery/images/center.pngbin0 -> 2392 bytes
-rw-r--r--examples/quick/extras/gallery/images/icon-back.pngbin0 -> 614 bytes
-rw-r--r--examples/quick/extras/gallery/images/icon-go.pngbin0 -> 1435 bytes
-rw-r--r--examples/quick/extras/gallery/images/icon-settings.pngbin0 -> 1786 bytes
-rw-r--r--examples/quick/extras/gallery/images/info.pngbin0 -> 709 bytes
-rw-r--r--examples/quick/extras/gallery/images/needle-light.pngbin0 -> 2105 bytes
-rw-r--r--examples/quick/extras/gallery/images/needle.pngbin0 -> 4891 bytes
-rw-r--r--examples/quick/extras/gallery/images/qt-logo.pngbin0 -> 5149 bytes
-rw-r--r--examples/quick/extras/gallery/images/zoom_in.pngbin0 -> 829 bytes
-rw-r--r--examples/quick/extras/gallery/images/zoom_out.pngbin0 -> 779 bytes
-rw-r--r--examples/quick/extras/gallery/main.cpp49
-rw-r--r--examples/quick/extras/gallery/qml/BlackButtonBackground.qml71
-rw-r--r--examples/quick/extras/gallery/qml/BlackButtonStyle.qml97
-rw-r--r--examples/quick/extras/gallery/qml/CircularGaugeDarkStyle.qml96
-rw-r--r--examples/quick/extras/gallery/qml/CircularGaugeDefaultStyle.qml46
-rw-r--r--examples/quick/extras/gallery/qml/CircularGaugeLightStyle.qml97
-rw-r--r--examples/quick/extras/gallery/qml/CircularGaugeView.qml230
-rw-r--r--examples/quick/extras/gallery/qml/ControlLabel.qml49
-rw-r--r--examples/quick/extras/gallery/qml/ControlView.qml188
-rw-r--r--examples/quick/extras/gallery/qml/ControlViewToolbar.qml91
-rw-r--r--examples/quick/extras/gallery/qml/CustomizerLabel.qml48
-rw-r--r--examples/quick/extras/gallery/qml/CustomizerSlider.qml75
-rw-r--r--examples/quick/extras/gallery/qml/CustomizerSwitch.qml46
-rw-r--r--examples/quick/extras/gallery/qml/FlickableMoreIndicator.qml76
-rw-r--r--examples/quick/extras/gallery/qml/PieMenuControlView.qml187
-rw-r--r--examples/quick/extras/gallery/qml/PieMenuDarkStyle.qml46
-rw-r--r--examples/quick/extras/gallery/qml/PieMenuDefaultStyle.qml44
-rw-r--r--examples/quick/extras/gallery/qml/StylePicker.qml99
-rw-r--r--examples/quick/extras/gallery/qml/gallery.qml440
-rw-r--r--src/extras/CircularGauge.qml159
-rw-r--r--src/extras/DelayButton.qml157
-rw-r--r--src/extras/Dial.qml228
-rw-r--r--src/extras/Gauge.qml209
-rw-r--r--src/extras/PieMenu.qml747
-rw-r--r--src/extras/Private/CircularButton.qml49
-rw-r--r--src/extras/Private/CircularButtonStyleHelper.qml133
-rw-r--r--src/extras/Private/CircularTickmarkLabel.qml142
-rw-r--r--src/extras/Private/Handle.qml120
-rw-r--r--src/extras/Private/PieMenuIcon.qml99
-rw-r--r--src/extras/Private/TextSingleton.qml41
-rw-r--r--src/extras/Private/private.pri24
-rw-r--r--src/extras/Private/qmldir1
-rw-r--r--src/extras/Private/qquickcircularprogressbar.cpp209
-rw-r--r--src/extras/Private/qquickcircularprogressbar_p.h99
-rw-r--r--src/extras/Private/qquickflatprogressbar.cpp202
-rw-r--r--src/extras/Private/qquickflatprogressbar_p.h88
-rw-r--r--src/extras/Private/qquickmathutils.cpp111
-rw-r--r--src/extras/Private/qquickmathutils_p.h61
-rw-r--r--src/extras/Private/qquickmousethief.cpp208
-rw-r--r--src/extras/Private/qquickmousethief_p.h86
-rw-r--r--src/extras/Private/qquickstylesettings.cpp157
-rw-r--r--src/extras/Private/qquickstylesettings_p.h79
-rw-r--r--src/extras/StatusIndicator.qml117
-rw-r--r--src/extras/Styles/Base/Base.pro34
-rw-r--r--src/extras/Styles/Base/CircularButtonStyle.qml85
-rw-r--r--src/extras/Styles/Base/CircularGaugeStyle.qml498
-rw-r--r--src/extras/Styles/Base/CircularTickmarkLabelStyle.qml304
-rw-r--r--src/extras/Styles/Base/CommonStyleHelper.qml56
-rw-r--r--src/extras/Styles/Base/DelayButtonStyle.qml233
-rw-r--r--src/extras/Styles/Base/DialStyle.qml392
-rw-r--r--src/extras/Styles/Base/GaugeStyle.qml545
-rw-r--r--src/extras/Styles/Base/HandleStyle.qml73
-rw-r--r--src/extras/Styles/Base/HandleStyleHelper.qml91
-rw-r--r--src/extras/Styles/Base/PieMenuStyle.qml393
-rw-r--r--src/extras/Styles/Base/StatusIndicatorStyle.qml237
-rw-r--r--src/extras/Styles/Base/ToggleButtonStyle.qml294
-rw-r--r--src/extras/Styles/Base/TumblerStyle.qml330
-rw-r--r--src/extras/Styles/Base/basestyle.qrc19
-rw-r--r--src/extras/Styles/Base/basestyleplugin.cpp70
-rw-r--r--src/extras/Styles/Base/basestyleplugin.h58
-rw-r--r--src/extras/Styles/Base/images/knob.pngbin0 -> 5495 bytes
-rw-r--r--src/extras/Styles/Base/images/needle.pngbin0 -> 4354 bytes
-rw-r--r--src/extras/Styles/Base/qmldir4
-rw-r--r--src/extras/Styles/Flat/ApplicationWindowStyle.qml111
-rw-r--r--src/extras/Styles/Flat/BusyIndicatorStyle.qml75
-rw-r--r--src/extras/Styles/Flat/ButtonStyle.qml194
-rw-r--r--src/extras/Styles/Flat/CalendarStyle.qml205
-rw-r--r--src/extras/Styles/Flat/CheckBoxDrawer.qml100
-rw-r--r--src/extras/Styles/Flat/CheckBoxStyle.qml62
-rw-r--r--src/extras/Styles/Flat/CircularButtonStyle.qml38
-rw-r--r--src/extras/Styles/Flat/CircularGaugeStyle.qml168
-rw-r--r--src/extras/Styles/Flat/CircularTickmarkLabelStyle.qml39
-rw-r--r--src/extras/Styles/Flat/ComboBoxStyle.qml163
-rw-r--r--src/extras/Styles/Flat/CursorHandleStyle.qml45
-rw-r--r--src/extras/Styles/Flat/DelayButtonStyle.qml291
-rw-r--r--src/extras/Styles/Flat/DialStyle.qml97
-rw-r--r--src/extras/Styles/Flat/Flat.pro67
-rw-r--r--src/extras/Styles/Flat/FlatStyle.qml100
-rw-r--r--src/extras/Styles/Flat/FocusFrameStyle.qml38
-rw-r--r--src/extras/Styles/Flat/GaugeStyle.qml132
-rw-r--r--src/extras/Styles/Flat/GroupBoxStyle.qml99
-rw-r--r--src/extras/Styles/Flat/LeftArrowIcon.qml61
-rw-r--r--src/extras/Styles/Flat/MenuBarStyle.qml42
-rw-r--r--src/extras/Styles/Flat/MenuStyle.qml95
-rw-r--r--src/extras/Styles/Flat/PieMenuStyle.qml169
-rw-r--r--src/extras/Styles/Flat/ProgressBarStyle.qml60
-rw-r--r--src/extras/Styles/Flat/RadioButtonStyle.qml87
-rw-r--r--src/extras/Styles/Flat/ScrollViewStyle.qml76
-rw-r--r--src/extras/Styles/Flat/SelectionHandleStyle.qml44
-rw-r--r--src/extras/Styles/Flat/SliderStyle.qml110
-rw-r--r--src/extras/Styles/Flat/SpinBoxStyle.qml153
-rw-r--r--src/extras/Styles/Flat/StatusBarStyle.qml38
-rw-r--r--src/extras/Styles/Flat/StatusIndicatorStyle.qml62
-rw-r--r--src/extras/Styles/Flat/SwitchStyle.qml86
-rw-r--r--src/extras/Styles/Flat/TabViewStyle.qml102
-rw-r--r--src/extras/Styles/Flat/TableViewStyle.qml163
-rw-r--r--src/extras/Styles/Flat/TextAreaStyle.qml67
-rw-r--r--src/extras/Styles/Flat/TextFieldStyle.qml70
-rw-r--r--src/extras/Styles/Flat/ToggleButtonStyle.qml99
-rw-r--r--src/extras/Styles/Flat/ToolBarStyle.qml75
-rw-r--r--src/extras/Styles/Flat/ToolButtonBackground.qml94
-rw-r--r--src/extras/Styles/Flat/ToolButtonIndicator.qml70
-rw-r--r--src/extras/Styles/Flat/ToolButtonStyle.qml110
-rw-r--r--src/extras/Styles/Flat/TumblerStyle.qml167
-rw-r--r--src/extras/Styles/Flat/flatstyle.qrc51
-rw-r--r--src/extras/Styles/Flat/flatstyleplugin.cpp117
-rw-r--r--src/extras/Styles/Flat/flatstyleplugin.h58
-rw-r--r--src/extras/Styles/Flat/fonts/LICENSE.txt202
-rw-r--r--src/extras/Styles/Flat/fonts/OpenSans-Light.ttfbin0 -> 222412 bytes
-rw-r--r--src/extras/Styles/Flat/fonts/OpenSans-Regular.ttfbin0 -> 217360 bytes
-rw-r--r--src/extras/Styles/Flat/fonts/OpenSans-Semibold.ttfbin0 -> 221328 bytes
-rw-r--r--src/extras/Styles/Flat/images/BusyIndicator_Normal-Large.pngbin0 -> 4377 bytes
-rw-r--r--src/extras/Styles/Flat/images/BusyIndicator_Normal-Medium.pngbin0 -> 2526 bytes
-rw-r--r--src/extras/Styles/Flat/images/BusyIndicator_Normal-Small.pngbin0 -> 1591 bytes
-rw-r--r--src/extras/Styles/Flat/qmldir3
-rw-r--r--src/extras/Styles/Flat/qquicktexthandle.cpp129
-rw-r--r--src/extras/Styles/Flat/qquicktexthandle.h83
-rw-r--r--src/extras/Styles/styles.pro4
-rw-r--r--src/extras/ToggleButton.qml69
-rw-r--r--src/extras/Tumbler.qml464
-rw-r--r--src/extras/TumblerColumn.qml170
-rw-r--r--src/extras/designer/CircularGaugeSpecifics.qml111
-rw-r--r--src/extras/designer/DelayButtonSpecifics.qml93
-rw-r--r--src/extras/designer/DialSpecifics.qml128
-rw-r--r--src/extras/designer/GaugeSpecifics.qml131
-rw-r--r--src/extras/designer/PictureSpecifics.qml80
-rw-r--r--src/extras/designer/PieMenuSpecifics.qml100
-rw-r--r--src/extras/designer/StatusIndicatorSpecifics.qml76
-rw-r--r--src/extras/designer/ToggleButtonSpecifics.qml92
-rw-r--r--src/extras/designer/TumblerSpecifics.qml50
-rw-r--r--src/extras/designer/designer.pri33
-rw-r--r--src/extras/designer/images/circulargauge-icon.pngbin0 -> 1542 bytes
-rw-r--r--src/extras/designer/images/circulargauge-icon16.pngbin0 -> 1349 bytes
-rw-r--r--src/extras/designer/images/delaybutton-icon.pngbin0 -> 1509 bytes
-rw-r--r--src/extras/designer/images/delaybutton-icon16.pngbin0 -> 1291 bytes
-rw-r--r--src/extras/designer/images/dial-icon.pngbin0 -> 1467 bytes
-rw-r--r--src/extras/designer/images/dial-icon16.pngbin0 -> 1247 bytes
-rw-r--r--src/extras/designer/images/gauge-icon.pngbin0 -> 1182 bytes
-rw-r--r--src/extras/designer/images/gauge-icon16.pngbin0 -> 1145 bytes
-rw-r--r--src/extras/designer/images/picture-icon.pngbin0 -> 1245 bytes
-rw-r--r--src/extras/designer/images/picture-icon16.pngbin0 -> 1189 bytes
-rw-r--r--src/extras/designer/images/piemenu-icon.pngbin0 -> 1578 bytes
-rw-r--r--src/extras/designer/images/piemenu-icon16.pngbin0 -> 1334 bytes
-rw-r--r--src/extras/designer/images/statusindicator-icon.pngbin0 -> 645 bytes
-rw-r--r--src/extras/designer/images/statusindicator-icon16.pngbin0 -> 404 bytes
-rw-r--r--src/extras/designer/images/togglebutton-icon.pngbin0 -> 1495 bytes
-rw-r--r--src/extras/designer/images/togglebutton-icon16.pngbin0 -> 1298 bytes
-rw-r--r--src/extras/designer/images/tumbler-icon.pngbin0 -> 1188 bytes
-rw-r--r--src/extras/designer/images/tumbler-icon16.pngbin0 -> 1130 bytes
-rw-r--r--src/extras/designer/qtquickextras.metainfo122
-rw-r--r--src/extras/doc/compat/qtquickextras.qdocconf5
-rw-r--r--src/extras/doc/images/circulargauge-angles.pngbin0 -> 19719 bytes
-rw-r--r--src/extras/doc/images/circulargauge-needle-example-2.pngbin0 -> 12680 bytes
-rw-r--r--src/extras/doc/images/circulargauge-needle.pngbin0 -> 1561 bytes
-rw-r--r--src/extras/doc/images/circulargauge-reversed.pngbin0 -> 21836 bytes
-rw-r--r--src/extras/doc/images/circulargauge-tickmark-indices-values.pngbin0 -> 40132 bytes
-rw-r--r--src/extras/doc/images/circulargauge.pngbin0 -> 26247 bytes
-rw-r--r--src/extras/doc/images/delaybutton-activated.pngbin0 -> 18460 bytes
-rw-r--r--src/extras/doc/images/delaybutton-progress.pngbin0 -> 15558 bytes
-rw-r--r--src/extras/doc/images/delaybutton.pngbin0 -> 8354 bytes
-rw-r--r--src/extras/doc/images/dial.pngbin0 -> 14815 bytes
-rw-r--r--src/extras/doc/images/gauge-minorTickmark-example.pngbin0 -> 4780 bytes
-rw-r--r--src/extras/doc/images/gauge-temperature.pngbin0 -> 6055 bytes
-rw-r--r--src/extras/doc/images/gauge-tickmark-example.pngbin0 -> 4882 bytes
-rw-r--r--src/extras/doc/images/gauge.pngbin0 -> 4852 bytes
-rw-r--r--src/extras/doc/images/piemenu-boundingItem-example.pngbin0 -> 30901 bytes
-rw-r--r--src/extras/doc/images/piemenu-boundingItem-null-example.pngbin0 -> 27923 bytes
-rw-r--r--src/extras/doc/images/piemenu-menuitem-example.pngbin0 -> 10606 bytes
-rw-r--r--src/extras/doc/images/piemenu.pngbin0 -> 17205 bytes
-rw-r--r--src/extras/doc/images/qtquickextras-example-dashboard.pngbin0 -> 75060 bytes
-rw-r--r--src/extras/doc/images/qtquickextras-example-flat.pngbin0 -> 20627 bytes
-rw-r--r--src/extras/doc/images/qtquickextras-example-gallery.pngbin0 -> 38319 bytes
-rw-r--r--src/extras/doc/images/statusindicator-active.pngbin0 -> 3434 bytes
-rw-r--r--src/extras/doc/images/statusindicator-green.pngbin0 -> 3753 bytes
-rw-r--r--src/extras/doc/images/statusindicator-inactive.pngbin0 -> 1702 bytes
-rw-r--r--src/extras/doc/images/styling-circulargauge-background-example.pngbin0 -> 13071 bytes
-rw-r--r--src/extras/doc/images/styling-circulargauge-knob-example.pngbin0 -> 13209 bytes
-rw-r--r--src/extras/doc/images/styling-circulargauge-minorTickmark-example.pngbin0 -> 11770 bytes
-rw-r--r--src/extras/doc/images/styling-circulargauge-needle-example.pngbin0 -> 13472 bytes
-rw-r--r--src/extras/doc/images/styling-circulargauge-tickmark-example.pngbin0 -> 12179 bytes
-rw-r--r--src/extras/doc/images/styling-circulargauge-tickmarkLabel-example.pngbin0 -> 12171 bytes
-rw-r--r--src/extras/doc/images/styling-gauge-font-size.pngbin0 -> 4410 bytes
-rw-r--r--src/extras/doc/images/styling-gauge-foreground.pngbin0 -> 3557 bytes
-rw-r--r--src/extras/doc/images/styling-gauge-minorTickmark.pngbin0 -> 3527 bytes
-rw-r--r--src/extras/doc/images/styling-gauge-tickmark.pngbin0 -> 3547 bytes
-rw-r--r--src/extras/doc/images/styling-gauge-valueBar.pngbin0 -> 3691 bytes
-rw-r--r--src/extras/doc/images/togglebutton-checked.pngbin0 -> 11014 bytes
-rw-r--r--src/extras/doc/images/togglebutton-unchecked.pngbin0 -> 10717 bytes
-rw-r--r--src/extras/doc/images/tumbler-flat-style.pngbin0 -> 5896 bytes
-rw-r--r--src/extras/doc/images/tumbler.pngbin0 -> 9856 bytes
-rw-r--r--src/extras/doc/qtquickextras-compat.qdocconf17
-rw-r--r--src/extras/doc/qtquickextras-project.qdocconf59
-rw-r--r--src/extras/doc/qtquickextras.qdocconf4
-rw-r--r--src/extras/doc/snippets/circulargauge-background-range.qml121
-rw-r--r--src/extras/doc/snippets/circulargauge-tickmark-indices-values.qml85
-rw-r--r--src/extras/doc/snippets/styling-gauge.qml93
-rw-r--r--src/extras/doc/src/qtquickextras-examples.qdoc67
-rw-r--r--src/extras/doc/src/qtquickextras-index.qdoc56
-rw-r--r--src/extras/doc/src/qtquickextras-overview.qdoc106
-rw-r--r--src/extras/doc/src/qtquickextras.qdoc48
-rw-r--r--src/extras/doc/src/qtquickextrasstyles-index.qdoc130
-rw-r--r--src/extras/doc/src/styling-circulargauge.qdoc145
-rw-r--r--src/extras/doc/src/styling-gauge.qdoc129
-rw-r--r--src/extras/extras.pro39
-rw-r--r--src/extras/extras.qrc19
-rw-r--r--src/extras/generateresource.prf27
-rw-r--r--src/extras/plugin.cpp116
-rw-r--r--src/extras/plugin.h61
-rw-r--r--src/extras/plugins.qmltypes619
-rw-r--r--src/extras/qmldir4
-rw-r--r--src/extras/qquickpicture.cpp158
-rw-r--r--src/extras/qquickpicture_p.h72
-rw-r--r--src/extras/qquicktriggermode_p.h72
-rw-r--r--src/src.pro3
-rw-r--r--tests/auto/auto.pro2
-rw-r--r--tests/auto/extras/data/PieMenu3Items.qml53
-rw-r--r--tests/auto/extras/data/PieMenu3ItemsKeepOpen.qml54
-rw-r--r--tests/auto/extras/data/PieMenu3ItemsLongPress.qml44
-rw-r--r--tests/auto/extras/data/PieMenuBoundingItem.qml51
-rw-r--r--tests/auto/extras/data/PieMenuRotatedBoundingItem.qml49
-rw-r--r--tests/auto/extras/data/PieMenuVisibleButNoParent.qml12
-rw-r--r--tests/auto/extras/data/PieMenuVisibleOnCompleted.qml14
-rw-r--r--tests/auto/extras/data/TestUtils.js55
-rw-r--r--tests/auto/extras/data/TumblerDatePicker.qml38
-rw-r--r--tests/auto/extras/data/picture.datbin0 -> 186 bytes
-rw-r--r--tests/auto/extras/data/tst_circulargauge.qml93
-rw-r--r--tests/auto/extras/data/tst_circulartickmarklabel.qml318
-rw-r--r--tests/auto/extras/data/tst_common.qml82
-rw-r--r--tests/auto/extras/data/tst_delaybutton.qml194
-rw-r--r--tests/auto/extras/data/tst_dial.qml367
-rw-r--r--tests/auto/extras/data/tst_gauge.qml287
-rw-r--r--tests/auto/extras/data/tst_picture.qml149
-rw-r--r--tests/auto/extras/data/tst_piemenu.qml836
-rw-r--r--tests/auto/extras/data/tst_statusindicator.qml127
-rw-r--r--tests/auto/extras/data/tst_togglebutton.qml65
-rw-r--r--tests/auto/extras/data/tst_tumbler.qml503
-rw-r--r--tests/auto/extras/extras.pro32
-rw-r--r--tests/auto/extras/tst_extras.cpp39
-rw-r--r--tests/auto/paint/paint.pro6
-rw-r--r--tests/auto/paint/tst_paint.cpp107
-rw-r--r--tests/benchmarks/benchmarks.pro3
-rw-r--r--tests/benchmarks/statusindicator/LotsOfIndicatorsActive.qml58
-rw-r--r--tests/benchmarks/statusindicator/LotsOfIndicatorsInactive.qml58
-rw-r--r--tests/benchmarks/statusindicator/statusindicator.pro13
-rw-r--r--tests/benchmarks/statusindicator/tst_statusindicator.cpp82
-rw-r--r--tests/tests.pro2
293 files changed, 24616 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index 7c2ec273..ad328129 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,12 +9,18 @@
/examples/quick/controls/touch/touch
/examples/quick/controls/texteditor/texteditor
/examples/quick/dialogs/systemdialogs/systemdialogs
+/examples/quick/extras/dashboard/dashboard
+/examples/quick/extras/flat/flat
+/examples/quick/extras/gallery/gallery
/tests/auto/activeFocusOnTab/tst_activeFocusOnTab
/tests/auto/controls/tst_controls
/tests/auto/dialogs/tst_dialogs
+/tests/auto/extras/tst_extras
+/tests/auto/paint/tst_paint
/tests/auto/qtdesktop/tst_qtdesktop
/tests/auto/applicationwindow/tst_applicationwindow
/tests/auto/testplugin/QtQuickControlsTests/testplugin.*
+/tests/benchmarks/statusindicator/tst_bench_statusindicator
callgrind.out.*
pcviewer.cfg
diff --git a/examples/examples.pro b/examples/examples.pro
index 266358ca..c80af37f 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -2,3 +2,4 @@ TEMPLATE = subdirs
SUBDIRS += quick/controls
SUBDIRS += quick/dialogs
+SUBDIRS += quick/extras
diff --git a/examples/quick/extras/dashboard/dashboard.pro b/examples/quick/extras/dashboard/dashboard.pro
new file mode 100644
index 00000000..c549250e
--- /dev/null
+++ b/examples/quick/extras/dashboard/dashboard.pro
@@ -0,0 +1,18 @@
+TEMPLATE = app
+TARGET = dashboard
+INCLUDEPATH += .
+QT += quick
+
+SOURCES += \
+ main.cpp
+
+RESOURCES += \
+ dashboard.qrc
+
+OTHER_FILES += \
+ qml/dashboard.qml \
+ qml/DashboardGaugeStyle.qml \
+ qml/IconGaugeStyle.qml \
+ qml/TachometerStyle.qml \
+ qml/TurnIndicator.qml \
+ qml/ValueSource.qml
diff --git a/examples/quick/extras/dashboard/dashboard.qrc b/examples/quick/extras/dashboard/dashboard.qrc
new file mode 100644
index 00000000..605e1678
--- /dev/null
+++ b/examples/quick/extras/dashboard/dashboard.qrc
@@ -0,0 +1,13 @@
+<RCC>
+ <qresource prefix="/">
+ <file>fonts/DejaVuSans.ttf</file>
+ <file>images/fuel-icon.png</file>
+ <file>images/temperature-icon.png</file>
+ <file>qml/dashboard.qml</file>
+ <file>qml/DashboardGaugeStyle.qml</file>
+ <file>qml/IconGaugeStyle.qml</file>
+ <file>qml/TachometerStyle.qml</file>
+ <file>qml/TurnIndicator.qml</file>
+ <file>qml/ValueSource.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/quick/extras/dashboard/fonts/DejaVuSans.ttf b/examples/quick/extras/dashboard/fonts/DejaVuSans.ttf
new file mode 100644
index 00000000..19ed0b46
--- /dev/null
+++ b/examples/quick/extras/dashboard/fonts/DejaVuSans.ttf
Binary files differ
diff --git a/examples/quick/extras/dashboard/images/fuel-icon.png b/examples/quick/extras/dashboard/images/fuel-icon.png
new file mode 100644
index 00000000..f521e905
--- /dev/null
+++ b/examples/quick/extras/dashboard/images/fuel-icon.png
Binary files differ
diff --git a/examples/quick/extras/dashboard/images/temperature-icon.png b/examples/quick/extras/dashboard/images/temperature-icon.png
new file mode 100644
index 00000000..5a4334e0
--- /dev/null
+++ b/examples/quick/extras/dashboard/images/temperature-icon.png
Binary files differ
diff --git a/examples/quick/extras/dashboard/main.cpp b/examples/quick/extras/dashboard/main.cpp
new file mode 100644
index 00000000..035d8932
--- /dev/null
+++ b/examples/quick/extras/dashboard/main.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QGuiApplication>
+#include <QtQml/QQmlApplicationEngine>
+#include <QtGui/QFont>
+#include <QtGui/QFontDatabase>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QFontDatabase::addApplicationFont(":/fonts/DejaVuSans.ttf");
+ app.setFont(QFont("DejaVu Sans"));
+
+ QQmlApplicationEngine engine(QUrl("qrc:/qml/dashboard.qml"));
+ return app.exec();
+}
diff --git a/examples/quick/extras/dashboard/qml/DashboardGaugeStyle.qml b/examples/quick/extras/dashboard/qml/DashboardGaugeStyle.qml
new file mode 100644
index 00000000..c2b43fce
--- /dev/null
+++ b/examples/quick/extras/dashboard/qml/DashboardGaugeStyle.qml
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Extras.Styles 1.3
+
+CircularGaugeStyle {
+ tickmarkInset: toPixels(0.04)
+ minorTickmarkInset: tickmarkInset
+ labelStepSize: 20
+ labelInset: toPixels(0.23)
+
+ property real xCenter: outerRadius
+ property real yCenter: outerRadius
+ property real needleLength: outerRadius - tickmarkInset * 1.25
+ property real needleTipWidth: toPixels(0.02)
+ property real needleBaseWidth: toPixels(0.06)
+ property bool halfGauge: false
+
+ function toPixels(percentage) {
+ return percentage * outerRadius;
+ }
+
+ function degToRad(degrees) {
+ return degrees * (Math.PI / 180);
+ }
+
+ function radToDeg(radians) {
+ return radians * (180 / Math.PI);
+ }
+
+ function paintBackground(ctx) {
+ if (halfGauge) {
+ ctx.beginPath();
+ ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height / 2);
+ ctx.clip();
+ }
+
+ ctx.beginPath();
+ ctx.fillStyle = "black";
+ ctx.ellipse(0, 0, ctx.canvas.width, ctx.canvas.height);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.lineWidth = tickmarkInset;
+ ctx.strokeStyle = "black";
+ ctx.arc(xCenter, yCenter, outerRadius - ctx.lineWidth / 2, outerRadius - ctx.lineWidth / 2, 0, Math.PI * 2);
+ ctx.stroke();
+
+ ctx.beginPath();
+ ctx.lineWidth = tickmarkInset / 2;
+ ctx.strokeStyle = "#222";
+ ctx.arc(xCenter, yCenter, outerRadius - ctx.lineWidth / 2, outerRadius - ctx.lineWidth / 2, 0, Math.PI * 2);
+ ctx.stroke();
+
+ ctx.beginPath();
+ var gradient = ctx.createRadialGradient(xCenter, yCenter, outerRadius * 0.8, xCenter, yCenter, outerRadius);
+ gradient.addColorStop(0, Qt.rgba(1, 1, 1, 0));
+ gradient.addColorStop(0.7, Qt.rgba(1, 1, 1, 0.13));
+ gradient.addColorStop(1, Qt.rgba(1, 1, 1, 1));
+ ctx.fillStyle = gradient;
+ ctx.arc(xCenter, yCenter, outerRadius - tickmarkInset, outerRadius - tickmarkInset, 0, Math.PI * 2);
+ ctx.fill();
+ }
+
+ background: Canvas {
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+ paintBackground(ctx);
+ }
+
+ Text {
+ id: speedText
+ font.pixelSize: toPixels(0.3)
+ text: kphInt
+ color: "white"
+ horizontalAlignment: Text.AlignRight
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.verticalCenter
+ anchors.topMargin: toPixels(0.1)
+
+ readonly property int kphInt: control.value
+ }
+ Text {
+ text: "km/h"
+ color: "white"
+ font.pixelSize: toPixels(0.09)
+ anchors.top: speedText.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ }
+
+ needle: Canvas {
+ implicitWidth: needleBaseWidth
+ implicitHeight: needleLength
+
+ property real xCenter: width / 2
+ property real yCenter: height / 2
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ ctx.beginPath();
+ ctx.moveTo(xCenter, height);
+ ctx.lineTo(xCenter - needleBaseWidth / 2, height - needleBaseWidth / 2);
+ ctx.lineTo(xCenter - needleTipWidth / 2, 0);
+ ctx.lineTo(xCenter, yCenter - needleLength);
+ ctx.lineTo(xCenter, 0);
+ ctx.closePath();
+ ctx.fillStyle = Qt.rgba(0.66, 0, 0, 0.66);
+ ctx.fill();
+
+ ctx.beginPath();
+ ctx.moveTo(xCenter, height)
+ ctx.lineTo(width, height - needleBaseWidth / 2);
+ ctx.lineTo(xCenter + needleTipWidth / 2, 0);
+ ctx.lineTo(xCenter, 0);
+ ctx.closePath();
+ ctx.fillStyle = Qt.lighter(Qt.rgba(0.66, 0, 0, 0.66));
+ ctx.fill();
+ }
+ }
+
+ foreground: null
+}
diff --git a/examples/quick/extras/dashboard/qml/IconGaugeStyle.qml b/examples/quick/extras/dashboard/qml/IconGaugeStyle.qml
new file mode 100644
index 00000000..4bf4751d
--- /dev/null
+++ b/examples/quick/extras/dashboard/qml/IconGaugeStyle.qml
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+
+DashboardGaugeStyle {
+ id: fuelGaugeStyle
+ minimumValueAngle: -60
+ maximumValueAngle: 60
+ tickmarkStepSize: 1
+ labelStepSize: 1
+ labelInset: toPixels(-0.25)
+ minorTickmarkCount: 3
+
+ needleLength: toPixels(0.85)
+ needleBaseWidth: toPixels(0.08)
+ needleTipWidth: toPixels(0.03)
+
+ halfGauge: true
+
+ property string icon: ""
+ property color minWarningColor: "transparent"
+ property color maxWarningColor: "transparent"
+ readonly property real minWarningStartAngle: minimumValueAngle - 90
+ readonly property real maxWarningStartAngle: maximumValueAngle - 90
+
+ tickmark: Rectangle {
+ implicitWidth: toPixels(0.06)
+ antialiasing: true
+ implicitHeight: toPixels(0.2)
+ color: "#c8c8c8"
+ }
+
+ minorTickmark: Rectangle {
+ implicitWidth: toPixels(0.03)
+ antialiasing: true
+ implicitHeight: toPixels(0.15)
+ color: "#c8c8c8"
+ }
+
+ background: Item {
+ Canvas {
+ anchors.fill: parent
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ paintBackground(ctx);
+
+ if (minWarningColor != "transparent") {
+ ctx.beginPath();
+ ctx.lineWidth = fuelGaugeStyle.toPixels(0.08);
+ ctx.strokeStyle = minWarningColor;
+ ctx.arc(outerRadius, outerRadius,
+ // Start the line in from the decorations, and account for the width of the line itself.
+ outerRadius - tickmarkInset - ctx.lineWidth / 2,
+ degToRad(minWarningStartAngle),
+ degToRad(minWarningStartAngle + angleRange / (minorTickmarkCount + 1)), false);
+ ctx.stroke();
+ }
+ if (maxWarningColor != "transparent") {
+ ctx.beginPath();
+ ctx.lineWidth = fuelGaugeStyle.toPixels(0.08);
+ ctx.strokeStyle = maxWarningColor;
+ ctx.arc(outerRadius, outerRadius,
+ // Start the line in from the decorations, and account for the width of the line itself.
+ outerRadius - tickmarkInset - ctx.lineWidth / 2,
+ degToRad(maxWarningStartAngle - angleRange / (minorTickmarkCount + 1)),
+ degToRad(maxWarningStartAngle), false);
+ ctx.stroke();
+ }
+ }
+ }
+
+ Image {
+ source: icon
+ anchors.bottom: parent.verticalCenter
+ anchors.bottomMargin: toPixels(0.3)
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: toPixels(0.3)
+ height: width
+ fillMode: Image.PreserveAspectFit
+ }
+ }
+}
diff --git a/examples/quick/extras/dashboard/qml/TachometerStyle.qml b/examples/quick/extras/dashboard/qml/TachometerStyle.qml
new file mode 100644
index 00000000..40ef157a
--- /dev/null
+++ b/examples/quick/extras/dashboard/qml/TachometerStyle.qml
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+
+DashboardGaugeStyle {
+ id: tachometerStyle
+ tickmarkStepSize: 1
+ labelStepSize: 1
+ needleLength: toPixels(0.85)
+ needleBaseWidth: toPixels(0.08)
+ needleTipWidth: toPixels(0.03)
+
+ tickmark: Rectangle {
+ implicitWidth: toPixels(0.03)
+ antialiasing: true
+ implicitHeight: toPixels(0.08)
+ color: styleData.index === 7 || styleData.index === 8 ? Qt.rgba(0.5, 0, 0, 1) : "#c8c8c8"
+ }
+
+ minorTickmark: null
+
+ tickmarkLabel: Text {
+ font.pixelSize: Math.max(6, toPixels(0.12))
+ text: styleData.value
+ color: styleData.index === 7 || styleData.index === 8 ? Qt.rgba(0.5, 0, 0, 1) : "#c8c8c8"
+ antialiasing: true
+ }
+
+ background: Canvas {
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+ paintBackground(ctx);
+
+ ctx.beginPath();
+ ctx.lineWidth = tachometerStyle.toPixels(0.08);
+ ctx.strokeStyle = Qt.rgba(0.5, 0, 0, 1);
+ var warningCircumference = maximumValueAngle - minimumValueAngle * 0.1;
+ var startAngle = maximumValueAngle - 90;
+ ctx.arc(outerRadius, outerRadius,
+ // Start the line in from the decorations, and account for the width of the line itself.
+ outerRadius - tickmarkInset - ctx.lineWidth / 2,
+ degToRad(startAngle - angleRange / 8 + angleRange * 0.015),
+ degToRad(startAngle - angleRange * 0.015), false);
+ ctx.stroke();
+ }
+
+ Text {
+ id: rpmText
+ font.pixelSize: tachometerStyle.toPixels(0.3)
+ text: rpmInt
+ color: "white"
+ horizontalAlignment: Text.AlignRight
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.verticalCenter
+ anchors.topMargin: 20
+
+ readonly property int rpmInt: valueSource.rpm
+ }
+ Text {
+ text: "x1000"
+ color: "white"
+ font.pixelSize: tachometerStyle.toPixels(0.1)
+ anchors.top: parent.top
+ anchors.topMargin: parent.height / 4
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ Text {
+ text: "RPM"
+ color: "white"
+ font.pixelSize: tachometerStyle.toPixels(0.1)
+ anchors.top: rpmText.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ }
+}
diff --git a/examples/quick/extras/dashboard/qml/TurnIndicator.qml b/examples/quick/extras/dashboard/qml/TurnIndicator.qml
new file mode 100644
index 00000000..960d27e7
--- /dev/null
+++ b/examples/quick/extras/dashboard/qml/TurnIndicator.qml
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Extras.Styles 1.3
+
+Item {
+ // This enum is actually keyboard-related, but it serves its purpose
+ // as an indication of direction for us.
+ property int direction: Qt.LeftArrow
+ property bool on: false
+
+ property bool flashing: false
+
+ scale: direction === Qt.LeftArrow ? 1 : -1
+
+ Timer {
+ id: flashTimer
+ interval: 500
+ running: on
+ repeat: true
+ onTriggered: flashing = !flashing
+ }
+
+ function paintOutlinePath(ctx) {
+ ctx.beginPath();
+ ctx.moveTo(0, height * 0.5);
+ ctx.lineTo(0.6 * width, 0);
+ ctx.lineTo(0.6 * width, height * 0.28);
+ ctx.lineTo(width, height * 0.28);
+ ctx.lineTo(width, height * 0.72);
+ ctx.lineTo(0.6 * width, height * 0.72);
+ ctx.lineTo(0.6 * width, height);
+ ctx.lineTo(0, height * 0.5);
+ }
+
+ Canvas {
+ id: backgroundCanvas
+ anchors.fill: parent
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ paintOutlinePath(ctx);
+
+ ctx.lineWidth = 1;
+ ctx.strokeStyle = "black";
+ ctx.stroke();
+ }
+ }
+
+ Canvas {
+ id: foregroundCanvas
+ anchors.fill: parent
+ visible: on && flashing
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ paintOutlinePath(ctx);
+
+ ctx.fillStyle = "green";
+ ctx.fill();
+ }
+ }
+}
diff --git a/examples/quick/extras/dashboard/qml/ValueSource.qml b/examples/quick/extras/dashboard/qml/ValueSource.qml
new file mode 100644
index 00000000..6f762724
--- /dev/null
+++ b/examples/quick/extras/dashboard/qml/ValueSource.qml
@@ -0,0 +1,320 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+
+Item {
+ id: valueSource
+ property real kph: 0
+ property real rpm: 1
+ property real fuel: 0.85
+ property string gear: {
+ var g;
+ if (kph == 0) {
+ return "P";
+ }
+ if (kph < 30) {
+ return "1";
+ }
+ if (kph < 50) {
+ return "2";
+ }
+ if (kph < 80) {
+ return "3";
+ }
+ if (kph < 120) {
+ return "4";
+ }
+ if (kph < 160) {
+ return "5";
+ }
+ }
+ property int turnSignal: gear == "P" && !start ? randomDirection() : -1
+ property real temperature: 0.6
+ property bool start: true
+
+ function randomDirection() {
+ return Math.random() > 0.5 ? Qt.LeftArrow : Qt.RightArrow;
+ }
+
+ SequentialAnimation {
+ running: true
+ loops: 1
+
+ // We want a small pause at the beginning, but we only want it to happen once.
+ PauseAnimation {
+ duration: 1000
+ }
+
+ PropertyAction {
+ target: valueSource
+ property: "start"
+ value: false
+ }
+
+ SequentialAnimation {
+ loops: Animation.Infinite
+
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ from: 0
+ to: 30
+ duration: 3000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ from: 1
+ to: 6.1
+ duration: 3000
+ }
+ }
+ ParallelAnimation {
+ // We changed gears so we lost a bit of speed.
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ from: 30
+ to: 26
+ duration: 600
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ from: 6
+ to: 2.4
+ duration: 600
+ }
+ }
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 60
+ duration: 3000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 5.6
+ duration: 3000
+ }
+ }
+ ParallelAnimation {
+ // We changed gears so we lost a bit of speed.
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 56
+ duration: 600
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 2.3
+ duration: 600
+ }
+ }
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 100
+ duration: 3000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 5.1
+ duration: 3000
+ }
+ }
+ ParallelAnimation {
+ // We changed gears so we lost a bit of speed.
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 96
+ duration: 600
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 2.2
+ duration: 600
+ }
+ }
+
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 140
+ duration: 3000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 6.2
+ duration: 3000
+ }
+ }
+
+ // Start downshifting.
+
+ // Fifth to fourth gear.
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.Linear
+ to: 100
+ duration: 5000
+ }
+
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 3.1
+ duration: 5000
+ }
+ }
+
+ // Fourth to third gear.
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 5.5
+ duration: 600
+ }
+
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 60
+ duration: 5000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 2.6
+ duration: 5000
+ }
+ }
+
+ // Third to second gear.
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 6.3
+ duration: 600
+ }
+
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 30
+ duration: 5000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 2.6
+ duration: 5000
+ }
+ }
+
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 6.5
+ duration: 600
+ }
+
+ // Second to first gear.
+ ParallelAnimation {
+ NumberAnimation {
+ target: valueSource
+ property: "kph"
+ easing.type: Easing.InOutSine
+ to: 0
+ duration: 5000
+ }
+ NumberAnimation {
+ target: valueSource
+ property: "rpm"
+ easing.type: Easing.InOutSine
+ to: 1
+ duration: 4500
+ }
+ }
+
+ PauseAnimation {
+ duration: 5000
+ }
+ }
+ }
+}
diff --git a/examples/quick/extras/dashboard/qml/dashboard.qml b/examples/quick/extras/dashboard/qml/dashboard.qml
new file mode 100644
index 00000000..d18e7bc6
--- /dev/null
+++ b/examples/quick/extras/dashboard/qml/dashboard.qml
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Window 2.1
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Styles 1.1
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+
+Window {
+ id: root
+ visible: true
+ width: 1024
+ height: 600
+
+ color: "#161616"
+ title: "Qt Quick Extras Demo"
+
+ ValueSource {
+ id: valueSource
+ }
+
+ // Dashboards are typically in a landscape orientation, so we need to ensure
+ // our height is never greater than our width.
+ Item {
+ id: container
+ width: root.width
+ height: Math.min(root.width, root.height)
+ anchors.centerIn: parent
+
+ Row {
+ id: gaugeRow
+ spacing: container.width * 0.02
+ anchors.centerIn: parent
+
+ TurnIndicator {
+ id: leftIndicator
+ anchors.verticalCenter: parent.verticalCenter
+ width: height
+ height: container.height * 0.1 - gaugeRow.spacing
+
+ direction: Qt.LeftArrow
+ on: valueSource.turnSignal == Qt.LeftArrow
+ }
+
+ Item {
+ width: height
+ height: container.height * 0.25 - gaugeRow.spacing
+ anchors.verticalCenter: parent.verticalCenter
+
+ CircularGauge {
+ id: fuelGauge
+ value: valueSource.fuel
+ maximumValue: 1
+ y: parent.height / 2 - height / 2 - container.height * 0.01
+ width: parent.width
+ height: parent.height * 0.7
+
+ style: IconGaugeStyle {
+ id: fuelGaugeStyle
+
+ icon: "qrc:/images/fuel-icon.png"
+ minWarningColor: Qt.rgba(0.5, 0, 0, 1)
+
+ tickmarkLabel: Text {
+ color: "white"
+ visible: styleData.value === 0 || styleData.value === 1
+ font.pixelSize: fuelGaugeStyle.toPixels(0.225)
+ text: styleData.value === 0 ? "E" : (styleData.value === 1 ? "F" : "")
+ }
+ }
+ }
+
+ CircularGauge {
+ value: valueSource.temperature
+ maximumValue: 1
+ width: parent.width
+ height: parent.height * 0.7
+ y: parent.height / 2 + container.height * 0.01
+
+ style: IconGaugeStyle {
+ id: tempGaugeStyle
+
+ icon: "qrc:/images/temperature-icon.png"
+ maxWarningColor: Qt.rgba(0.5, 0, 0, 1)
+
+ tickmarkLabel: Text {
+ color: "white"
+ visible: styleData.value === 0 || styleData.value === 1
+ font.pixelSize: tempGaugeStyle.toPixels(0.225)
+ text: styleData.value === 0 ? "C" : (styleData.value === 1 ? "H" : "")
+ }
+ }
+ }
+ }
+
+ CircularGauge {
+ id: speedometer
+ value: valueSource.kph
+ anchors.verticalCenter: parent.verticalCenter
+ maximumValue: 280
+ // We set the width to the height, because the height will always be
+ // the more limited factor. Also, all circular controls letterbox
+ // their contents to ensure that they remain circular. However, we
+ // don't want to extra space on the left and right of our gauges,
+ // because they're laid out horizontally, and that would create
+ // large horizontal gaps between gauges on wide screens.
+ width: height
+ height: container.height * 0.5
+
+ style: DashboardGaugeStyle {}
+ }
+
+ CircularGauge {
+ id: tachometer
+ width: height
+ height: container.height * 0.25 - gaugeRow.spacing
+ value: valueSource.rpm
+ maximumValue: 8
+ anchors.verticalCenter: parent.verticalCenter
+
+ style: TachometerStyle {}
+ }
+
+ TurnIndicator {
+ id: rightIndicator
+ anchors.verticalCenter: parent.verticalCenter
+ width: height
+ height: container.height * 0.1 - gaugeRow.spacing
+
+ direction: Qt.RightArrow
+ on: valueSource.turnSignal == Qt.RightArrow
+ }
+
+ }
+ }
+}
diff --git a/examples/quick/extras/extras.pro b/examples/quick/extras/extras.pro
new file mode 100644
index 00000000..7f7b7215
--- /dev/null
+++ b/examples/quick/extras/extras.pro
@@ -0,0 +1,5 @@
+TEMPLATE = subdirs
+SUBDIRS += \
+ gallery \
+ dashboard \
+ flat
diff --git a/examples/quick/extras/flat/Content.qml b/examples/quick/extras/flat/Content.qml
new file mode 100644
index 00000000..dcef1f1c
--- /dev/null
+++ b/examples/quick/extras/flat/Content.qml
@@ -0,0 +1,707 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtQuick.Layouts 1.1
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles.Flat 1.0 as Flat
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.XmlListModel 2.0
+
+Item {
+ anchors.fill: parent
+
+ Text {
+ id: text
+ visible: false
+ }
+
+ FontMetrics {
+ id: fontMetrics
+ font.family: Flat.FlatStyle.fontFamily
+ }
+
+ readonly property int layoutSpacing: Math.round(5 * Flat.FlatStyle.scaleFactor)
+
+ property var componentModel: [
+ { name: "Buttons", component: buttonsComponent },
+ { name: "Calendar", component: calendarComponent },
+ { name: "DelayButton", component: delayButtonComponent },
+ { name: "Dial", component: dialComponent },
+ { name: "Input", component: inputComponent },
+ { name: "PieMenu", component: pieMenuComponent },
+ { name: "Progress", component: progressComponent },
+ { name: "TableView", component: tableViewComponent },
+ { name: "TextArea", component: textAreaComponent },
+ { name: "Tumbler", component: tumblerComponent }
+ ]
+
+ Loader {
+ id: componentLoader
+ anchors.fill: parent
+ sourceComponent: componentModel[controlData.componentIndex].component
+ }
+
+ property Component buttonsComponent: ScrollView {
+ id: scrollView
+ horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
+
+ Flickable {
+ anchors.fill: parent
+ contentWidth: viewport.width
+ contentHeight: buttoncolumn.implicitHeight + textMargins * 1.5
+ ColumnLayout {
+ id: buttoncolumn
+ anchors.fill: parent
+ anchors.margins: textMargins
+ anchors.topMargin: textMargins / 2
+ spacing: textMargins / 2
+ enabled: !settingsData.allDisabled
+
+ GroupBox {
+ title: "Button"
+ checkable: settingsData.checks
+ flat: !settingsData.frames
+ Layout.fillWidth: true
+ GridLayout {
+ columns: Math.max(1, Math.floor(scrollView.width / button.implicitWidth - 0.5))
+ Button {
+ id: button
+ text: "Normal"
+ }
+ Button {
+ text: "Default"
+ isDefault: true
+ }
+ Button {
+ text: "Checkable"
+ checkable: true
+ }
+ Button {
+ text: "Menu"
+ menu: Menu {
+ MenuItem { text: "Normal"; shortcut: "Ctrl+N" }
+ MenuSeparator { }
+ MenuItem { text: "Checkable 1"; checkable: true; checked: true }
+ MenuItem { text: "Checkable 2"; checkable: true; checked: true }
+ MenuSeparator { }
+ }
+ visible: Qt.application.supportsMultipleWindows
+ }
+ }
+ }
+
+ GroupBox {
+ title: "RadioButton"
+ checkable: settingsData.checks
+ flat: !settingsData.frames
+ Layout.fillWidth: true
+ ExclusiveGroup { id: radiobuttongroup }
+ ColumnLayout {
+ anchors.fill: parent
+ Repeater {
+ model: ["First", "Second", "Third"]
+ RadioButton {
+ text: modelData
+ checked: index === 0
+ exclusiveGroup: radiobuttongroup
+ Layout.fillWidth: true
+ }
+ }
+ }
+ }
+
+ GroupBox {
+ title: "CheckBox"
+ checkable: settingsData.checks
+ flat: !settingsData.frames
+ Layout.fillWidth: true
+ ColumnLayout {
+ anchors.fill: parent
+ Repeater {
+ model: ["First", "Second", "Third"]
+ CheckBox {
+ text: modelData
+ checked: index === 0
+ Layout.fillWidth: true
+ }
+ }
+ }
+ }
+
+ GroupBox {
+ title: "Switch"
+ checkable: settingsData.checks
+ flat: !settingsData.frames
+ Layout.fillWidth: true
+ ColumnLayout {
+ anchors.fill: parent
+ Repeater {
+ model: ["First", "Second", "Third"]
+ RowLayout {
+ spacing: layoutSpacing * 2
+ Label {
+ text: modelData
+ font.family: Flat.FlatStyle.fontFamily
+ renderType: Text.QtRendering
+ Layout.preferredWidth: fontMetrics.advanceWidth("Second")
+ }
+ Switch { checked: index == 0 }
+ }
+ }
+ }
+ }
+
+ GroupBox {
+ title: "ToggleButton"
+ checkable: settingsData.checks
+ flat: !settingsData.frames
+ Layout.fillWidth: true
+ GridLayout {
+ columns: Math.max(1, !!children[0] ? Math.floor(scrollView.width / children[0].implicitWidth - 0.5) : children.length)
+ ToggleButton {
+ text: "Pump 1"
+ checked: true
+ }
+ ToggleButton {
+ text: "Pump 2"
+ checked: false
+ }
+ }
+ }
+
+ GroupBox {
+ title: "StatusIndicator"
+ checkable: settingsData.checks
+ flat: !settingsData.frames
+ Layout.fillWidth: true
+ GridLayout {
+ columns: Math.max(1, Math.floor(scrollView.width / recordButton.implicitWidth - 0.5))
+ columnSpacing: layoutSpacing * 4
+
+ Button {
+ id: recordButton
+ text: "Record"
+ Layout.alignment: Qt.AlignTop
+ onClicked: recordStatusIndicator.active = !recordStatusIndicator.active
+
+ StatusIndicator {
+ id: recordStatusIndicator
+ active: false
+ anchors.left: parent.left
+ anchors.leftMargin: Math.max(6, Math.round(text.implicitHeight * 0.4))
+ anchors.verticalCenter: parent.verticalCenter
+ rotation: 90
+ }
+ }
+ ColumnLayout {
+ Repeater {
+ model: 3
+ delegate: RowLayout {
+ Layout.alignment: Qt.AlignCenter
+ StatusIndicator {
+ active: true
+ color: "#f09116"
+ }
+ Label {
+ text: "Camera " + (index + 1)
+ font.family: Flat.FlatStyle.fontFamily
+ renderType: Text.QtRendering
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ property Component progressComponent: ScrollView {
+ id: scrollView
+ horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
+ Flickable {
+ anchors.fill: parent
+ contentWidth: viewport.width
+ contentHeight: progresscolumn.implicitHeight + textMargins * 1.5
+ ColumnLayout {
+ id: progresscolumn
+ anchors.fill: parent
+ anchors.leftMargin: textMargins
+ anchors.rightMargin: textMargins
+ anchors.bottomMargin: textMargins
+ anchors.topMargin: textMargins / 2
+ spacing: textMargins / 2
+ enabled: !settingsData.allDisabled
+
+ GroupBox {
+ title: "BusyIndicator"
+ checkable: settingsData.checks
+ flat: !settingsData.frames
+ Layout.fillWidth: true
+ BusyIndicator {
+ id: busyindicator
+ anchors.centerIn: parent
+ running: scrollView.visible
+ }
+ }
+
+ GroupBox {
+ title: "ProgressBar"
+ checkable: settingsData.checks
+ flat: !settingsData.frames
+ Layout.fillWidth: true
+ ColumnLayout {
+ anchors.fill: parent
+ ProgressBar {
+ value: slider.value
+ maximumValue: slider.maximumValue
+ Layout.fillWidth: true
+ }
+ ProgressBar {
+ indeterminate: true
+ value: slider.value
+ maximumValue: slider.maximumValue
+ Layout.fillWidth: true
+ }
+ }
+ }
+
+ GroupBox {
+ title: "Slider"
+ checkable: settingsData.checks
+ flat: !settingsData.frames
+ Layout.fillWidth: true
+ ColumnLayout {
+ anchors.fill: parent
+ Slider {
+ id: slider
+ // TODO: can't use maximumValue / 2 here, otherwise the gauges
+ // initially show up as empty; find out why.
+ value: 50
+ // If we use the default value of 1 here, we run into QTBUG-42358,
+ // even though that report specifically uses 100 as an example...
+ maximumValue: 100
+ Layout.fillWidth: true
+ }
+ }
+ }
+
+ GroupBox {
+ title: "Gauge"
+ checkable: settingsData.checks
+ flat: !settingsData.frames
+ Layout.fillWidth: true
+ Gauge {
+ id: gauge
+ value: slider.value * 1.4
+ orientation: window.width < window.height ? Qt.Vertical : Qt.Horizontal
+ minimumValue: slider.minimumValue * 1.4
+ maximumValue: slider.maximumValue * 1.4
+ tickmarkStepSize: 20
+
+ anchors.centerIn: parent
+ }
+ }
+
+ GroupBox {
+ title: "CircularGauge"
+ checkable: settingsData.checks
+ flat: !settingsData.frames
+ Layout.fillWidth: true
+ Layout.minimumWidth: 0
+ CircularGauge {
+ id: circularGauge
+ value: slider.value * 3.2
+ minimumValue: slider.minimumValue * 3.2
+ maximumValue: slider.maximumValue * 3.2
+
+ anchors.centerIn: parent
+ width: Math.min(implicitWidth, parent.width)
+ height: Math.min(implicitHeight, parent.height)
+
+ style: Flat.CircularGaugeStyle {
+ tickmarkStepSize: 20
+ labelStepSize: 40
+ minorTickmarkCount: 2
+ }
+
+ Column {
+ anchors.centerIn: parent
+
+ Label {
+ text: Math.floor(circularGauge.value)
+ anchors.horizontalCenter: parent.horizontalCenter
+ renderType: Text.QtRendering
+ font.pixelSize: unitLabel.font.pixelSize * 2
+ font.family: Flat.FlatStyle.fontFamily
+ font.weight: Font.Light
+ }
+ Label {
+ id: unitLabel
+ text: "km/h"
+ renderType: Text.QtRendering
+ font.family: Flat.FlatStyle.fontFamily
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ property Component inputComponent: ScrollView {
+ id: scrollView
+ horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
+ Flickable {
+ anchors.fill: parent
+ contentWidth: viewport.width
+ contentHeight: inputcolumn.implicitHeight + textMargins * 1.5
+ ColumnLayout {
+ id: inputcolumn
+ anchors.fill: parent
+ anchors.margins: textMargins
+ spacing: textMargins / 2
+ enabled: !settingsData.allDisabled
+
+ GroupBox {
+ title: "TextField"
+ checkable: settingsData.checks
+ flat: !settingsData.frames
+ Layout.fillWidth: true
+ ColumnLayout {
+ anchors.fill: parent
+ TextField {
+ z: 1
+ placeholderText: "TextField"
+ Layout.fillWidth: true
+ }
+ TextField {
+ placeholderText: "Password"
+ echoMode: TextInput.Password // TODO: PasswordEchoOnEdit
+ Layout.fillWidth: true
+ }
+ }
+ }
+
+ GroupBox {
+ title: "ComboBox"
+ checkable: settingsData.checks
+ flat: !settingsData.frames
+ Layout.fillWidth: true
+ visible: Qt.application.supportsMultipleWindows
+ ColumnLayout {
+ anchors.fill: parent
+ ComboBox {
+ model: ["Option 1", "Option 2", "Option 3"]
+ Layout.fillWidth: true
+ }
+ ComboBox {
+ editable: true
+ model: ListModel {
+ id: combomodel
+ ListElement { text: "Option 1" }
+ ListElement { text: "Option 2" }
+ ListElement { text: "Option 3" }
+ }
+ onAccepted: {
+ if (find(currentText) === -1) {
+ combomodel.append({text: editText})
+ currentIndex = find(editText)
+ }
+ }
+ Layout.fillWidth: true
+ }
+ }
+ }
+
+ GroupBox {
+ title: "SpinBox"
+ checkable: settingsData.checks
+ flat: !settingsData.frames
+ Layout.fillWidth: true
+ GridLayout {
+ anchors.fill: parent
+ columns: Math.max(1, Math.floor(scrollView.width / spinbox.implicitWidth - 0.5))
+ SpinBox {
+ id: spinbox
+ Layout.fillWidth: true
+ }
+ SpinBox {
+ decimals: 1
+ Layout.fillWidth: true
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Component {
+ id: tableViewComponent
+ TableView {
+ id: view
+ enabled: !settingsData.allDisabled
+ TableViewColumn {
+ role: "title"
+ title: "Title"
+ width: view.width / 2
+ resizable: false
+ movable: false
+ }
+ TableViewColumn {
+ role: "author"
+ title: "Author"
+ width: view.width / 2
+ resizable: false
+ movable: false
+ }
+
+ frameVisible: false
+ backgroundVisible: true
+ alternatingRowColors: false
+ model: ListModel {
+ ListElement {
+ title: "Moby-Dick"
+ author: "Herman Melville"
+ }
+ ListElement {
+ title: "The Adventures of Tom Sawyer"
+ author: "Mark Twain"
+ }
+ ListElement {
+ title: "Cat’s Cradle"
+ author: "Kurt Vonnegut"
+ }
+ ListElement {
+ title: "Farenheit 451"
+ author: "Ray Bradbury"
+ }
+ ListElement {
+ title: "It"
+ author: "Stephen King"
+ }
+ ListElement {
+ title: "On the Road"
+ author: "Jack Kerouac"
+ }
+ ListElement {
+ title: "Of Mice and Men"
+ author: "John Steinbeck"
+ }
+ ListElement {
+ title: "Do Androids Dream of Electric Sheep?"
+ author: "Philip K. Dick"
+ }
+ ListElement {
+ title: "Uncle Tom’s Cabin"
+ author: "Harriet Beecher Stowe"
+ }
+ ListElement {
+ title: "The Call of the Wild"
+ author: "Jack London"
+ }
+ ListElement {
+ title: "The Old Man and the Sea"
+ author: "Ernest Hemingway"
+ }
+ ListElement {
+ title: "A Streetcar Named Desire"
+ author: "Tennessee Williams"
+ }
+ ListElement {
+ title: "Catch-22"
+ author: "Joseph Heller"
+ }
+ ListElement {
+ title: "One Flew Over the Cuckoo’s Nest"
+ author: "Ken Kesey"
+ }
+ ListElement {
+ title: "The Murders in the Rue Morgue"
+ author: "Edgar Allan Poe"
+ }
+ ListElement {
+ title: "Breakfast at Tiffany’s"
+ author: "Truman Capote"
+ }
+ ListElement {
+ title: "Death of a Salesman"
+ author: "Arthur Miller"
+ }
+ ListElement {
+ title: "Post Office"
+ author: "Charles Bukowski"
+ }
+ ListElement {
+ title: "Herbert West—Reanimator"
+ author: "H. P. Lovecraft"
+ }
+ }
+ }
+ }
+ Component {
+ id: calendarComponent
+ Item {
+ enabled: !settingsData.allDisabled
+ Calendar {
+ anchors.centerIn: parent
+ weekNumbersVisible: true
+ frameVisible: settingsData.frames
+ }
+ }
+ }
+ Component {
+ id: textAreaComponent
+ TextArea {
+ enabled: !settingsData.allDisabled
+ frameVisible: false
+ flickableItem.flickableDirection: Flickable.VerticalFlick
+ text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum quis justo a sem faucibus mattis nec vitae nisi. Fusce fringilla nulla a tellus vehicula sodales. Etiam volutpat suscipit erat vitae adipiscing. Sed vestibulum massa nisl, eget posuere urna porta ac. Morbi at nunc ligula. Cras et mauris aliquet ligula sodales suscipit eget imperdiet augue. Ut eget dui eu magna malesuada imperdiet. Donec imperdiet urna eu consequat ornare. Cras at metus tristique, ullamcorper nisl ut, faucibus mauris. Fusce in euismod arcu. Donec tristique rutrum porta. Praesent mattis ac tortor quis scelerisque. Integer luctus nulla ut lacinia tempus."
+ }
+ }
+ Component {
+ id: pieMenuComponent
+ Item {
+ enabled: !settingsData.allDisabled
+
+ Column {
+ anchors.fill: parent
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: controlData.textMargins
+ spacing: Math.round(controlData.textMargins * 0.5)
+
+ Image {
+ id: pieMenuImage
+ source: "qrc:/images/piemenu-image-rgb.jpg"
+ fillMode: Image.PreserveAspectFit
+ width: parent.width
+ height: Math.min((width / sourceSize.width) * sourceSize.height, (parent.height - parent.spacing) * 0.88)
+ }
+ Item {
+ width: parent.width
+ height: parent.height - pieMenuImage.height - parent.spacing
+
+ Text {
+ id: instructionText
+ anchors.fill: parent
+ anchors.leftMargin: controlData.textMargins
+ anchors.rightMargin: controlData.textMargins
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ text: "Tap and hold to open menu"
+ font.family: Flat.FlatStyle.fontFamily
+ font.pixelSize: Math.round(20 * Flat.FlatStyle.scaleFactor)
+ fontSizeMode: Text.Fit
+ color: Flat.FlatStyle.lightFrameColor
+ }
+ }
+ }
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onPressAndHold: pieMenu.popup(mouse.x, mouse.y)
+ }
+ PieMenu {
+ id: pieMenu
+ triggerMode: TriggerMode.TriggerOnClick
+
+ MenuItem {
+ iconSource: "qrc:/images/piemenu-rgb-" + (pieMenu.currentIndex === 0 ? "pressed" : "normal") + ".png"
+ onTriggered: pieMenuImage.source = "qrc:/images/piemenu-image-rgb.jpg"
+ }
+ MenuItem {
+ iconSource: "qrc:/images/piemenu-bw-" + (pieMenu.currentIndex === 1 ? "pressed" : "normal") + ".png"
+ onTriggered: pieMenuImage.source = "qrc:/images/piemenu-image-bw.jpg"
+ }
+ MenuItem {
+ iconSource: "qrc:/images/piemenu-sepia-" + (pieMenu.currentIndex === 2 ? "pressed" : "normal") + ".png"
+ onTriggered: pieMenuImage.source = "qrc:/images/piemenu-image-sepia.jpg"
+ }
+ }
+ }
+ }
+ Component {
+ id: delayButtonComponent
+ Item {
+ enabled: !settingsData.allDisabled
+ DelayButton {
+ text: progress < 1 ? "START" : "STOP"
+ anchors.centerIn: parent
+ }
+ }
+ }
+ Component {
+ id: dialComponent
+ Item {
+ enabled: !settingsData.allDisabled
+ Dial {
+ anchors.centerIn: parent
+ }
+ }
+ }
+ Component {
+ id: tumblerComponent
+ Item {
+ enabled: !settingsData.allDisabled
+ Tumbler {
+ anchors.centerIn: parent
+ TumblerColumn {
+ model: {
+ var hours = [];
+ for (var i = 1; i <= 24; ++i)
+ hours.push(i < 10 ? "0" + i : i);
+ hours;
+ }
+ }
+ TumblerColumn {
+ model: {
+ var minutes = [];
+ for (var i = 0; i < 60; ++i)
+ minutes.push(i < 10 ? "0" + i : i);
+ minutes;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/examples/quick/extras/flat/SettingsIcon.qml b/examples/quick/extras/flat/SettingsIcon.qml
new file mode 100644
index 00000000..a31972ee
--- /dev/null
+++ b/examples/quick/extras/flat/SettingsIcon.qml
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+
+Canvas {
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ ctx.scale(width, height);
+
+ ctx.beginPath();
+ ctx.moveTo(0.706,0.542);
+ ctx.bezierCurveTo(0.709,0.527,0.711,0.512,0.711,0.49700000000000005);
+ ctx.bezierCurveTo(0.711,0.4820000000000001,0.709,0.465,0.706,0.451);
+ ctx.lineTo(0.752,0.41600000000000004);
+ ctx.lineTo(0.759,0.41);
+ ctx.lineTo(0.756,0.4);
+ ctx.bezierCurveTo(0.756,0.399,0.749,0.382,0.737,0.36200000000000004);
+ ctx.bezierCurveTo(0.725,0.3420000000000001,0.714,0.328,0.714,0.327);
+ ctx.lineTo(0.708,0.319);
+ ctx.lineTo(0.698,0.324);
+ ctx.lineTo(0.645,0.346);
+ ctx.bezierCurveTo(0.623,0.32499999999999996,0.595,0.309,0.5650000000000001,0.3);
+ ctx.lineTo(0.558,0.243);
+ ctx.lineTo(0.557,0.23299999999999998);
+ ctx.lineTo(0.547,0.23099999999999998);
+ ctx.bezierCurveTo(0.546,0.23099999999999998,0.528,0.22799999999999998,0.505,0.22799999999999998);
+ ctx.bezierCurveTo(0.481,0.22799999999999998,0.463,0.23099999999999998,0.463,0.23099999999999998);
+ ctx.lineTo(0.453,0.23299999999999998);
+ ctx.lineTo(0.452,0.243);
+ ctx.lineTo(0.444,0.299);
+ ctx.bezierCurveTo(0.41400000000000003,0.308,0.387,0.324,0.364,0.345);
+ ctx.lineTo(0.312,0.323);
+ ctx.lineTo(0.302,0.319);
+ ctx.lineTo(0.296,0.327);
+ ctx.bezierCurveTo(0.296,0.327,0.284,0.342,0.27299999999999996,0.362);
+ ctx.bezierCurveTo(0.26,0.383,0.254,0.399,0.254,0.4);
+ ctx.lineTo(0.25,0.41);
+ ctx.lineTo(0.258,0.416);
+ ctx.lineTo(0.303,0.45099999999999996);
+ ctx.bezierCurveTo(0.3,0.465,0.299,0.48,0.299,0.497);
+ ctx.bezierCurveTo(0.299,0.513,0.3,0.528,0.304,0.543);
+ ctx.lineTo(0.259,0.577);
+ ctx.lineTo(0.25,0.584);
+ ctx.lineTo(0.254,0.593);
+ ctx.bezierCurveTo(0.254,0.594,0.261,0.61,0.273,0.63);
+ ctx.bezierCurveTo(0.28500000000000003,0.65,0.29500000000000004,0.664,0.29600000000000004,0.665);
+ ctx.lineTo(0.30200000000000005,0.673);
+ ctx.lineTo(0.31200000000000006,0.669);
+ ctx.lineTo(0.36500000000000005,0.647);
+ ctx.bezierCurveTo(0.38700000000000007,0.668,0.41400000000000003,0.684,0.44400000000000006,0.6930000000000001);
+ ctx.lineTo(0.45200000000000007,0.7510000000000001);
+ ctx.lineTo(0.45300000000000007,0.7620000000000001);
+ ctx.lineTo(0.4640000000000001,0.7630000000000001);
+ ctx.bezierCurveTo(0.4640000000000001,0.7630000000000001,0.4820000000000001,0.7640000000000001,0.5060000000000001,0.7640000000000001);
+ ctx.bezierCurveTo(0.5300000000000001,0.7640000000000001,0.5470000000000002,0.7620000000000001,0.5480000000000002,0.7620000000000001);
+ ctx.lineTo(0.5580000000000002,0.7610000000000001);
+ ctx.lineTo(0.5590000000000002,0.7510000000000001);
+ ctx.lineTo(0.5660000000000002,0.6940000000000001);
+ ctx.bezierCurveTo(0.5960000000000002,0.685,0.6230000000000002,0.669,0.6460000000000001,0.648);
+ ctx.lineTo(0.6990000000000002,0.67);
+ ctx.lineTo(0.7090000000000002,0.674);
+ ctx.lineTo(0.7150000000000002,0.665);
+ ctx.bezierCurveTo(0.7150000000000002,0.665,0.7260000000000002,0.65,0.7370000000000002,0.63);
+ ctx.bezierCurveTo(0.7490000000000002,0.61,0.7560000000000002,0.594,0.7560000000000002,0.593);
+ ctx.lineTo(0.7600000000000002,0.584);
+ ctx.lineTo(0.751,0.577);
+ ctx.lineTo(0.706,0.542);
+ ctx.closePath();
+ ctx.moveTo(0.505,0.622);
+ ctx.bezierCurveTo(0.436,0.622,0.38,0.566,0.38,0.497);
+ ctx.bezierCurveTo(0.38,0.428,0.436,0.372,0.505,0.372);
+ ctx.bezierCurveTo(0.5740000000000001,0.372,0.63,0.428,0.63,0.497);
+ ctx.bezierCurveTo(0.63,0.565,0.574,0.622,0.505,0.622);
+ ctx.closePath();
+ ctx.fillStyle = "#333333";
+ ctx.fill();
+ }
+}
diff --git a/examples/quick/extras/flat/flat.pro b/examples/quick/extras/flat/flat.pro
new file mode 100644
index 00000000..387e7ca0
--- /dev/null
+++ b/examples/quick/extras/flat/flat.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+TARGET = flat
+QT += quick
+
+SOURCES += \
+ main.cpp
+
+RESOURCES += \
+ flat.qrc
+
+OTHER_FILES += \
+ main.qml
+
+DISTFILES += \
+ Content.qml \
+ SettingsIcon.qml
diff --git a/examples/quick/extras/flat/flat.qrc b/examples/quick/extras/flat/flat.qrc
new file mode 100644
index 00000000..5b06a55c
--- /dev/null
+++ b/examples/quick/extras/flat/flat.qrc
@@ -0,0 +1,16 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>images/piemenu-bw-normal.png</file>
+ <file>images/piemenu-bw-pressed.png</file>
+ <file>images/piemenu-rgb-normal.png</file>
+ <file>images/piemenu-rgb-pressed.png</file>
+ <file>images/piemenu-sepia-normal.png</file>
+ <file>images/piemenu-sepia-pressed.png</file>
+ <file>images/piemenu-image-bw.jpg</file>
+ <file>images/piemenu-image-rgb.jpg</file>
+ <file>images/piemenu-image-sepia.jpg</file>
+ <file>Content.qml</file>
+ <file>SettingsIcon.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/quick/extras/flat/images/piemenu-bw-normal.png b/examples/quick/extras/flat/images/piemenu-bw-normal.png
new file mode 100644
index 00000000..ef57111f
--- /dev/null
+++ b/examples/quick/extras/flat/images/piemenu-bw-normal.png
Binary files differ
diff --git a/examples/quick/extras/flat/images/piemenu-bw-pressed.png b/examples/quick/extras/flat/images/piemenu-bw-pressed.png
new file mode 100644
index 00000000..b6bd1d20
--- /dev/null
+++ b/examples/quick/extras/flat/images/piemenu-bw-pressed.png
Binary files differ
diff --git a/examples/quick/extras/flat/images/piemenu-image-bw.jpg b/examples/quick/extras/flat/images/piemenu-image-bw.jpg
new file mode 100644
index 00000000..ce4d8ffd
--- /dev/null
+++ b/examples/quick/extras/flat/images/piemenu-image-bw.jpg
Binary files differ
diff --git a/examples/quick/extras/flat/images/piemenu-image-rgb.jpg b/examples/quick/extras/flat/images/piemenu-image-rgb.jpg
new file mode 100644
index 00000000..2d7d2205
--- /dev/null
+++ b/examples/quick/extras/flat/images/piemenu-image-rgb.jpg
Binary files differ
diff --git a/examples/quick/extras/flat/images/piemenu-image-sepia.jpg b/examples/quick/extras/flat/images/piemenu-image-sepia.jpg
new file mode 100644
index 00000000..3ef7b1f0
--- /dev/null
+++ b/examples/quick/extras/flat/images/piemenu-image-sepia.jpg
Binary files differ
diff --git a/examples/quick/extras/flat/images/piemenu-rgb-normal.png b/examples/quick/extras/flat/images/piemenu-rgb-normal.png
new file mode 100644
index 00000000..2278f4a9
--- /dev/null
+++ b/examples/quick/extras/flat/images/piemenu-rgb-normal.png
Binary files differ
diff --git a/examples/quick/extras/flat/images/piemenu-rgb-pressed.png b/examples/quick/extras/flat/images/piemenu-rgb-pressed.png
new file mode 100644
index 00000000..f45846b1
--- /dev/null
+++ b/examples/quick/extras/flat/images/piemenu-rgb-pressed.png
Binary files differ
diff --git a/examples/quick/extras/flat/images/piemenu-sepia-normal.png b/examples/quick/extras/flat/images/piemenu-sepia-normal.png
new file mode 100644
index 00000000..f1e9ffd2
--- /dev/null
+++ b/examples/quick/extras/flat/images/piemenu-sepia-normal.png
Binary files differ
diff --git a/examples/quick/extras/flat/images/piemenu-sepia-pressed.png b/examples/quick/extras/flat/images/piemenu-sepia-pressed.png
new file mode 100644
index 00000000..0f2b3517
--- /dev/null
+++ b/examples/quick/extras/flat/images/piemenu-sepia-pressed.png
Binary files differ
diff --git a/examples/quick/extras/flat/main.cpp b/examples/quick/extras/flat/main.cpp
new file mode 100644
index 00000000..99ba7205
--- /dev/null
+++ b/examples/quick/extras/flat/main.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QGuiApplication>
+#include <QtQml/QQmlApplicationEngine>
+#include <QtGui/QFontDatabase>
+#include <QtCore/QDir>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+ if (qgetenv("QT_QUICK_CONTROLS_STYLE").isEmpty()) {
+ qputenv("QT_QUICK_CONTROLS_STYLE", "Flat");
+ }
+ QQmlApplicationEngine engine;
+ engine.load(QUrl("qrc:/main.qml"));
+ return app.exec();
+}
diff --git a/examples/quick/extras/flat/main.qml b/examples/quick/extras/flat/main.qml
new file mode 100644
index 00000000..4d93074b
--- /dev/null
+++ b/examples/quick/extras/flat/main.qml
@@ -0,0 +1,480 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles.Flat 1.0 as Flat
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private 1.0
+
+ApplicationWindow {
+ id: window
+ width: 480
+ height: 860
+ title: "Flat Example"
+ visible: true
+
+ readonly property bool contentLoaded: contentLoader.item
+ readonly property alias anchorItem: controlsMenu
+ property int currentMenu: -1
+ readonly property int textMargins: Math.round(32 * Flat.FlatStyle.scaleFactor)
+ readonly property int menuMargins: Math.round(13 * Flat.FlatStyle.scaleFactor)
+ readonly property int menuWidth: Math.min(window.width, window.height) * 0.75
+
+ onCurrentMenuChanged: {
+ xBehavior.enabled = true;
+ anchorCurrentMenu();
+ }
+
+ onMenuWidthChanged: anchorCurrentMenu()
+
+ function anchorCurrentMenu() {
+ switch (currentMenu) {
+ case -1:
+ anchorItem.x = -menuWidth;
+ break;
+ case 0:
+ anchorItem.x = 0;
+ break;
+ case 1:
+ anchorItem.x = -menuWidth * 2;
+ break;
+ }
+ }
+
+ Item {
+ id: container
+ anchors.fill: parent
+
+ Item {
+ id: loadingScreen
+ anchors.fill: parent
+ visible: !contentLoaded
+
+ Timer {
+ running: true
+ interval: 100
+ // TODO: Find a way to know when the loading screen has been rendered instead
+ // of using an abritrary amount of time.
+ onTriggered: contentLoader.sourceComponent = Qt.createComponent("Content.qml")
+ }
+
+ Column {
+ anchors.centerIn: parent
+ spacing: Math.round(10 * Flat.FlatStyle.scaleFactor)
+
+ BusyIndicator {
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+ Label {
+ text: "Loading Light Flat UI..."
+ width: Math.min(loadingScreen.width, loadingScreen.height) * 0.8
+ height: font.pixelSize
+ anchors.horizontalCenter: parent.horizontalCenter
+ renderType: Text.QtRendering
+ font.pixelSize: Math.round(26 * Flat.FlatStyle.scaleFactor)
+ horizontalAlignment: Text.AlignHCenter
+ fontSizeMode: Text.Fit
+ font.family: Flat.FlatStyle.fontFamily
+ font.weight: Font.Light
+ }
+ }
+ }
+
+ Rectangle {
+ id: controlsMenu
+ x: container.x - width
+ z: contentContainer.z + 1
+ width: menuWidth
+ height: parent.height
+
+ // Don't let the menus become visible when resizing the window
+ Binding {
+ target: controlsMenu
+ property: "x"
+ value: container.x - controlsMenu.width
+ when: !xBehavior.enabled && !xNumberAnimation.running && currentMenu == -1
+ }
+
+ Behavior on x {
+ id: xBehavior
+ enabled: false
+ NumberAnimation {
+ id: xNumberAnimation
+ easing.type: Easing.OutExpo
+ duration: 500
+ onRunningChanged: xBehavior.enabled = false
+ }
+ }
+
+ Rectangle {
+ id: controlsTitleBar
+ width: parent.width
+ height: toolBar.height
+ color: Flat.FlatStyle.defaultTextColor
+
+ Label {
+ text: "Controls"
+ font.family: Flat.FlatStyle.fontFamily
+ font.pixelSize: Math.round(16 * Flat.FlatStyle.scaleFactor)
+ renderType: Text.QtRendering
+ color: "white"
+ anchors.left: parent.left
+ anchors.leftMargin: menuMargins
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ ListView {
+ id: controlView
+ width: parent.width
+ anchors.top: controlsTitleBar.bottom
+ anchors.bottom: parent.bottom
+ clip: true
+ currentIndex: 0
+ model: contentLoaded ? contentLoader.item.componentModel : null
+ delegate: MouseArea {
+ id: delegateItem
+ width: parent.width
+ height: 64 * Flat.FlatStyle.scaleFactor
+ onClicked: {
+ if (controlView.currentIndex != index)
+ controlView.currentIndex = index;
+
+ currentMenu = -1;
+ }
+
+ Rectangle {
+ width: parent.width
+ height: Flat.FlatStyle.onePixel
+ anchors.bottom: parent.bottom
+ color: Flat.FlatStyle.lightFrameColor
+ }
+
+ Label {
+ text: delegateItem.ListView.view.model[index].name
+ font.pixelSize: Math.round(15 * Flat.FlatStyle.scaleFactor)
+ font.family: Flat.FlatStyle.fontFamily
+ renderType: Text.QtRendering
+ color: delegateItem.ListView.isCurrentItem ? Flat.FlatStyle.styleColor : Flat.FlatStyle.defaultTextColor
+ anchors.left: parent.left
+ anchors.leftMargin: menuMargins
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Rectangle {
+ width: parent.height
+ height: 8 * Flat.FlatStyle.scaleFactor
+ rotation: 90
+ anchors.left: parent.right
+ transformOrigin: Item.TopLeft
+
+ gradient: Gradient {
+ GradientStop {
+ color: Qt.rgba(0, 0, 0, 0.15)
+ position: 0
+ }
+ GradientStop {
+ color: Qt.rgba(0, 0, 0, 0.05)
+ position: 0.5
+ }
+ GradientStop {
+ color: Qt.rgba(0, 0, 0, 0)
+ position: 1
+ }
+ }
+ }
+ }
+ }
+
+ Item {
+ id: contentContainer
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.left: controlsMenu.right
+ width: parent.width
+
+ ToolBar {
+ id: toolBar
+ visible: !loadingScreen.visible
+ width: parent.width
+ height: 54 * Flat.FlatStyle.scaleFactor
+ z: contentLoader.z + 1
+ style: Flat.ToolBarStyle {
+ padding.left: 0
+ padding.right: 0
+ }
+
+ RowLayout {
+ anchors.fill: parent
+
+ MouseArea {
+ id: controlsButton
+ Layout.preferredWidth: toolBar.height + textMargins
+ Layout.preferredHeight: toolBar.height
+ onClicked: currentMenu = currentMenu == 0 ? -1 : 0
+
+ Column {
+ id: controlsIcon
+ anchors.left: parent.left
+ anchors.leftMargin: textMargins
+ anchors.verticalCenter: parent.verticalCenter
+ spacing: Math.round(2 * Flat.FlatStyle.scaleFactor)
+
+ Repeater {
+ model: 3
+
+ Rectangle {
+ width: Math.round(4 * Flat.FlatStyle.scaleFactor)
+ height: width
+ radius: width / 2
+ color: Flat.FlatStyle.defaultTextColor
+ }
+ }
+ }
+ }
+
+ Text {
+ text: "Light Flat UI Demo"
+ font.family: Flat.FlatStyle.fontFamily
+ font.pixelSize: Math.round(16 * Flat.FlatStyle.scaleFactor)
+ horizontalAlignment: Text.AlignHCenter
+ color: "#666666"
+ Layout.fillWidth: true
+ }
+
+ MouseArea {
+ id: settingsButton
+ Layout.preferredWidth: controlsButton.Layout.preferredWidth
+ Layout.preferredHeight: controlsButton.Layout.preferredHeight
+ onClicked: currentMenu = currentMenu == 1 ? -1 : 1
+
+ SettingsIcon {
+ width: Math.round(32 * Flat.FlatStyle.scaleFactor)
+ height: Math.round(32 * Flat.FlatStyle.scaleFactor)
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+ anchors.rightMargin: textMargins - Math.round(8 * Flat.FlatStyle.scaleFactor)
+ }
+ }
+ }
+ }
+
+ Loader {
+ id: contentLoader
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: toolBar.bottom
+ anchors.bottom: parent.bottom
+
+ property QtObject settingsData: QtObject {
+ readonly property bool checks: disableSingleItemsAction.checked
+ readonly property bool frames: !greyBackgroundAction.checked
+ readonly property bool allDisabled: disableAllAction.checked
+ }
+ property QtObject controlData: QtObject {
+ readonly property int componentIndex: controlView.currentIndex
+ readonly property int textMargins: window.textMargins
+ }
+
+ MouseArea {
+ enabled: currentMenu != -1
+ // We would be able to just set this to true here, if it weren't for QTBUG-43083.
+ hoverEnabled: enabled
+ anchors.fill: parent
+ preventStealing: true
+ onClicked: currentMenu = -1
+ focus: enabled
+ z: 1000
+ }
+ }
+ }
+
+ Rectangle {
+ id: settingsMenu
+ z: contentContainer.z + 1
+ width: menuWidth
+ height: parent.height
+ anchors.left: contentContainer.right
+
+ Rectangle {
+ id: optionsTitleBar
+ width: parent.width
+ height: toolBar.height
+ color: Flat.FlatStyle.defaultTextColor
+
+ Label {
+ text: "Options"
+ font.family: Flat.FlatStyle.fontFamily
+ font.pixelSize: Math.round(16 * Flat.FlatStyle.scaleFactor)
+ renderType: Text.QtRendering
+ color: "white"
+ anchors.left: parent.left
+ anchors.leftMargin: menuMargins
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Action {
+ id: disableAllAction
+ checkable: true
+ checked: false
+ }
+
+ Action {
+ id: disableSingleItemsAction
+ checkable: true
+ checked: false
+ }
+
+ Action {
+ id: greyBackgroundAction
+ checkable: true
+ checked: false
+ }
+
+ ListView {
+ id: optionsListView
+ width: parent.width
+ anchors.top: optionsTitleBar.bottom
+ anchors.bottom: parent.bottom
+ clip: true
+ interactive: delegateHeight * count > height
+
+ readonly property int delegateHeight: 64 * Flat.FlatStyle.scaleFactor
+
+ model: [
+ { name: "Disable all", action: disableAllAction },
+ { name: "Disable single items", action: disableSingleItemsAction },
+ { name: "Grey background", action: greyBackgroundAction },
+ { name: "Exit", action: null }
+ ]
+ delegate: Rectangle {
+ id: optionDelegateItem
+ width: parent.width
+ height: optionsListView.delegateHeight
+
+ Rectangle {
+ width: parent.width
+ height: Flat.FlatStyle.onePixel
+ anchors.bottom: parent.bottom
+ color: Flat.FlatStyle.lightFrameColor
+ }
+
+ Loader {
+ sourceComponent: optionText !== "Exit"
+ ? optionsListView.checkBoxComponent : optionsListView.exitComponent
+ anchors.fill: parent
+ anchors.leftMargin: menuMargins
+
+ property string optionText: optionsListView.model[index].name
+ property int optionIndex: index
+ }
+ }
+
+ property Component checkBoxComponent: Item {
+ Label {
+ text: optionText
+ font.family: Flat.FlatStyle.fontFamily
+ font.pixelSize: Math.round(15 * Flat.FlatStyle.scaleFactor)
+ fontSizeMode: Text.Fit
+ renderType: Text.QtRendering
+ verticalAlignment: Text.AlignVCenter
+ color: Flat.FlatStyle.defaultTextColor
+ height: parent.height
+ anchors.left: parent.left
+ anchors.right: checkBox.left
+ anchors.rightMargin: Flat.FlatStyle.twoPixels
+ }
+
+ CheckBox {
+ id: checkBox
+ checked: optionsListView.model[optionIndex].action.checked
+ anchors.right: parent.right
+ anchors.rightMargin: menuMargins
+ anchors.verticalCenter: parent.verticalCenter
+ onCheckedChanged: optionsListView.model[optionIndex].action.checked = checkBox.checked
+ }
+ }
+
+ property Component exitComponent: MouseArea {
+ anchors.fill: parent
+ onClicked: Qt.quit()
+
+ Label {
+ text: optionText
+ font.family: Flat.FlatStyle.fontFamily
+ font.pixelSize: Math.round(15 * Flat.FlatStyle.scaleFactor)
+ renderType: Text.QtRendering
+ color: Flat.FlatStyle.defaultTextColor
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Rectangle {
+ width: parent.height
+ height: 8 * Flat.FlatStyle.scaleFactor
+ rotation: -90
+ anchors.right: parent.left
+ transformOrigin: Item.TopRight
+
+ gradient: Gradient {
+ GradientStop {
+ color: Qt.rgba(0, 0, 0, 0.15)
+ position: 0
+ }
+ GradientStop {
+ color: Qt.rgba(0, 0, 0, 0.05)
+ position: 0.5
+ }
+ GradientStop {
+ color: Qt.rgba(0, 0, 0, 0)
+ position: 1
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/examples/quick/extras/gallery/fonts/LICENSE.txt b/examples/quick/extras/gallery/fonts/LICENSE.txt
new file mode 100644
index 00000000..d6456956
--- /dev/null
+++ b/examples/quick/extras/gallery/fonts/LICENSE.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/examples/quick/extras/gallery/fonts/OpenSans-Regular.ttf b/examples/quick/extras/gallery/fonts/OpenSans-Regular.ttf
new file mode 100644
index 00000000..db433349
--- /dev/null
+++ b/examples/quick/extras/gallery/fonts/OpenSans-Regular.ttf
Binary files differ
diff --git a/examples/quick/extras/gallery/gallery.pro b/examples/quick/extras/gallery/gallery.pro
new file mode 100644
index 00000000..3c50a7c2
--- /dev/null
+++ b/examples/quick/extras/gallery/gallery.pro
@@ -0,0 +1,31 @@
+TEMPLATE = app
+TARGET = gallery
+INCLUDEPATH += .
+QT += quick
+
+SOURCES += \
+ main.cpp
+
+RESOURCES += \
+ gallery.qrc
+
+OTHER_FILES += \
+ qml/BlackButtonBackground.qml \
+ qml/BlackButtonStyle.qml \
+ qml/CircularGaugeDarkStyle.qml \
+ qml/CircularGaugeDefaultStyle.qml \
+ qml/CircularGaugeLightStyle.qml \
+ qml/CircularGaugeView.qml \
+ qml/ControlLabel.qml \
+ qml/ControlView.qml \
+ qml/ControlViewToolBar.qml \
+ qml/CustomizerSwitch.qml \
+ qml/CustomizerLabel.qml \
+ qml/CustomizerSlider.qml \
+ qml/FlickableMoreIndicator.qml \
+ qml/gallery.qml \
+ qml/PieMenuControlView.qml \
+ qml/PieMenuDefaultStyle.qml \
+ qml/PieMenuDarkStyle.qml \
+ qml/StylePicker.qml \
+ gallery.qrc
diff --git a/examples/quick/extras/gallery/gallery.qrc b/examples/quick/extras/gallery/gallery.qrc
new file mode 100644
index 00000000..97beb6b1
--- /dev/null
+++ b/examples/quick/extras/gallery/gallery.qrc
@@ -0,0 +1,36 @@
+<RCC>
+ <qresource prefix="/">
+ <file>fonts/OpenSans-Regular.ttf</file>
+ <file>images/background-light.png</file>
+ <file>images/background.png</file>
+ <file>images/center-light.png</file>
+ <file>images/center.png</file>
+ <file>images/icon-go.png</file>
+ <file>images/icon-settings.png</file>
+ <file>images/info.png</file>
+ <file>images/needle-light.png</file>
+ <file>images/needle.png</file>
+ <file>images/qt-logo.png</file>
+ <file>images/zoom_in.png</file>
+ <file>images/zoom_out.png</file>
+ <file>qml/BlackButtonBackground.qml</file>
+ <file>qml/BlackButtonStyle.qml</file>
+ <file>qml/CircularGaugeDarkStyle.qml</file>
+ <file>qml/CircularGaugeDefaultStyle.qml</file>
+ <file>qml/CircularGaugeLightStyle.qml</file>
+ <file>qml/CircularGaugeView.qml</file>
+ <file>qml/ControlView.qml</file>
+ <file>qml/ControlViewToolbar.qml</file>
+ <file>qml/CustomizerSwitch.qml</file>
+ <file>qml/CustomizerLabel.qml</file>
+ <file>qml/CustomizerSlider.qml</file>
+ <file>qml/FlickableMoreIndicator.qml</file>
+ <file>qml/gallery.qml</file>
+ <file>qml/PieMenuControlView.qml</file>
+ <file>qml/StylePicker.qml</file>
+ <file>qml/PieMenuDarkStyle.qml</file>
+ <file>qml/PieMenuDefaultStyle.qml</file>
+ <file>qml/ControlLabel.qml</file>
+ <file>images/icon-back.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/quick/extras/gallery/images/background-light.png b/examples/quick/extras/gallery/images/background-light.png
new file mode 100644
index 00000000..2f769845
--- /dev/null
+++ b/examples/quick/extras/gallery/images/background-light.png
Binary files differ
diff --git a/examples/quick/extras/gallery/images/background.png b/examples/quick/extras/gallery/images/background.png
new file mode 100644
index 00000000..a3f4302b
--- /dev/null
+++ b/examples/quick/extras/gallery/images/background.png
Binary files differ
diff --git a/examples/quick/extras/gallery/images/center-light.png b/examples/quick/extras/gallery/images/center-light.png
new file mode 100644
index 00000000..75add20c
--- /dev/null
+++ b/examples/quick/extras/gallery/images/center-light.png
Binary files differ
diff --git a/examples/quick/extras/gallery/images/center.png b/examples/quick/extras/gallery/images/center.png
new file mode 100644
index 00000000..b18a5fa8
--- /dev/null
+++ b/examples/quick/extras/gallery/images/center.png
Binary files differ
diff --git a/examples/quick/extras/gallery/images/icon-back.png b/examples/quick/extras/gallery/images/icon-back.png
new file mode 100644
index 00000000..0b037ff6
--- /dev/null
+++ b/examples/quick/extras/gallery/images/icon-back.png
Binary files differ
diff --git a/examples/quick/extras/gallery/images/icon-go.png b/examples/quick/extras/gallery/images/icon-go.png
new file mode 100644
index 00000000..bcb2a822
--- /dev/null
+++ b/examples/quick/extras/gallery/images/icon-go.png
Binary files differ
diff --git a/examples/quick/extras/gallery/images/icon-settings.png b/examples/quick/extras/gallery/images/icon-settings.png
new file mode 100644
index 00000000..7763ba20
--- /dev/null
+++ b/examples/quick/extras/gallery/images/icon-settings.png
Binary files differ
diff --git a/examples/quick/extras/gallery/images/info.png b/examples/quick/extras/gallery/images/info.png
new file mode 100644
index 00000000..5c7a9df3
--- /dev/null
+++ b/examples/quick/extras/gallery/images/info.png
Binary files differ
diff --git a/examples/quick/extras/gallery/images/needle-light.png b/examples/quick/extras/gallery/images/needle-light.png
new file mode 100644
index 00000000..d486d9e5
--- /dev/null
+++ b/examples/quick/extras/gallery/images/needle-light.png
Binary files differ
diff --git a/examples/quick/extras/gallery/images/needle.png b/examples/quick/extras/gallery/images/needle.png
new file mode 100644
index 00000000..6b10c604
--- /dev/null
+++ b/examples/quick/extras/gallery/images/needle.png
Binary files differ
diff --git a/examples/quick/extras/gallery/images/qt-logo.png b/examples/quick/extras/gallery/images/qt-logo.png
new file mode 100644
index 00000000..14ddf2a0
--- /dev/null
+++ b/examples/quick/extras/gallery/images/qt-logo.png
Binary files differ
diff --git a/examples/quick/extras/gallery/images/zoom_in.png b/examples/quick/extras/gallery/images/zoom_in.png
new file mode 100644
index 00000000..41282106
--- /dev/null
+++ b/examples/quick/extras/gallery/images/zoom_in.png
Binary files differ
diff --git a/examples/quick/extras/gallery/images/zoom_out.png b/examples/quick/extras/gallery/images/zoom_out.png
new file mode 100644
index 00000000..772d6ac1
--- /dev/null
+++ b/examples/quick/extras/gallery/images/zoom_out.png
Binary files differ
diff --git a/examples/quick/extras/gallery/main.cpp b/examples/quick/extras/gallery/main.cpp
new file mode 100644
index 00000000..5b1dbfee
--- /dev/null
+++ b/examples/quick/extras/gallery/main.cpp
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QGuiApplication>
+#include <QtQml/QQmlApplicationEngine>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+ QQmlApplicationEngine engine(QUrl("qrc:/qml/gallery.qml"));
+ return app.exec();
+}
diff --git a/examples/quick/extras/gallery/qml/BlackButtonBackground.qml b/examples/quick/extras/gallery/qml/BlackButtonBackground.qml
new file mode 100644
index 00000000..983554a2
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/BlackButtonBackground.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Styles 1.1
+
+Rectangle {
+ property bool pressed: false
+
+ gradient: Gradient {
+ GradientStop {
+ color: pressed ? "#222" : "#333"
+ position: 0
+ }
+ GradientStop {
+ color: "#222"
+ position: 1
+ }
+ }
+ Rectangle {
+ height: 1
+ width: parent.width
+ anchors.top: parent.top
+ color: "#444"
+ visible: !pressed
+ }
+ Rectangle {
+ height: 1
+ width: parent.width
+ anchors.bottom: parent.bottom
+ color: "#000"
+ }
+}
diff --git a/examples/quick/extras/gallery/qml/BlackButtonStyle.qml b/examples/quick/extras/gallery/qml/BlackButtonStyle.qml
new file mode 100644
index 00000000..8bc561a7
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/BlackButtonStyle.qml
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Styles 1.1
+
+ButtonStyle {
+ property color fontColor
+
+ property url rightAlignedIconSource
+
+ background: BlackButtonBackground {
+ pressed: control.pressed
+ }
+ label: Item {
+ implicitWidth: row.implicitWidth
+ implicitHeight: row.implicitHeight
+ baselineOffset: row.y + text.y + text.baselineOffset
+
+ Row {
+ id: row
+ anchors.left: control.text.length === 0 ? undefined : parent.left
+ anchors.leftMargin: control.text.length === 0 ? 0 : textSingleton.implicitHeight
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: control.text.length === 0 ? parent.horizontalCenter : undefined
+
+ Image {
+ source: control.iconSource
+ width: Math.min(sourceSize.width, height)
+ height: text.implicitHeight
+ fillMode: Image.PreserveAspectFit
+ }
+ Text {
+ id: text
+ text: control.text
+ color: fontColor
+ font.pixelSize: control.height * 0.25
+ font.family: openSans.name
+ horizontalAlignment: Text.AlignLeft
+ verticalAlignment: Text.AlignVCenter
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Loader {
+ active: rightAlignedIconSource.toString().length !== 0
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+ anchors.rightMargin: textSingleton.implicitHeight
+
+ sourceComponent: Image {
+ width: Math.min(sourceSize.width, height)
+ height: text.implicitHeight
+ fillMode: Image.PreserveAspectFit
+ source: rightAlignedIconSource
+ }
+ }
+ }
+}
diff --git a/examples/quick/extras/gallery/qml/CircularGaugeDarkStyle.qml b/examples/quick/extras/gallery/qml/CircularGaugeDarkStyle.qml
new file mode 100644
index 00000000..04e9233f
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/CircularGaugeDarkStyle.qml
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Extras.Styles 1.3
+
+CircularGaugeStyle {
+ id: root
+ tickmarkStepSize: 10
+ minorTickmarkCount: 1
+ labelStepSize: 20
+ tickmarkInset: outerRadius * 0.06
+ minorTickmarkInset: tickmarkInset
+ labelInset: outerRadius * 0.23
+
+ background: Image {
+ source: "qrc:/images/background.png"
+ }
+
+ needle: Image {
+ id: needleImage
+ transformOrigin: Item.Bottom
+ source: "qrc:/images/needle.png"
+ scale: {
+ var distanceFromLabelToRadius = labelInset / 2;
+ var idealHeight = outerRadius - distanceFromLabelToRadius;
+ var originalImageHeight = needleImage.sourceSize.height;
+ idealHeight / originalImageHeight;
+ }
+ }
+
+ foreground: Item {
+ Image {
+ anchors.centerIn: parent
+ source: "qrc:/images/center.png"
+ scale: (outerRadius * 0.25) / sourceSize.height
+ }
+ }
+
+ tickmark: Rectangle {
+ implicitWidth: outerRadius * 0.02
+ antialiasing: true
+ implicitHeight: outerRadius * 0.05
+ color: "#888"
+ }
+
+ minorTickmark: Rectangle {
+ implicitWidth: outerRadius * 0.01
+ antialiasing: true
+ implicitHeight: outerRadius * 0.02
+ color: "#444"
+ }
+
+ tickmarkLabel: Text {
+ font.pixelSize: Math.max(6, outerRadius * 0.1)
+ text: styleData.value
+ color: "white"
+ }
+}
diff --git a/examples/quick/extras/gallery/qml/CircularGaugeDefaultStyle.qml b/examples/quick/extras/gallery/qml/CircularGaugeDefaultStyle.qml
new file mode 100644
index 00000000..2f276163
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/CircularGaugeDefaultStyle.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Extras.Styles 1.3
+
+CircularGaugeStyle {
+ labelStepSize: 20
+}
diff --git a/examples/quick/extras/gallery/qml/CircularGaugeLightStyle.qml b/examples/quick/extras/gallery/qml/CircularGaugeLightStyle.qml
new file mode 100644
index 00000000..d31e831a
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/CircularGaugeLightStyle.qml
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Extras.Styles 1.3
+
+CircularGaugeStyle {
+ id: root
+ tickmarkStepSize: 10
+ minorTickmarkCount: 2
+ labelStepSize: 40
+ tickmarkInset: outerRadius * 0.06
+ minorTickmarkInset: tickmarkInset
+ labelInset: outerRadius * 0.23
+
+ background: Image {
+ source: "qrc:/images/background-light.png"
+ }
+
+ needle: Image {
+ id: needleImage
+ source: "qrc:/images/needle-light.png"
+ transformOrigin: Item.Bottom
+ scale: {
+ var distanceFromLabelToRadius = labelInset / 2;
+ var idealHeight = outerRadius - distanceFromLabelToRadius;
+ var originalImageHeight = needleImage.sourceSize.height;
+ idealHeight / originalImageHeight;
+ }
+ }
+
+ foreground: Item {
+ Image {
+ anchors.centerIn: parent
+ source: "qrc:/images/center-light.png"
+ scale: (outerRadius * 0.25) / sourceSize.height
+ }
+ }
+
+ tickmark: Rectangle {
+ implicitWidth: outerRadius * 0.01
+ antialiasing: true
+ implicitHeight: outerRadius * 0.04
+ color: "#999"
+ }
+
+ minorTickmark: Rectangle {
+ implicitWidth: outerRadius * 0.01
+ antialiasing: true
+ implicitHeight: outerRadius * 0.02
+ color: "#bbb"
+ }
+
+ tickmarkLabel: Text {
+ font.family: "Helvetica neue"
+ font.pixelSize: Math.max(6, outerRadius * 0.1)
+ text: styleData.value
+ color: "#333"
+ }
+}
diff --git a/examples/quick/extras/gallery/qml/CircularGaugeView.qml b/examples/quick/extras/gallery/qml/CircularGaugeView.qml
new file mode 100644
index 00000000..e763e7b9
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/CircularGaugeView.qml
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Extras 1.3
+
+ControlView {
+ id: controlView
+ darkBackground: customizerItem.currentStyleDark
+
+ property color fontColor: darkBackground ? "white" : "black"
+
+ property bool accelerating: false
+
+ Keys.onSpacePressed: accelerating = true
+ Keys.onReleased: {
+ if (event.key === Qt.Key_Space) {
+ accelerating = false;
+ event.accepted = true;
+ }
+ }
+
+ Button {
+ id: accelerate
+ text: "Accelerate"
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ height: root.height * 0.125
+
+ onPressedChanged: accelerating = pressed
+
+ style: BlackButtonStyle {
+ background: BlackButtonBackground {
+ pressed: control.pressed
+ }
+ label: Text {
+ text: control.text
+ color: "white"
+ font.pixelSize: Math.max(textSingleton.font.pixelSize, root.toPixels(0.04))
+ font.family: openSans.name
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
+ }
+
+ control: CircularGauge {
+ id: gauge
+ minimumValue: customizerItem.minimumValue
+ maximumValue: customizerItem.maximumValue
+ width: controlBounds.width
+ height: controlBounds.height
+
+ value: accelerating ? maximumValue : 0
+ style: styleMap[customizerItem.currentStylePath]
+
+ // This stops the styles being recreated when a new one is chosen.
+ property var styleMap: {
+ var styles = {};
+ for (var i = 0; i < customizerItem.allStylePaths.length; ++i) {
+ var path = customizerItem.allStylePaths[i];
+ styles[path] = Qt.createComponent(path, gauge);
+ }
+ styles;
+ }
+
+ // Called to update the style after the user has edited a property.
+ Connections {
+ target: customizerItem
+ onMinimumValueAngleChanged: __style.minimumValueAngle = customizerItem.minimumValueAngle
+ onMaximumValueAngleChanged: __style.maximumValueAngle = customizerItem.maximumValueAngle
+ onLabelStepSizeChanged: __style.tickmarkStepSize = __style.labelStepSize = customizerItem.labelStepSize
+ }
+
+ Behavior on value {
+ NumberAnimation {
+ easing.type: Easing.OutCubic
+ duration: 6000
+ }
+ }
+ }
+
+ customizer: Column {
+ readonly property var allStylePaths: {
+ var paths = [];
+ for (var i = 0; i < stylePicker.model.count; ++i) {
+ paths.push(stylePicker.model.get(i).path);
+ }
+ paths;
+ }
+ property alias currentStylePath: stylePicker.currentStylePath
+ property alias currentStyleDark: stylePicker.currentStyleDark
+ property alias minimumValue: minimumValueSlider.value
+ property alias maximumValue: maximumValueSlider.value
+ property alias minimumValueAngle: minimumAngleSlider.value
+ property alias maximumValueAngle: maximumAngleSlider.value
+ property alias labelStepSize: labelStepSizeSlider.value
+
+ id: circularGaugeColumn
+ spacing: customizerPropertySpacing
+
+ readonly property bool isDefaultStyle: stylePicker.model.get(stylePicker.currentIndex).name === "Default"
+
+ Item {
+ id: stylePickerBottomSpacing
+ width: parent.width
+ height: stylePicker.height + textSingleton.implicitHeight
+
+ StylePicker {
+ id: stylePicker
+ currentIndex: 1
+
+ model: ListModel {
+ ListElement {
+ name: "Default"
+ path: "CircularGaugeDefaultStyle.qml"
+ dark: true
+ }
+ ListElement {
+ name: "Dark"
+ path: "CircularGaugeDarkStyle.qml"
+ dark: true
+ }
+ ListElement {
+ name: "Light"
+ path: "CircularGaugeLightStyle.qml"
+ dark: false
+ }
+ }
+ }
+ }
+
+ CustomizerLabel {
+ text: "Minimum angle"
+ }
+
+ CustomizerSlider {
+ id: minimumAngleSlider
+ minimumValue: -180
+ value: -145
+ maximumValue: 180
+ width: parent.width
+ }
+
+ CustomizerLabel {
+ text: "Maximum angle"
+ }
+
+ CustomizerSlider {
+ id: maximumAngleSlider
+ minimumValue: -180
+ value: 145
+ maximumValue: 180
+ }
+
+ CustomizerLabel {
+ text: "Minimum value"
+ }
+
+ CustomizerSlider {
+ id: minimumValueSlider
+ minimumValue: 0
+ value: 0
+ maximumValue: 360
+ stepSize: 1
+ }
+
+ CustomizerLabel {
+ text: "Maximum value"
+ }
+
+ CustomizerSlider {
+ id: maximumValueSlider
+ minimumValue: 0
+ value: 240
+ maximumValue: 300
+ stepSize: 1
+ }
+
+ CustomizerLabel {
+ text: "Label step size"
+ }
+
+ CustomizerSlider {
+ id: labelStepSizeSlider
+ minimumValue: 10
+ value: 20
+ maximumValue: 100
+ stepSize: 20
+ }
+ }
+}
diff --git a/examples/quick/extras/gallery/qml/ControlLabel.qml b/examples/quick/extras/gallery/qml/ControlLabel.qml
new file mode 100644
index 00000000..b13c2a04
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/ControlLabel.qml
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Extras 1.3
+
+Text {
+ font.pixelSize: Math.max(textSingleton.font.pixelSize, Math.min(32, root.toPixels(0.045)))
+ color: "#4e4e4e"
+ styleColor: "#ffffff"
+ style: Text.Raised
+}
diff --git a/examples/quick/extras/gallery/qml/ControlView.qml b/examples/quick/extras/gallery/qml/ControlView.qml
new file mode 100644
index 00000000..cc479439
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/ControlView.qml
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+
+Rectangle {
+ id: view
+ color: darkBackground ? "transparent" : lightBackgroundColor
+
+ Keys.onReleased: {
+ if (event.key === Qt.Key_Back) {
+ stackView.pop();
+ event.accepted = true;
+ }
+ }
+
+ property bool darkBackground: true
+
+ property Component control
+ property Component customizer
+
+ property alias controlItem: controlLoader.item
+ property alias customizerItem: customizerLoader.item
+
+ property bool isCustomizerVisible: false
+
+ property real margin: root.toPixels(0.05)
+
+ property rect controlBounds: Qt.rect(largestControlItem.x + controlBoundsItem.x,
+ largestControlItem.y + controlBoundsItem.y, controlBoundsItem.width, controlBoundsItem.height)
+
+ Item {
+ id: largestControlItem
+ x: margin
+ y: margin
+ width: isCustomizerVisible ? widthWhenCustomizing : widthWhenNotCustomizing
+ height: isCustomizerVisible ? heightWhenCustomizing : heightWhenNotCustomizing
+
+ readonly property real widthWhenCustomizing: (!isScreenPortrait ? parent.width / 2 : parent.width) - margin * 2
+ readonly property real heightWhenCustomizing: (isScreenPortrait ? parent.height / 2 : parent.height - toolbar.height) - margin * 2
+ readonly property real widthWhenNotCustomizing: parent.width - margin * 2
+ readonly property real heightWhenNotCustomizing: parent.height - toolbar.height - margin * 2
+
+ Item {
+ id: controlBoundsItem
+ x: parent.width / 2 - controlBoundsItem.width / 2
+ y: customizer && customizerItem.visible ? 0 : (isScreenPortrait ? (parent.height / 2) - (controlBoundsItem.height / 2) : 0)
+ width: Math.min(parent.widthWhenCustomizing, parent.widthWhenNotCustomizing)
+ height: Math.min(parent.heightWhenCustomizing, parent.heightWhenNotCustomizing)
+
+ Behavior on x {
+ id: controlXBehavior
+ enabled: false
+ NumberAnimation {}
+ }
+
+ Behavior on y {
+ id: controlYBehavior
+ enabled: false
+ NumberAnimation {}
+ }
+
+ Loader {
+ id: controlLoader
+ sourceComponent: control
+ anchors.centerIn: parent
+
+ property alias view: view
+ }
+ }
+ }
+
+ Flickable {
+ id: flickable
+ // Hide the customizer on the right of the screen if it's not visible.
+ x: (isScreenPortrait ? 0 : (isCustomizerVisible ? largestControlItem.x + largestControlItem.width + margin : view.width)) + margin
+ y: (isScreenPortrait ? largestControlItem.y + largestControlItem.height : 0) + margin
+ width: largestControlItem.width
+ height: parent.height - y - toolbar.height - margin
+ anchors.leftMargin: margin
+ anchors.rightMargin: margin
+ visible: customizerLoader.opacity > 0
+
+ flickableDirection: Flickable.VerticalFlick
+
+ clip: true
+ contentWidth: width
+ contentHeight: customizerLoader.height
+
+ Behavior on x {
+ id: flickableXBehavior
+ enabled: false
+ NumberAnimation {}
+ }
+
+ Behavior on y {
+ id: flickableYBehavior
+ enabled: false
+ NumberAnimation {}
+ }
+
+ Loader {
+ id: customizerLoader
+ sourceComponent: customizer
+ opacity: 0
+ width: flickable.width
+
+ property alias view: view
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 300
+ }
+ }
+ }
+ }
+
+ ControlViewToolbar {
+ id: toolbar
+
+ onCustomizeClicked: {
+ controlXBehavior.enabled = !isScreenPortrait;
+ controlYBehavior.enabled = isScreenPortrait;
+
+ isCustomizerVisible = !isCustomizerVisible;
+
+ if (isScreenPortrait) {
+ flickableXBehavior.enabled = false;
+ flickableYBehavior.enabled = true;
+ } else {
+ flickableXBehavior.enabled = true;
+ flickableYBehavior.enabled = false;
+ }
+
+ customizerLoader.opacity = isCustomizerVisible ? 1 : 0;
+ }
+ }
+
+ FlickableMoreIndicator {
+ flickable: flickable
+ atTop: true
+ gradientColor: view.darkBackground ? darkBackgroundColor : lightBackgroundColor
+ }
+
+ FlickableMoreIndicator {
+ flickable: flickable
+ atTop: false
+ gradientColor: view.darkBackground ? darkBackgroundColor : lightBackgroundColor
+ }
+}
diff --git a/examples/quick/extras/gallery/qml/ControlViewToolbar.qml b/examples/quick/extras/gallery/qml/ControlViewToolbar.qml
new file mode 100644
index 00000000..7df5103c
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/ControlViewToolbar.qml
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+
+BlackButtonBackground {
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: root.height * 0.125
+
+ signal customizeClicked
+
+ gradient: Gradient {
+ GradientStop {
+ color: "#333"
+ position: 0
+ }
+ GradientStop {
+ color: "#222"
+ position: 1
+ }
+ }
+
+ Button {
+ id: back
+ width: parent.height
+ height: parent.height
+ anchors.left: parent.left
+ anchors.bottom: parent.bottom
+ iconSource: "qrc:/images/icon-back.png"
+ onClicked: stackView.pop()
+
+ style: BlackButtonStyle {
+ }
+
+ }
+
+ Button {
+ id: customize
+ width: parent.height
+ height: parent.height
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ iconSource: "qrc:/images/icon-settings.png"
+ visible: customizer
+
+ style: BlackButtonStyle {
+ }
+
+ onClicked: customizeClicked()
+ }
+}
diff --git a/examples/quick/extras/gallery/qml/CustomizerLabel.qml b/examples/quick/extras/gallery/qml/CustomizerLabel.qml
new file mode 100644
index 00000000..1640f86c
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/CustomizerLabel.qml
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+
+Text {
+ color: darkBackground ? root.darkFontColor : root.lightFontColor
+ font.pixelSize: root.toPixels(0.04)
+ font.family: openSans.name
+ anchors.horizontalCenter: parent.horizontalCenter
+}
diff --git a/examples/quick/extras/gallery/qml/CustomizerSlider.qml b/examples/quick/extras/gallery/qml/CustomizerSlider.qml
new file mode 100644
index 00000000..54b85ca9
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/CustomizerSlider.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Styles 1.1
+
+Slider {
+ id: slider
+ width: parent.width
+ height: root.toPixels(0.1)
+
+ style: SliderStyle {
+ handle: Rectangle {
+ height: root.toPixels(0.06)
+ width: height
+ radius: width/2
+ color: "#fff"
+ }
+
+ groove: Rectangle {
+ implicitHeight: root.toPixels(0.015)
+ implicitWidth: 100
+ radius: height/2
+ border.color: "#333"
+ color: "#222"
+ Rectangle {
+ height: parent.height
+ width: styleData.handlePosition
+ implicitHeight: 6
+ implicitWidth: 100
+ radius: height/2
+ color: "#555"
+ }
+ }
+
+ }
+}
diff --git a/examples/quick/extras/gallery/qml/CustomizerSwitch.qml b/examples/quick/extras/gallery/qml/CustomizerSwitch.qml
new file mode 100644
index 00000000..2586b63f
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/CustomizerSwitch.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+
+Switch {
+ anchors.horizontalCenter: parent.horizontalCenter
+}
diff --git a/examples/quick/extras/gallery/qml/FlickableMoreIndicator.qml b/examples/quick/extras/gallery/qml/FlickableMoreIndicator.qml
new file mode 100644
index 00000000..649e9715
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/FlickableMoreIndicator.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+
+Rectangle {
+ anchors.top: atTop ? flickable.top : undefined
+ anchors.bottom: atTop ? undefined : flickable.bottom
+ anchors.left: isScreenPortrait ? parent.left : parent.horizontalCenter
+ anchors.right: parent.right
+ height: 30
+ visible: flickable.visible
+ opacity: atTop
+ ? (flickable.contentY > showDistance ? 1 : 0)
+ : (flickable.contentY < flickable.contentHeight - showDistance ? 1 : 0)
+ scale: atTop ? 1 : -1
+
+ readonly property real showDistance: 0
+ property Flickable flickable
+ property color gradientColor
+ /*! \c true if this indicator is at the top of the item */
+ property bool atTop
+
+ Behavior on opacity {
+ NumberAnimation {
+ }
+ }
+
+ gradient: Gradient {
+ GradientStop {
+ position: 0.0
+ color: gradientColor
+ }
+ GradientStop {
+ position: 1.0
+ color: "transparent"
+ }
+ }
+}
diff --git a/examples/quick/extras/gallery/qml/PieMenuControlView.qml b/examples/quick/extras/gallery/qml/PieMenuControlView.qml
new file mode 100644
index 00000000..f486431a
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/PieMenuControlView.qml
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtGraphicalEffects 1.0
+import QtQuick.Controls 1.1
+import QtQuick.Extras 1.3
+
+Rectangle {
+ id: view
+ color: customizerItem.currentStyleDark ? "#111" : "#555"
+
+ Behavior on color {
+ ColorAnimation {}
+ }
+
+ Keys.onReleased: {
+ if (event.key === Qt.Key_Back) {
+ stackView.pop();
+ event.accepted = true;
+ }
+ }
+
+ property bool darkBackground: true
+
+ property Component mouseArea
+
+ property Component customizer: Item {
+ property alias currentStylePath: stylePicker.currentStylePath
+ property alias currentStyleDark: stylePicker.currentStyleDark
+
+ StylePicker {
+ id: stylePicker
+ currentIndex: 0
+ width: Math.round(Math.max(textSingleton.implicitHeight * 6 * 2, parent.width * 0.5))
+ anchors.centerIn: parent
+
+ model: ListModel {
+ ListElement {
+ name: "Default"
+ path: "PieMenuDefaultStyle.qml"
+ dark: false
+ }
+ ListElement {
+ name: "Dark"
+ path: "PieMenuDarkStyle.qml"
+ dark: true
+ }
+ }
+ }
+ }
+
+ property alias controlItem: pieMenu
+ property alias customizerItem: customizerLoader.item
+
+ Item {
+ id: controlBoundsItem
+ width: parent.width
+ height: parent.height - toolbar.height
+ visible: customizerLoader.opacity === 0
+
+ Image {
+ id: bgImage
+ anchors.centerIn: parent
+ height: 48
+ Text {
+ id: bgLabel
+ anchors.top: parent.bottom
+ anchors.topMargin: 20
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: "Tap to open"
+ color: "#999"
+ font.pointSize: 20
+ }
+ }
+
+ MouseArea {
+ id: touchArea
+ anchors.fill: parent
+ onClicked: pieMenu.popup(touchArea.mouseX, touchArea.mouseY)
+ }
+
+ PieMenu {
+ id: pieMenu
+ triggerMode: TriggerMode.TriggerOnClick
+ width: Math.min(controlBoundsItem.width, controlBoundsItem.height) * 0.5
+ height: width
+
+ style: Qt.createComponent(customizerItem.currentStylePath)
+
+ MenuItem {
+ text: "Zoom In"
+ onTriggered: {
+ bgImage.source = iconSource
+ bgLabel.text = text + " selected"
+ }
+ iconSource: "qrc:/images/zoom_in.png"
+ }
+ MenuItem {
+ text: "Zoom Out"
+ onTriggered: {
+ bgImage.source = iconSource
+ bgLabel.text = text + " selected"
+ }
+ iconSource: "qrc:/images/zoom_out.png"
+ }
+ MenuItem {
+ text: "Info"
+ onTriggered: {
+ bgImage.source = iconSource
+ bgLabel.text = text + " selected"
+ }
+ iconSource: "qrc:/images/info.png"
+ }
+ }
+ }
+ Loader {
+ id: customizerLoader
+ sourceComponent: customizer
+ opacity: 0
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.leftMargin: 30
+ anchors.rightMargin: 30
+ y: parent.height / 2 - height / 2 - toolbar.height
+ visible: customizerLoader.opacity > 0
+
+ property alias view: view
+
+ Behavior on y {
+ NumberAnimation {
+ duration: 300
+ }
+ }
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 300
+ }
+ }
+ }
+
+ ControlViewToolbar {
+ id: toolbar
+
+ onCustomizeClicked: {
+ customizerLoader.opacity = customizerLoader.opacity == 0 ? 1 : 0;
+ }
+ }
+}
diff --git a/examples/quick/extras/gallery/qml/PieMenuDarkStyle.qml b/examples/quick/extras/gallery/qml/PieMenuDarkStyle.qml
new file mode 100644
index 00000000..b5905192
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/PieMenuDarkStyle.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick.Extras.Styles 1.3
+
+PieMenuStyle {
+ backgroundColor: "#222"
+ shadowColor: Qt.rgba(1, 1, 1, 0.26)
+}
diff --git a/examples/quick/extras/gallery/qml/PieMenuDefaultStyle.qml b/examples/quick/extras/gallery/qml/PieMenuDefaultStyle.qml
new file mode 100644
index 00000000..f34584fe
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/PieMenuDefaultStyle.qml
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick.Extras.Styles 1.3
+
+PieMenuStyle {
+}
diff --git a/examples/quick/extras/gallery/qml/StylePicker.qml b/examples/quick/extras/gallery/qml/StylePicker.qml
new file mode 100644
index 00000000..4606cb97
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/StylePicker.qml
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Styles 1.1
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+
+ListView {
+ id: stylePicker
+ width: parent.width
+ height: root.height * 0.06
+ interactive: false
+ spacing: -1
+
+ orientation: ListView.Horizontal
+
+ readonly property string currentStylePath: stylePicker.model.get(stylePicker.currentIndex).path
+ readonly property bool currentStyleDark: stylePicker.model.get(stylePicker.currentIndex).dark !== undefined
+ ? stylePicker.model.get(stylePicker.currentIndex).dark
+ : true
+
+ ExclusiveGroup {
+ id: styleExclusiveGroup
+ }
+
+ delegate: Button {
+ width: Math.round(stylePicker.width / stylePicker.model.count)
+ height: stylePicker.height
+ checkable: true
+ checked: index === ListView.view.currentIndex
+ exclusiveGroup: styleExclusiveGroup
+
+ onCheckedChanged: {
+ if (checked) {
+ ListView.view.currentIndex = index;
+ }
+ }
+
+ style: ButtonStyle {
+ background: Rectangle {
+ readonly property color checkedColor: currentStyleDark ? "#444" : "#777"
+ readonly property color uncheckedColor: currentStyleDark ? "#222" : "#bbb"
+ color: checked ? checkedColor : uncheckedColor
+ border.color: checkedColor
+ border.width: 1
+ radius: 1
+ }
+
+ label: Text {
+ text: name
+ color: currentStyleDark ? "white" : (checked ? "white" : "black")
+ font.pixelSize: root.toPixels(0.04)
+ font.family: openSans.name
+ anchors.centerIn: parent
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
+ }
+}
diff --git a/examples/quick/extras/gallery/qml/gallery.qml b/examples/quick/extras/gallery/qml/gallery.qml
new file mode 100644
index 00000000..d29b8997
--- /dev/null
+++ b/examples/quick/extras/gallery/qml/gallery.qml
@@ -0,0 +1,440 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtGraphicalEffects 1.0
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Styles 1.1
+import QtQuick.Dialogs 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Layouts 1.0
+import QtQuick.Window 2.1
+
+Window {
+ id: root
+ objectName: "window"
+ visible: true
+ width: 480
+ height: 800
+
+ color: "#161616"
+ title: "Qt Quick Extras Demo"
+
+ function toPixels(percentage) {
+ return percentage * Math.min(root.width, root.height);
+ }
+
+ property bool isScreenPortrait: height > width
+ property color lightFontColor: "#222"
+ property color darkFontColor: "#e7e7e7"
+ readonly property color lightBackgroundColor: "#cccccc"
+ readonly property color darkBackgroundColor: "#161616"
+ property real customizerPropertySpacing: 10
+ property real colorPickerRowSpacing: 8
+
+ Text {
+ id: textSingleton
+ }
+
+ property Component circularGauge: CircularGaugeView {}
+
+ property Component dial: ControlView {
+ darkBackground: false
+
+ control: Column {
+ id: dialColumn
+ width: controlBounds.width
+ height: controlBounds.height - spacing
+ spacing: root.toPixels(0.05)
+
+ ColumnLayout {
+ id: volumeColumn
+ width: parent.width
+ height: (dialColumn.height - dialColumn.spacing) / 2
+ spacing: height * 0.025
+
+ Dial {
+ id: volumeDial
+ anchors.horizontalCenter: parent.horizontalCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ /*!
+ Determines whether the dial animates its rotation to the new value when
+ a single click or touch is received on the dial.
+ */
+ property bool animate: customizerItem.animate
+
+ Behavior on value {
+ enabled: volumeDial.animate && !volumeDial.pressed
+ NumberAnimation {
+ duration: 300
+ easing.type: Easing.OutSine
+ }
+ }
+ }
+
+ ControlLabel {
+ id: volumeText
+ text: "Volume"
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ }
+
+ ColumnLayout {
+ id: trebleColumn
+ width: parent.width
+ height: (dialColumn.height - dialColumn.spacing) / 2
+ spacing: height * 0.025
+
+ Dial {
+ id: dial2
+ anchors.horizontalCenter: parent.horizontalCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ stepSize: 1
+ maximumValue: 10
+
+ style: DialStyle {
+ labelInset: outerRadius * 0
+ }
+ }
+
+ ControlLabel {
+ id: trebleText
+ text: "Treble"
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ }
+ }
+
+ customizer: Column {
+ spacing: customizerPropertySpacing
+
+ property alias animate: animateCheckBox.checked
+
+ CustomizerLabel {
+ text: "Animate"
+ }
+
+ CustomizerSwitch {
+ id: animateCheckBox
+ }
+ }
+ }
+
+ property Component delayButton: ControlView {
+ darkBackground: false
+
+ control: DelayButton {
+ text: "Alarm"
+ anchors.centerIn: parent
+ }
+ }
+
+ property Component gauge: ControlView {
+ id: gaugeView
+ control: Gauge {
+ id: gauge
+ width: orientation === Qt.Vertical ? implicitWidth : gaugeView.controlBounds.width
+ height: orientation === Qt.Vertical ? gaugeView.controlBounds.height : implicitHeight
+ anchors.centerIn: parent
+
+ minimumValue: 0
+ value: customizerItem.value
+ maximumValue: 100
+ orientation: customizerItem.orientationFlag ? Qt.Vertical : Qt.Horizontal
+ tickmarkAlignment: orientation === Qt.Vertical
+ ? (customizerItem.alignFlag ? Qt.AlignLeft : Qt.AlignRight)
+ : (customizerItem.alignFlag ? Qt.AlignTop : Qt.AlignBottom)
+ }
+
+ customizer: Column {
+ spacing: customizerPropertySpacing
+
+ property alias value: valueSlider.value
+ property alias orientationFlag: orientationCheckBox.checked
+ property alias alignFlag: alignCheckBox.checked
+
+ CustomizerLabel {
+ text: "Value"
+ }
+
+ CustomizerSlider {
+ id: valueSlider
+ minimumValue: 0
+ value: 50
+ maximumValue: 100
+ }
+
+ CustomizerLabel {
+ text: "Vertical orientation"
+ }
+
+ CustomizerSwitch {
+ id: orientationCheckBox
+ checked: true
+ }
+
+ CustomizerLabel {
+ text: controlItem.orientation === Qt.Vertical ? "Left align" : "Top align"
+ }
+
+ CustomizerSwitch {
+ id: alignCheckBox
+ checked: true
+ }
+ }
+ }
+
+ property Component toggleButton: ControlView {
+ darkBackground: false
+
+ control: ToggleButton {
+ text: checked ? "On" : "Off"
+ anchors.centerIn: parent
+ }
+ }
+
+ property Component pieMenu: PieMenuControlView {}
+
+ property Component statusIndicator: ControlView {
+ id: statusIndicatorView
+ darkBackground: false
+
+ Timer {
+ id: recordingFlashTimer
+ running: true
+ repeat: true
+ interval: 1000
+ }
+
+ ColumnLayout {
+ id: indicatorLayout
+ width: statusIndicatorView.controlBounds.width * 0.25
+ height: statusIndicatorView.controlBounds.height * 0.75
+ anchors.centerIn: parent
+
+ Repeater {
+ model: ListModel {
+ id: indicatorModel
+ ListElement {
+ name: "Power"
+ indicatorColor: "#35e02f"
+ }
+ ListElement {
+ name: "Recording"
+ indicatorColor: "red"
+ }
+ }
+
+ ColumnLayout {
+ Layout.preferredWidth: indicatorLayout.width
+ spacing: 0
+
+ StatusIndicator {
+ id: indicator
+ color: indicatorColor
+ Layout.preferredWidth: statusIndicatorView.controlBounds.width * 0.07
+ Layout.preferredHeight: Layout.preferredWidth
+ Layout.alignment: Qt.AlignHCenter
+ on: true
+
+ Connections {
+ target: recordingFlashTimer
+ onTriggered: if (name == "Recording") indicator.active = !indicator.active
+ }
+ }
+ ControlLabel {
+ id: indicatorLabel
+ text: name
+ Layout.alignment: Qt.AlignHCenter
+ Layout.maximumWidth: parent.width
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+ }
+ }
+ }
+
+ property Component tumbler: ControlView {
+ id: tumblerView
+ darkBackground: false
+
+ Tumbler {
+ id: tumbler
+ anchors.centerIn: parent
+
+ // TODO: Use FontMetrics with 5.4
+ Label {
+ id: characterMetrics
+ font.bold: true
+ font.pixelSize: textSingleton.font.pixelSize * 1.25
+ font.family: openSans.name
+ visible: false
+ text: "M"
+ }
+
+ readonly property real delegateTextMargins: characterMetrics.width * 1.5
+ readonly property var days: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
+
+ TumblerColumn {
+ id: tumblerDayColumn
+
+ function updateModel() {
+ var previousIndex = tumblerDayColumn.currentIndex;
+ var newDays = tumbler.days[monthColumn.currentIndex];
+
+ if (!model) {
+ var array = [];
+ for (var i = 0; i < newDays; ++i) {
+ array.push(i + 1);
+ }
+ model = array;
+ } else {
+ // If we've already got days in the model, just add or remove
+ // the minimum amount necessary to make spinning the month column fast.
+ var difference = model.length - newDays;
+ if (model.length > newDays) {
+ model.splice(model.length - 1, difference);
+ } else {
+ var lastDay = model[model.length - 1];
+ for (i = lastDay; i < lastDay + difference; ++i) {
+ model.push(i + 1);
+ }
+ }
+ }
+
+ tumbler.setCurrentIndexAt(0, Math.min(newDays - 1, previousIndex));
+ }
+ }
+ TumblerColumn {
+ id: monthColumn
+ width: characterMetrics.width * 3 + tumbler.delegateTextMargins
+ model: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+ onCurrentIndexChanged: tumblerDayColumn.updateModel()
+ }
+ TumblerColumn {
+ width: characterMetrics.width * 4 + tumbler.delegateTextMargins
+ model: ListModel {
+ Component.onCompleted: {
+ for (var i = 2000; i < 2100; ++i) {
+ append({value: i.toString()});
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ FontLoader {
+ id: openSans
+ source: "qrc:/fonts/OpenSans-Regular.ttf"
+ }
+
+ property var componentMap: {
+ "CircularGauge": circularGauge,
+ "DelayButton": delayButton,
+ "Dial": dial,
+ "Gauge": gauge,
+ "PieMenu": pieMenu,
+ "StatusIndicator": statusIndicator,
+ "ToggleButton": toggleButton,
+ "Tumbler": tumbler
+ }
+
+ StackView {
+ id: stackView
+ anchors.fill: parent
+
+ initialItem: ListView {
+ model: ListModel {
+ ListElement {
+ title: "CircularGauge"
+ }
+ ListElement {
+ title: "DelayButton"
+ }
+ ListElement {
+ title: "Dial"
+ }
+ ListElement {
+ title: "Gauge"
+ }
+ ListElement {
+ title: "PieMenu"
+ }
+ ListElement {
+ title: "StatusIndicator"
+ }
+ ListElement {
+ title: "ToggleButton"
+ }
+ ListElement {
+ title: "Tumbler"
+ }
+ }
+
+ delegate: Button {
+ width: stackView.width
+ height: root.height * 0.125
+ text: title
+
+ style: BlackButtonStyle {
+ fontColor: root.darkFontColor
+ rightAlignedIconSource: "qrc:/images/icon-go.png"
+ }
+
+ onClicked: {
+ if (stackView.depth == 1) {
+ // Only push the control view if we haven't already pushed it...
+ stackView.push({item: componentMap[title]});
+ stackView.currentItem.forceActiveFocus();
+ }
+ }
+ }
+ }
+ }
+}
+
+
diff --git a/src/extras/CircularGauge.qml b/src/extras/CircularGauge.qml
new file mode 100644
index 00000000..7a91f8bf
--- /dev/null
+++ b/src/extras/CircularGauge.qml
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+// Workaround for QTBUG-37751; we need this import for RangeModel, although we shouldn't.
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Styles 1.3
+
+/*!
+ \qmltype CircularGauge
+ \inqmlmodule QtQuick.Extras
+ \since QtQuick.Extras 1.0
+ \ingroup extras
+ \ingroup extras-non-interactive
+ \brief A gauge that displays a value within a range along an arc.
+
+ \image circulargauge.png CircularGauge
+
+ The CircularGauge is similar to traditional mechanical gauges that use a
+ needle to display a value from some input, such as the speed of a vehicle or
+ air pressure, for example.
+
+ The minimum and maximum values displayable by the gauge can be set with the
+ \l minimumValue and \l maximumValue properties. The angle at which these
+ values are displayed can be set with the
+ \l {QtQuick.Extras.Styles::CircularGaugeStyle::}{minimumValueAngle} and
+ \l {QtQuick.Extras.Styles::CircularGaugeStyle::}{maximumValueAngle} properties of
+ \l {QtQuick.Extras.Styles::}{CircularGaugeStyle}.
+
+ Example:
+ \code
+ CircularGauge {
+ value: accelerating ? maximumValue : 0
+ anchors.centerIn: parent
+
+ property bool accelerating: false
+
+ Keys.onSpacePressed: accelerating = true
+ Keys.onReleased: {
+ if (event.key === Qt.Key_Space) {
+ accelerating = false;
+ event.accepted = true;
+ }
+ }
+
+ Component.onCompleted: forceActiveFocus()
+
+ Behavior on value {
+ NumberAnimation {
+ duration: 1000
+ }
+ }
+ }
+ \endcode
+
+ You can create a custom appearance for a CircularGauge by assigning a
+ \l {QtQuick.Extras.Styles::}{CircularGaugeStyle}.
+*/
+
+Control {
+ id: circularGauge
+
+ style: Qt.createComponent(StyleSettings.style + "/CircularGaugeStyle.qml", circularGauge)
+
+ /*!
+ \qmlproperty real CircularGauge::minimumValue
+
+ This property holds the smallest value displayed by the gauge.
+ */
+ property alias minimumValue: range.minimumValue
+
+ /*!
+ \qmlproperty real CircularGauge::maximumValue
+
+ This property holds the largest value displayed by the gauge.
+ */
+ property alias maximumValue: range.maximumValue
+
+ /*!
+ This property holds the current value displayed by the gauge, which will
+ always be between \l minimumValue and \l maximumValue, inclusive.
+ */
+ property alias value: range.value
+
+ /*!
+ \qmlproperty real CircularGauge::stepSize
+
+ This property holds the size of the value increments that the needle
+ displays.
+
+ For example, when stepSize is \c 10 and value is \c 0, adding \c 5 to
+ \l value will have no visible effect on the needle, although \l value
+ will still be incremented. Adding an extra \c 5 to \l value will then
+ cause the needle to point to \c 10.
+ */
+ property alias stepSize: range.stepSize
+
+ /*!
+ \since 1.2
+
+ This property determines whether or not the gauge displays tickmarks,
+ minor tickmarks, and labels.
+
+ For more fine-grained control over what is displayed, the following
+ style components of
+ \l {QtQuick.Extras.Styles::}{CircularGaugeStyle} can be
+ used:
+
+ \list
+ \li \l {QtQuick.Extras.Styles::CircularGaugeStyle::tickmark}{tickmark}
+ \li \l {QtQuick.Extras.Styles::CircularGaugeStyle::minorTickmark}{minorTickmark}
+ \li \l {QtQuick.Extras.Styles::CircularGaugeStyle::tickmarkLabel}{tickmarkLabel}
+ \endlist
+ */
+ property bool tickmarksVisible: true
+
+ RangeModel {
+ id: range
+ minimumValue: 0
+ maximumValue: 100
+ stepSize: 0
+ value: minimumValue
+ }
+}
diff --git a/src/extras/DelayButton.qml b/src/extras/DelayButton.qml
new file mode 100644
index 00000000..7218d457
--- /dev/null
+++ b/src/extras/DelayButton.qml
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private 1.0
+
+/*!
+ \qmltype DelayButton
+ \inherits QtQuickControls::Button
+ \inqmlmodule QtQuick.Extras
+ \since QtQuick.Extras 1.0
+ \ingroup extras
+ \ingroup extras-interactive
+ \brief A checkable button that triggers an action when held in long enough.
+
+ \image delaybutton.png A DelayButton
+
+ The DelayButton is a checkable button that incorporates a delay before
+ the button becomes checked and the \l activated signal is emitted. This
+ delay prevents accidental presses.
+
+ The current progress is expressed as a decimal value between \c 0.0 and
+ \c 1.0. The time it takes for \l activated to be emitted is measured in
+ milliseconds, and can be set with the \l delay property.
+
+ The progress is indicated by a progress indicator around the button. When
+ the indicator reaches completion, it flashes.
+
+ \image delaybutton-progress.png A DelayButton being held down
+ A DelayButton being held down
+ \image delaybutton-activated.png A DelayButton after being activated
+ A DelayButton after being activated
+
+ You can create a custom appearance for a DelayButton by assigning a
+ \l {QtQuick.Extras.Styles::}{DelayButtonStyle}.
+*/
+
+Button {
+ id: root
+
+ style: Qt.createComponent(StyleSettings.style + "/DelayButtonStyle.qml", root)
+
+ /*!
+ \qmlproperty real DelayButton::progress
+
+ This property holds the current progress as displayed by the progress
+ indicator, in the range \c 0.0 - \c 1.0.
+ */
+ readonly property alias progress: root.__progress
+
+ /*!
+ This property holds the time it takes (in milliseconds) for \l progress
+ to reach \c 1.0 and emit \l activated.
+
+ The default value is \c 3000 ms.
+ */
+ property int delay: 3000
+
+ /*!
+ This signal is emitted when \l progress reaches \c 1.0 and the button
+ becomes checked.
+ */
+ signal activated
+
+
+ /*! \internal */
+ property real __progress: 0.0
+
+ Behavior on __progress {
+ id: progressBehavior
+
+ NumberAnimation {
+ id: numberAnimation
+ }
+ }
+
+ Binding {
+ // Force checkable to false to get full control over the checked -property
+ target: root
+ property: "checkable"
+ value: false
+ }
+
+ onProgressChanged: {
+ if (__progress === 1.0) {
+ checked = true;
+ activated();
+ }
+ }
+
+ onCheckedChanged: {
+ if (checked) {
+ if (__progress < 1) {
+ // Programmatically activated the button; don't animate.
+ progressBehavior.enabled = false;
+ __progress = 1;
+ progressBehavior.enabled = true;
+ }
+ } else {
+ // Unchecked the button after it was flashing; it should instantly stop
+ // flashing (with no reversed progress bar).
+ progressBehavior.enabled = false;
+ __progress = 0;
+ progressBehavior.enabled = true;
+ }
+ }
+
+ onPressedChanged: {
+ if (checked) {
+ if (pressed) {
+ // Pressed the button to stop the activation.
+ checked = false;
+ }
+ } else {
+ var effectiveDelay = pressed ? delay : delay * 0.3;
+ // Not active. Either the button is being held down or let go.
+ numberAnimation.duration = Math.max(0, (pressed ? 1 - __progress : __progress) * effectiveDelay);
+ __progress = pressed ? 1 : 0;
+ }
+ }
+}
diff --git a/src/extras/Dial.qml b/src/extras/Dial.qml
new file mode 100644
index 00000000..aa1dc4d6
--- /dev/null
+++ b/src/extras/Dial.qml
@@ -0,0 +1,228 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private 1.0
+
+/*!
+ \qmltype Dial
+ \inqmlmodule QtQuick.Extras
+ \since QtQuick.Extras 1.0
+ \ingroup extras
+ \ingroup extras-interactive
+ \brief A circular dial that is rotated to set a value.
+
+ \image dial.png A Dial
+
+ The Dial is similar to a traditional dial knob that is found on devices
+ such as stereos or industrial equipment. It allows the user to specify a
+ value within a range.
+
+ Like CircularGauge, Dial can display tickmarks to give an indication of
+ the current value. When a suitable stepSize is combined with
+ \l {QtQuick.Extras.Styles::DialStyle::}{tickmarkStepSize},
+ the dial "snaps" to each tickmark.
+
+ You can create a custom appearance for a Dial by assigning a
+ \l {QtQuick.Extras.Styles::}{DialStyle}.
+*/
+
+Control {
+ id: dial
+
+ activeFocusOnTab: true
+ style: Qt.createComponent(StyleSettings.style + "/DialStyle.qml", dial)
+
+ /*!
+ \qmlproperty real Dial::value
+
+ The angle of the handle along the dial, in the range of
+ \c 0.0 to \c 1.0.
+
+ The default value is \c{0.0}.
+ */
+ property alias value: range.value
+
+ /*!
+ \qmlproperty real Dial::minimumValue
+
+ The smallest value allowed by the dial.
+
+ The default value is \c{0.0}.
+
+ \sa value, maximumValue
+ */
+ property alias minimumValue: range.minimumValue
+
+ /*!
+ \qmlproperty real Dial::maximumValue
+
+ The largest value allowed by the dial.
+
+ The default value is \c{1.0}.
+
+ \sa value, minimumValue
+ */
+ property alias maximumValue: range.maximumValue
+
+ /*!
+ \qmlproperty real Dial::hovered
+
+ This property holds whether the button is being hovered.
+ */
+ readonly property alias hovered: mouseArea.containsMouse
+
+ /*!
+ \qmlproperty real Dial::stepSize
+
+ The default value is \c{0.0}.
+ */
+ property alias stepSize: range.stepSize
+
+ /*!
+ \internal
+ Determines whether the dial can be freely rotated past the zero marker.
+
+ The default value is \c false.
+ */
+ property bool __wrap: false
+
+ /*!
+ This property specifies whether the dial should gain active focus when
+ pressed.
+
+ The default value is \c false.
+
+ \sa pressed
+ */
+ property bool activeFocusOnPress: false
+
+ /*!
+ \qmlproperty bool Dial::pressed
+
+ Returns \c true if the dial is pressed.
+
+ \sa activeFocusOnPress
+ */
+ readonly property alias pressed: mouseArea.pressed
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ This property determines whether or not the dial displays tickmarks,
+ minor tickmarks, and labels.
+
+ For more fine-grained control over what is displayed, the following
+ style components of
+ \l {QtQuick.Extras.Styles::}{DialStyle} can be used:
+
+ \list
+ \li \l {QtQuick.Extras.Styles::DialStyle::tickmark}{tickmark}
+ \li \l {QtQuick.Extras.Styles::DialStyle::minorTickmark}{minorTickmark}
+ \li \l {QtQuick.Extras.Styles::DialStyle::tickmarkLabel}{tickmarkLabel}
+ \endlist
+
+ The default value is \c true.
+ */
+ property bool tickmarksVisible: true
+
+ Keys.onLeftPressed: value -= stepSize
+ Keys.onDownPressed: value -= stepSize
+ Keys.onRightPressed: value += stepSize
+ Keys.onUpPressed: value += stepSize
+ Keys.onPressed: {
+ if (event.key === Qt.Key_Home) {
+ value = minimumValue;
+ event.accepted = true;
+ } else if (event.key === Qt.Key_End) {
+ value = maximumValue;
+ event.accepted = true;
+ }
+ }
+
+ RangeModel {
+ id: range
+ minimumValue: 0.0
+ maximumValue: 1.0
+ stepSize: 0
+ value: 0
+ }
+
+ MouseArea {
+ id: mouseArea
+ hoverEnabled: true
+ parent: __panel.background.parent
+ anchors.fill: parent
+
+ onPositionChanged: {
+ if (pressed) {
+ value = valueFromPoint(mouseX, mouseY);
+ }
+ }
+ onPressed: {
+ if (!__style.__dragToSet)
+ value = valueFromPoint(mouseX, mouseY);
+
+ if (activeFocusOnPress)
+ dial.forceActiveFocus();
+ }
+
+ function bound(val) { return Math.max(minimumValue, Math.min(maximumValue, val)); }
+
+ function valueFromPoint(x, y)
+ {
+ var yy = height / 2.0 - y;
+ var xx = x - width / 2.0;
+ var angle = (xx || yy) ? Math.atan2(yy, xx) : 0;
+
+ if (angle < Math.PI/ -2)
+ angle = angle + Math.PI * 2;
+
+ var range = maximumValue - minimumValue;
+ var value;
+ if (__wrap)
+ value = (minimumValue + range * (Math.PI * 3 / 2 - angle) / (2 * Math.PI));
+ else
+ value = (minimumValue + range * (Math.PI * 4 / 3 - angle) / (Math.PI * 10 / 6));
+
+ return bound(value)
+ }
+ }
+}
diff --git a/src/extras/Gauge.qml b/src/extras/Gauge.qml
new file mode 100644
index 00000000..1a845ee3
--- /dev/null
+++ b/src/extras/Gauge.qml
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private 1.0
+
+/*!
+ \qmltype Gauge
+ \inqmlmodule QtQuick.Extras
+ \since QtQuick.Extras 1.0
+ \ingroup extras
+ \ingroup extras-non-interactive
+ \brief A straight gauge that displays a value within a range.
+
+ \image gauge.png Gauge
+
+ The Gauge control displays a value within some range along a horizontal or
+ vertical axis. It can be thought of as an extension of ProgressBar,
+ providing tickmarks and labels to provide a visual measurement of the
+ progress.
+
+ The minimum and maximum values displayable by the gauge can be set with the
+ \l minimumValue and \l maximumValue properties.
+
+ Example:
+ \code
+ Gauge {
+ minimumValue: 0
+ value: 50
+ maximumValue: 100
+ anchors.centerIn: parent
+ }
+ \endcode
+
+ You can create a custom appearance for a Gauge by assigning a
+ \l {QtQuick.Extras.Styles::}{GaugeStyle}.
+*/
+
+Control {
+ id: gauge
+
+ style: Qt.createComponent(StyleSettings.style + "/GaugeStyle.qml", gauge)
+
+ /*!
+ This property holds the smallest value displayed by the gauge.
+
+ The default value is \c 0.
+ */
+ property alias minimumValue: range.minimumValue
+
+ /*!
+ This property holds the value displayed by the gauge.
+
+ The default value is \c 0.
+ */
+ property alias value: range.value
+
+ /*!
+ This property holds the largest value displayed by the gauge.
+
+ The default value is \c 100.
+ */
+ property alias maximumValue: range.maximumValue
+
+ /*!
+ This property determines the orientation of the gauge.
+
+ The default value is \c Qt.Vertical.
+ */
+ property int orientation: Qt.Vertical
+
+ /*!
+ This property determines the alignment of each tickmark within the
+ gauge. When \l orientation is \c Qt.Vertical, the valid values are:
+
+ \list
+ \li Qt.AlignLeft
+ \li Qt.AlignRight
+ \endlist
+
+ Any other value will cause \c Qt.AlignLeft to be used, which is also the
+ default value for this orientation.
+
+ When \l orientation is \c Qt.Horizontal, the valid values are:
+
+ \list
+ \li Qt.AlignTop
+ \li Qt.AlignBottom
+ \endlist
+
+ Any other value will cause \c Qt.AlignBottom to be used, which is also
+ the default value for this orientation.
+ */
+ property int tickmarkAlignment: orientation == Qt.Vertical ? Qt.AlignLeft : Qt.AlignBottom
+ property int __tickmarkAlignment: {
+ if (orientation == Qt.Vertical) {
+ return (tickmarkAlignment == Qt.AlignLeft || tickmarkAlignment == Qt.AlignRight) ? tickmarkAlignment : Qt.AlignLeft;
+ }
+
+ return (tickmarkAlignment == Qt.AlignTop || tickmarkAlignment == Qt.AlignBottom) ? tickmarkAlignment : Qt.AlignBottom;
+ }
+
+ /*!
+ \internal
+
+ TODO: finish this
+
+ This property determines whether or not the tickmarks and their labels
+ are drawn inside (over) the gauge. The value of this property affects
+ \l tickmarkAlignment.
+ */
+ property bool __tickmarksInside: false
+
+ /*!
+ This property determines the rate at which tickmarks are drawn on the
+ gauge. The lower the value, the more often tickmarks are drawn.
+
+ The default value is \c 10.
+ */
+ property real tickmarkStepSize: 10
+
+ /*!
+ This property determines the amount of minor tickmarks drawn between
+ each regular tickmark.
+
+ The default value is \c 4.
+ */
+ property int minorTickmarkCount: 4
+
+ /*!
+ \qmlproperty font Gauge::font
+
+ The font to use for the tickmark text.
+ */
+ property alias font: hiddenText.font
+
+ /*!
+ \since QtQuick.Extras 1.3
+
+ This property accepts a function that formats the given \a value for
+ display in
+ \l {QtQuick.Extras.Styles::GaugeStyle}{tickmarkLabel}.
+
+ For example, to provide a custom format that displays all values with 3
+ decimal places:
+
+ \code
+ formatValue: function(value) {
+ return value.toFixed(3);
+ }
+ \endcode
+
+ The default function does no formatting.
+ */
+ property var formatValue: function(value) {
+ return value;
+ }
+
+ property alias __hiddenText: hiddenText
+ Text {
+ id: hiddenText
+ text: formatValue(maximumValue)
+ visible: false
+ }
+
+ RangeModel {
+ id: range
+ minimumValue: 0
+ value: 0
+ maximumValue: 100
+ }
+}
diff --git a/src/extras/PieMenu.qml b/src/extras/PieMenu.qml
new file mode 100644
index 00000000..94b6d414
--- /dev/null
+++ b/src/extras/PieMenu.qml
@@ -0,0 +1,747 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Private.CppUtils 1.0 as CppUtils
+import QtQuick.Extras.Styles 1.3
+
+/*!
+ \qmltype PieMenu
+ \inqmlmodule QtQuick.Extras
+ \since QtQuick.Extras 1.0
+ \ingroup extras
+ \ingroup extras-interactive
+ \brief A popup menu that displays several menu items along an arc.
+
+ \image piemenu.png A PieMenu
+
+ The PieMenu provides a radial context menu as an alternative to a
+ traditional menu. All of the items in a PieMenu are an equal distance
+ from the center of the control.
+
+ \section2 Populating the Menu
+
+ To create a menu, define at least one MenuItem as a child of it:
+ \code
+ PieMenu {
+ id: pieMenu
+
+ MenuItem {
+ text: "Action 1"
+ onTriggered: print("Action 1")
+ }
+ MenuItem {
+ text: "Action 2"
+ onTriggered: print("Action 2")
+ }
+ MenuItem {
+ text: "Action 3"
+ onTriggered: print("Action 3")
+ }
+ }
+ \endcode
+
+ By default, only the currently selected item's text is displayed above the
+ menu. To provide text that is always visible when there is no current item,
+ set the \l title property.
+
+ \section2 Displaying the Menu
+
+ The typical use case for a menu is to open at the point of the mouse
+ cursor after a right click occurs. To do that, define a MouseArea that
+ covers the region upon which clicks should open the menu. When the
+ MouseArea is right-clicked, call the popup() function:
+ \code
+ MouseArea {
+ anchors.fill: parent
+ acceptedButtons: Qt.RightButton
+
+ onClicked: pieMenu.popup(mouseX, mouseY)
+ }
+ \endcode
+
+ If the menu is opened in a position where some of its menu items would be
+ outside of \l boundingItem, it is automatically moved to a position where
+ they will not be hidden. By default, the boundingItem is set to the parent
+ of the menu. It can also be set to \c null to prevent this behavior.
+
+ PieMenu can be displayed at any position on the screen. With a traditional
+ context menu, the menu would be positioned with its top left corner at the
+ position of the right click, but since PieMenu is radial, we position it
+ centered over the position of the right click.
+
+ To create a PieMenu that opens after a long press and selects items upon
+ releasing, you can combine ActivationMode.ActivateOnRelease with a
+ MouseArea using a Timer:
+ \code
+ MouseArea {
+ id: touchArea
+ anchors.fill: parent
+
+ Timer {
+ id: pressAndHoldTimer
+ interval: 300
+ onTriggered: pieMenu.popup(touchArea.mouseX, touchArea.mouseY);
+ }
+
+ onPressed: pressAndHoldTimer.start()
+ onReleased: pressAndHoldTimer.stop();
+ }
+
+ PieMenu {
+ id: pieMenu
+
+ triggerMode: TriggerMode.TriggerOnRelease
+
+ MenuItem {
+ text: "Action 1"
+ onTriggered: print("Action 1")
+ }
+ MenuItem {
+ text: "Action 2"
+ onTriggered: print("Action 2")
+ }
+ MenuItem {
+ text: "Action 3"
+ onTriggered: print("Action 3")
+ }
+ }
+ \endcode
+
+ You can hide individual menu items by setting their visible property to
+ \c false. Hiding items does not affect the
+ \l {QtQuick.Extras.Styles::PieMenuStyle::}{startAngle} or
+ \l {QtQuick.Extras.Styles::PieMenuStyle::}{endAngle}; the
+ remaining items will grow to consume the available space.
+
+ You can create a custom appearance for a PieMenu by assigning a
+ \l {QtQuick.Extras.Styles::}{PieMenuStyle}.
+*/
+
+Control {
+ id: pieMenu
+ visible: false
+
+ style: Qt.createComponent(StyleSettings.style + "/PieMenuStyle.qml", pieMenu)
+
+ /*!
+ This property reflects the angle (in radians) created by the imaginary
+ line from the center of the menu to the position of the cursor.
+
+ Its value is undefined when the menu is not visible.
+ */
+ readonly property real selectionAngle: {
+ var centerX = width / 2;
+ var centerY = height / 2;
+ var targetX = __protectedScope.selectionPos.x;
+ var targetY = __protectedScope.selectionPos.y;
+
+ var xDistance = centerX - targetX;
+ var yDistance = centerY - targetY;
+
+ var angleToTarget = Math.atan2(xDistance, yDistance) * -1;
+ angleToTarget;
+ }
+
+ /*!
+ \qmlproperty enumeration PieMenu::activationMode
+
+ This property determines the method for selecting items in the menu.
+
+ \list
+ \li An activationMode of \a ActivationMode.ActivateOnPress means that menu
+ items will only be selected when a mouse press event occurs over them.
+
+ \li An activationMode of \a ActivationMode.ActivateOnRelease means that menu
+ items will only be selected when a mouse release event occurs over them.
+ This means that the user must keep the mouse button down after opening
+ the menu and release the mouse over the item they wish to select.
+
+ \li An activationMode of \a ActivationMode.ActivateOnClick means that menu
+ items will only be selected when the user clicks once over them.
+ \endlist
+
+ \warning Changing the activationMode while the menu is visible will
+ result in undefined behavior.
+
+ \deprecated Use triggerMode instead.
+ */
+ property alias activationMode: pieMenu.triggerMode
+
+ /*!
+ \qmlproperty enumeration PieMenu::triggerMode
+
+ This property determines the method for selecting items in the menu.
+
+ \list
+ \li A triggerMode of \a TriggerMode.TriggerOnPress means that menu
+ items will only be selected when a mouse press event occurs over them.
+
+ \li A triggerMode of \a TriggerMode.TriggerOnRelease means that menu
+ items will only be selected when a mouse release event occurs over them.
+ This means that the user must keep the mouse button down after opening
+ the menu and release the mouse over the item they wish to select.
+
+ \li A triggerMode of \a TriggerMode.TriggerOnClick means that menu
+ items will only be selected when the user clicks once over them.
+ \endlist
+
+ \warning Changing the triggerMode while the menu is visible will
+ result in undefined behavior.
+ */
+ property int triggerMode: TriggerMode.TriggerOnClick
+
+ /*!
+ \qmlproperty list<MenuItem> menuItems
+
+ The list of menu items displayed by this menu.
+
+ You can assign menu items by declaring them as children of PieMenu:
+ \code
+ PieMenu {
+ MenuItem {
+ text: "Action 1"
+ onTriggered: function() { print("Action 1"); }
+ }
+ MenuItem {
+ text: "Action 2"
+ onTriggered: function() { print("Action 2"); }
+ }
+ MenuItem {
+ text: "Action 3"
+ onTriggered: function() { print("Action 3"); }
+ }
+ }
+ \endcode
+ */
+ default property alias menuItems: defaultPropertyHack.menuItems
+
+ QtObject {
+ // Can't specify a list as a default property (QTBUG-10822)
+ id: defaultPropertyHack
+ property list<MenuItem> menuItems
+ }
+
+ /*!
+ \qmlproperty int PieMenu::currentIndex
+
+ The index of the the menu item that is currently under the mouse,
+ or \c -1 if there is no such item.
+ */
+ readonly property alias currentIndex: protectedScope.currentIndex
+
+ /*!
+ \qmlproperty int PieMenu::currentItem
+
+ The menu item that is currently under the mouse, or \c null if there is
+ no such item.
+ */
+ readonly property alias currentItem: protectedScope.currentItem
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ This property defines the text that is shown above the menu when
+ there is no current menu item (currentIndex is \c -1).
+
+ The default value is \c "" (an empty string).
+ */
+ property string title: ""
+
+ /*!
+ \since QtQuick.Extras 1.2
+
+ The item which the menu must stay within.
+
+ A typical use case for PieMenu involves:
+
+ \list
+ \li A MouseArea that determines the clickable area within which the
+ menu can be opened.
+ \li The bounds that the menu must not go outside of.
+ \endlist
+
+ Although they sound similar, they have different purposes. Consider the
+ example below:
+
+ \image piemenu-boundingItem-example.png Canvas boundingItem example
+
+ The user can only open the menu within the inner rectangle. In this
+ case, they've opened the menu on the edge of the MouseArea, but there
+ would not be enough room to display the entire menu centered at the
+ cursor position, so it was moved to the left.
+
+ If for some reason we didn't want this restriction, we can set
+ boundingItem to \c null:
+
+ \image piemenu-boundingItem-null-example.png Canvas null boundingItem example
+
+ By default, the menu's \l {Item::}{parent} is the boundingItem.
+ */
+ property Item boundingItem: parent
+
+ /*!
+ \qmlmethod void popup(real x, real y)
+
+ Opens the menu at coordinates \a x, \a y.
+ */
+ function popup(x, y) {
+ if (x !== undefined)
+ pieMenu.x = x - pieMenu.width / 2;
+ if (y !== undefined)
+ pieMenu.y = y - pieMenu.height / 2;
+
+ pieMenu.visible = true;
+ }
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ \qmlmethod void addItem(string text)
+
+ Adds an item to the end of the menu items.
+
+ Equivalent to passing calling \c insertItem(menuItems.length, text).
+
+ Returns the newly added item.
+ */
+ function addItem(text) {
+ return insertItem(menuItems.length, text);
+ }
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ \qmlmethod void insertItem(int before, string text)
+
+ Inserts a MenuItem with \a text before the index at \a before.
+
+ To insert an item at the end, pass \c menuItems.length.
+
+ Returns the newly inserted item, or \c null if \a before is invalid.
+ */
+ function insertItem(before, text) {
+ if (before < 0 || before > menuItems.length) {
+ return null;
+ }
+
+ var newItems = __protectedScope.copyItemsToJsArray();
+ var newItem = Qt.createQmlObject("import QtQuick.Controls 1.1; MenuItem {}", pieMenu, "");
+ newItem.text = text;
+ newItems.splice(before, 0, newItem);
+
+ menuItems = newItems;
+ return newItem;
+ }
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ \qmlmethod void removeItem(item)
+
+ Removes \a item from the menu.
+ */
+ function removeItem(item) {
+ for (var i = 0; i < menuItems.length; ++i) {
+ if (menuItems[i] === item) {
+ var newItems = __protectedScope.copyItemsToJsArray();
+
+ newItems.splice(i, 1);
+ menuItems = newItems;
+ break;
+ }
+ }
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ hoverEnabled: !Settings.hasTouchScreen && triggerMode !== TriggerMode.TriggerOnRelease
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+ onContainsMouseChanged: if (!containsMouse) __protectedScope.currentIndex = -1
+ objectName: "PieMenu internal MouseArea"
+
+ // The mouse thief also updates the selectionPos, so we can't bind to
+ // this mouseArea's mouseX/mouseY.
+ onPositionChanged: {
+ __protectedScope.selectionPos = Qt.point(mouseX, mouseY)
+ }
+ }
+
+ /*! \internal */
+ property alias __mouseThief: mouseThief
+
+ CppUtils.MouseThief {
+ id: mouseThief
+
+ onPressed: {
+ __protectedScope.selectionPos = Qt.point(mouseX, mouseY);
+ if (__protectedScope.handleEvent(ActivationMode.ActivateOnPress)) {
+ mouseThief.acceptCurrentEvent();
+ // We handled the press event, so we can reset this now.
+ mouseThief.receivedPressEvent = false;
+ }
+ }
+ onReleased: {
+ __protectedScope.selectionPos = Qt.point(mouseX, mouseY);
+ if (__protectedScope.handleEvent(ActivationMode.ActivateOnRelease)) {
+ mouseThief.acceptCurrentEvent();
+ // We handled the press event, so we can reset this now.
+ mouseThief.receivedPressEvent = false;
+ }
+ __protectedScope.pressedIndex = -1;
+ }
+ onClicked: {
+ __protectedScope.selectionPos = Qt.point(mouseX, mouseY);
+ if (__protectedScope.handleEvent(ActivationMode.ActivateOnClick)) {
+ mouseThief.acceptCurrentEvent();
+ }
+
+ // Clicked is the last stage in a click event (press, release, click),
+ // so we can safely set this to false now.
+ mouseThief.receivedPressEvent = false;
+ }
+ onTouchUpdate: __protectedScope.selectionPos = Qt.point(mouseX, mouseY)
+ }
+
+ onVisibleChanged: {
+ // parent check is for when it's created without a parent,
+ // which we do in the tests, for example.
+ if (parent) {
+ if (visible) {
+ if (boundingItem)
+ __protectedScope.moveWithinBounds();
+
+ // We need to grab the mouse so that we can detect released()
+ // (which is only emitted after pressed(), which our MouseArea can't
+ // emit as it didn't have focus until we were made visible).
+ mouseThief.grabMouse(mouseArea);
+ } else {
+ mouseThief.ungrabMouse();
+ __protectedScope.selectionPos = Qt.point(width / 2, height / 2);
+ }
+ }
+ }
+ onSelectionAngleChanged: __protectedScope.checkForCurrentItem()
+
+ /*! \internal */
+ property QtObject __protectedScope: QtObject {
+ id: protectedScope
+
+ property int currentIndex: -1
+ property MenuItem currentItem: currentIndex != -1 ? visibleItems[currentIndex] : null
+ property point selectionPos: Qt.point(width / 2, height / 2)
+ property int pressedIndex: -1
+ readonly property var localRect: mapFromItem(mouseArea, mouseArea.mouseX, mouseArea.mouseY)
+ readonly property var visibleItems: {
+ var items = [];
+ for (var i = 0; i < menuItems.length; ++i) {
+ if (menuItems[i].visible) {
+ items.push(menuItems[i]);
+ }
+ }
+ return items;
+ }
+
+ onSelectionPosChanged: __protectedScope.checkForCurrentItem()
+
+ // Can't bind directly, because the menu sets this to (0, 0) on closing.
+ onLocalRectChanged: {
+ if (visible)
+ selectionPos = Qt.point(localRect.x, localRect.y);
+ }
+
+ function copyItemsToJsArray() {
+ var newItems = [];
+ for (var j = 0; j < menuItems.length; ++j) {
+ newItems.push(menuItems[j]);
+ }
+ return newItems;
+ }
+
+ /*!
+ Returns \c true if the mouse is over the section at \a itemIndex.
+ */
+ function isMouseOver(itemIndex) {
+ if (__style == null)
+ return false;
+
+ // Our mouse angle's origin is north naturally, but the section angles need to be
+ // altered to have their origin north, so we need to remove the alteration here in order to compare properly.
+ // For example, section 0 will start at -1.57, whereas we want it to start at 0.
+ var sectionStart = __protectedScope.sectionStartAngle(itemIndex) + Math.PI / 2;
+ var sectionEnd = __protectedScope.sectionEndAngle(itemIndex) + Math.PI / 2;
+
+ var selAngle = selectionAngle;
+ var pastStart = selAngle >= sectionStart;
+ var isWithinOurAngle = false;
+
+ if (sectionStart > CppUtils.MathUtils.pi2) {
+ sectionStart %= CppUtils.MathUtils.pi2;
+ } else if (sectionStart < -CppUtils.MathUtils.pi2) {
+ sectionStart %= -CppUtils.MathUtils.pi2;
+ }
+
+ if (sectionEnd > CppUtils.MathUtils.pi2) {
+ sectionEnd %= CppUtils.MathUtils.pi2;
+ } else if (sectionEnd < -CppUtils.MathUtils.pi2) {
+ sectionEnd %= -CppUtils.MathUtils.pi2;
+ }
+
+ // If the section crosses the -180 => 180 wrap-around point (from atan2),
+ // temporarily rotate the section so it doesn't.
+ if (sectionStart > Math.PI) {
+ var difference = sectionStart - Math.PI;
+ selAngle -= difference;
+ sectionStart -= difference;
+ sectionEnd -= difference;
+ } else if (sectionStart < -Math.PI) {
+ difference = Math.abs(sectionStart - (-Math.PI));
+ selAngle += difference;
+ sectionStart += difference;
+ sectionEnd += difference;
+ }
+
+ if (sectionEnd > Math.PI) {
+ difference = sectionEnd - Math.PI;
+ selAngle -= difference;
+ sectionStart -= difference;
+ sectionEnd -= difference;
+ } else if (sectionEnd < -Math.PI) {
+ difference = Math.abs(sectionEnd - (-Math.PI));
+ selAngle += difference;
+ sectionStart += difference;
+ sectionEnd += difference;
+ }
+
+ // If we moved the mouse past -180 or 180, we need to move it back within,
+ // without changing its actual direction.
+ if (selAngle > Math.PI) {
+ selAngle = selAngle - CppUtils.MathUtils.pi2;
+ } else if (selAngle < -Math.PI) {
+ selAngle += CppUtils.MathUtils.pi2;
+ }
+
+ if (sectionStart > sectionEnd) {
+ isWithinOurAngle = selAngle >= sectionEnd && selAngle < sectionStart;
+ } else {
+ isWithinOurAngle = selAngle >= sectionStart && selAngle < sectionEnd;
+ }
+
+ var x1 = width / 2;
+ var y1 = height / 2;
+ var x2 = __protectedScope.selectionPos.x;
+ var y2 = __protectedScope.selectionPos.y;
+ var distanceFromCenter = Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2);
+ var cancelRadiusSquared = __style.cancelRadius * __style.cancelRadius;
+ var styleRadiusSquared = __style.radius * __style.radius;
+ var isWithinOurRadius = distanceFromCenter >= cancelRadiusSquared
+ && distanceFromCenter < styleRadiusSquared;
+ return isWithinOurAngle && isWithinOurRadius;
+ }
+
+ readonly property real arcRange: endAngleRadians - startAngleRadians
+
+ /*!
+ The size of one section in radians.
+ */
+ readonly property real sectionSize: arcRange / visibleItems.length
+ readonly property real startAngleRadians: CppUtils.MathUtils.degToRadOffset(__style.startAngle)
+ readonly property real endAngleRadians: CppUtils.MathUtils.degToRadOffset(__style.endAngle)
+
+ readonly property real circumferenceOfFullRange: 2 * Math.PI * __style.radius
+ readonly property real percentageOfFullRange: (arcRange / (Math.PI * 2))
+ readonly property real circumferenceOfSection: (sectionSize / arcRange) * (percentageOfFullRange * circumferenceOfFullRange)
+
+ function sectionStartAngle(section) {
+ var start = startAngleRadians + section * sectionSize;
+ return start;
+ }
+
+ function sectionCenterAngle(section) {
+ return (sectionStartAngle(section) + sectionEndAngle(section)) / 2;
+ }
+
+ function sectionEndAngle(section) {
+ var end = startAngleRadians + section * sectionSize + sectionSize;
+ return end;
+ }
+
+ function handleEvent(eventType) {
+ if (!visible)
+ return false;
+
+ checkForCurrentItem();
+
+ if (eventType === TriggerMode.TriggerOnPress)
+ pressedIndex = currentIndex;
+
+ if (eventType === TriggerMode.TriggerOnPress && triggerMode === TriggerMode.TriggerOnClick) {
+ // We *MUST* accept press events if we plan on also accepting the release
+ // (aka click, since we create that ourselves) event. If we don't, the
+ // external mouse area gets the press event but not the release event,
+ // and won't open until a release event is received, which means until the
+ // user taps twice on the external mouse area.
+ // Usually, we accept the current event in the onX MouseThief event handlers above,
+ // but there we set receivedPressEvent to false if this function says it handled
+ // the event, which we don't want, since TriggerOnClick is expecting to have
+ // received a press event. So, we ensure that receivedPressEvent stays true
+ // by saying we didn't handle the event, even though we actually do.
+ mouseThief.acceptCurrentEvent();
+ return false;
+ }
+
+ if (triggerMode === eventType) {
+ if (eventType === TriggerMode.TriggerOnClick && !mouseThief.receivedPressEvent) {
+ // When the trigger mode is TriggerOnClick, we can't
+ // act on a click event if we didn't receive the press.
+ return false;
+ }
+
+ // Setting visible to false resets the selectionPos to the center
+ // of the menu, which in turn causes the currentItem check to be re-evaluated,
+ // which sees that there's no current item because the selectionPos is centered.
+ // To avoid all of that, we store these variables before setting visible to false.
+ var currentItemBeforeClosing = currentItem;
+ var selectionPosBeforeClosing = selectionPos;
+ var currentIndexBeforeClosing = currentIndex;
+
+ // If the cursor was over an item; trigger it. If it wasn't,
+ // close our menu regardless. We do this first so that it's
+ // possible to keep the menu open by setting visible to true in onTriggered.
+ visible = false;
+
+ if (currentItemBeforeClosing) {
+ currentItemBeforeClosing.trigger();
+ }
+
+ if (visible && !Settings.hasTouchScreen && !Settings.isMobile) {
+ // The user kept the menu open in onTriggered, so restore the hover stuff.
+ selectionPos = selectionPosBeforeClosing;
+ currentIndex = currentIndexBeforeClosing;
+ }
+
+ // If the trigger mode and event are Release, we should ensure
+ // that we received a press event beforehand. If we didn't, we shouldn't steal
+ // the event in MouseThief's event filter.
+ return mouseThief.receivedPressEvent;
+ }
+ return false;
+ }
+
+ function checkForCurrentItem() {
+ // Use a temporary varibable because setting currentIndex to -1 here
+ // will trigger onCurrentIndexChanged.
+ if (!!visibleItems) {
+ var hoveredIndex = -1;
+ for (var i = 0; i < visibleItems.length; ++i) {
+ if (isMouseOver(i)) {
+ hoveredIndex = i;
+ break;
+ }
+ }
+ currentIndex = hoveredIndex;
+ }
+ }
+
+ function simplifyAngle(angle) {
+ var simplified = angle % 360;
+ if (simplified < 0)
+ simplified += 360;
+ return simplified;
+ }
+
+ function isWithinBottomEdge() {
+ var start = simplifyAngle(pieMenu.__style.startAngle);
+ var end = simplifyAngle(pieMenu.__style.endAngle);
+ return start >= 270 && end <= 90 && ((start < 360 && end <= 360) || (start >= 0 && end > 0));
+ }
+
+ function isWithinTopEdge() {
+ var start = simplifyAngle(pieMenu.__style.startAngle);
+ var end = simplifyAngle(pieMenu.__style.endAngle);
+ return start >= 90 && start < 270 && end > 90 && end <= 270;
+ }
+
+ function isWithinLeftEdge() {
+ var start = simplifyAngle(pieMenu.__style.startAngle);
+ var end = simplifyAngle(pieMenu.__style.endAngle);
+ return (start === 360 || start >= 0) && start < 180 && end > 0 && end <= 180;
+ }
+
+ function isWithinRightEdge() {
+ var start = simplifyAngle(pieMenu.__style.startAngle);
+ var end = simplifyAngle(pieMenu.__style.endAngle);
+ return start >= 180 && start < 360 && end > 180 && (end === 360 || end === 0);
+ }
+
+ /*!
+ Moves the menu if it would open with parts outside of \a rootParent.
+ */
+ function moveWithinBounds() {
+ // Find the bounding rect of the bounding item in the parent's referential.
+ var topLeft = boundingItem.mapToItem(pieMenu.parent, 0, 0);
+ var topRight = boundingItem.mapToItem(pieMenu.parent, boundingItem.width, 0);
+ var bottomLeft = boundingItem.mapToItem(pieMenu.parent, 0, boundingItem.height);
+ var bottomRight = boundingItem.mapToItem(pieMenu.parent, boundingItem.width, boundingItem.height);
+
+ // If the boundingItem is rotated, normalize the bounding rect.
+ topLeft.x = Math.min(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
+ topLeft.y = Math.min(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
+ bottomRight.x = Math.max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
+ bottomRight.y = Math.max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
+
+ if (pieMenu.x < topLeft.x && !isWithinLeftEdge()) {
+ // The width and height of the menu is always that of a full circle,
+ // so the menu is not always outside an edge when it's outside the edge -
+ // it depends on the start and end angles.
+ pieMenu.x = topLeft.x;
+ } else if (pieMenu.x + pieMenu.width > bottomRight.x && !isWithinRightEdge()) {
+ pieMenu.x = bottomRight.x - pieMenu.width;
+ }
+
+ if (pieMenu.y < topLeft.y && !isWithinTopEdge()) {
+ pieMenu.y = topLeft.y;
+ } else if (pieMenu.y + pieMenu.height > bottomRight.y && !isWithinBottomEdge()) {
+ pieMenu.y = bottomRight.y - pieMenu.height;
+ }
+ }
+ }
+}
diff --git a/src/extras/Private/CircularButton.qml b/src/extras/Private/CircularButton.qml
new file mode 100644
index 00000000..b2baf5a2
--- /dev/null
+++ b/src/extras/Private/CircularButton.qml
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Styles 1.3
+
+/*!
+ \internal
+*/
+Button {
+ id: button
+ style: Qt.createComponent(StyleSettings.style + "/CircularButtonStyle.qml", button)
+}
diff --git a/src/extras/Private/CircularButtonStyleHelper.qml b/src/extras/Private/CircularButtonStyleHelper.qml
new file mode 100644
index 00000000..fedd3a37
--- /dev/null
+++ b/src/extras/Private/CircularButtonStyleHelper.qml
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private 1.0
+
+QtObject {
+ id: circularButtonStyleHelper
+
+ property Item control
+
+ property color buttonColorUpTop: "#e3e3e3"
+ property color buttonColorUpBottom: "#b3b3b3"
+ property color buttonColorDownTop: "#d3d3d3"
+ property color buttonColorDownBottom: "#939393"
+ property color outerArcColorTop: "#9c9c9c"
+ property color outerArcColorBottom: Qt.rgba(0.941, 0.941, 0.941, 0.29)
+ property color innerArcColorTop: "#e3e3e3"
+ property color innerArcColorBottom: "#acacac"
+ property real innerArcColorBottomStop: 0.4
+ property color shineColor: Qt.rgba(1, 1, 1, 0.29)
+ property real smallestAxis: control ? Math.min(control.width, control.height) : 0
+ property real outerArcLineWidth: smallestAxis * 0.04
+ property real innerArcLineWidth: Math.max(1, outerArcLineWidth * 0.1)
+ property real shineArcLineWidth: Math.max(1, outerArcLineWidth * 0.1)
+ property real implicitWidth: Math.round(TextSingleton.implicitHeight * 8)
+ property real implicitHeight: Math.round(TextSingleton.implicitHeight * 8)
+
+ property color textColorUp: "#4e4e4e"
+ property color textColorDown: "#303030"
+ property color textRaisedColorUp: "#ffffff"
+ property color textRaisedColorDown: "#e3e3e3"
+
+ property real radius: (smallestAxis * 0.5) - outerArcLineWidth - innerArcLineWidth
+ property real halfRadius: radius / 2
+ property real outerArcRadius: innerArcRadius + outerArcLineWidth / 2
+ property real innerArcRadius: radius + innerArcLineWidth / 2
+ property real shineArcRadius: outerArcRadius + outerArcLineWidth / 2 - shineArcLineWidth / 2
+ property real zeroAngle: Math.PI * 0.5
+
+ property color buttonColorTop: control && control.pressed ? buttonColorDownTop : buttonColorUpTop
+ property color buttonColorBottom: control && control.pressed ? buttonColorDownBottom : buttonColorUpBottom
+
+ function toPixels(percentageOfSmallestAxis) {
+ return percentageOfSmallestAxis * smallestAxis;
+ }
+
+ function paintBackground(ctx) {
+ ctx.reset();
+
+ if (outerArcRadius < 0 || radius < 0)
+ return;
+
+ var xCenter = ctx.canvas.width / 2;
+ var yCenter = ctx.canvas.height / 2;
+
+ /* Draw outer arc */
+ ctx.beginPath();
+ ctx.lineWidth = outerArcLineWidth;
+ ctx.arc(xCenter, yCenter, outerArcRadius, 0, Math.PI * 2, false);
+ var gradient = ctx.createRadialGradient(xCenter, yCenter - halfRadius,
+ halfRadius, xCenter, yCenter - halfRadius, radius);
+ gradient.addColorStop(0, outerArcColorTop);
+ gradient.addColorStop(1, outerArcColorBottom);
+ ctx.strokeStyle = gradient;
+ ctx.stroke();
+
+ /* Draw the shine along the bottom */
+ ctx.beginPath();
+ ctx.lineWidth = shineArcLineWidth;
+ ctx.arc(xCenter, yCenter, shineArcRadius, 0, Math.PI, false);
+ gradient = ctx.createLinearGradient(xCenter, yCenter + radius, xCenter, yCenter);
+ gradient.addColorStop(0, shineColor);
+ gradient.addColorStop(0.5, "rgba(255, 255, 255, 0)");
+ ctx.strokeStyle = gradient;
+ ctx.stroke();
+
+ /* Draw inner arc */
+ ctx.beginPath();
+ ctx.lineWidth = innerArcLineWidth + 1;
+ ctx.arc(xCenter, yCenter, innerArcRadius, 0, Math.PI * 2, false);
+ gradient = ctx.createLinearGradient(xCenter, yCenter - halfRadius,
+ xCenter, yCenter + halfRadius);
+ gradient.addColorStop(0, innerArcColorTop);
+ gradient.addColorStop(innerArcColorBottomStop, innerArcColorBottom);
+ ctx.strokeStyle = gradient;
+ ctx.stroke();
+
+ /* Draw the button's body */
+ ctx.beginPath();
+ ctx.ellipse(xCenter - radius, yCenter - radius, radius * 2, radius * 2);
+ gradient = ctx.createRadialGradient(xCenter, yCenter + radius * 0.85, radius,
+ xCenter, yCenter + radius * 0.85, radius * 0.85);
+ gradient.addColorStop(1, buttonColorTop);
+ gradient.addColorStop(0, buttonColorBottom);
+ ctx.fillStyle = gradient;
+ ctx.fill();
+ }
+}
diff --git a/src/extras/Private/CircularTickmarkLabel.qml b/src/extras/Private/CircularTickmarkLabel.qml
new file mode 100644
index 00000000..05554878
--- /dev/null
+++ b/src/extras/Private/CircularTickmarkLabel.qml
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+// Workaround for QTBUG-37751; we need this import for RangeModel, although we shouldn't.
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private 1.0
+
+Control {
+ id: label
+ style: Qt.createComponent(StyleSettings.style + "/CircularTickmarkLabelStyle.qml", label)
+
+ property alias minimumValue: range.minimumValue
+
+ property alias maximumValue: range.maximumValue
+
+ property alias stepSize: range.stepSize
+
+ RangeModel {
+ id: range
+ minimumValue: 0
+ maximumValue: 100
+ stepSize: 0
+ // Not used.
+ value: minimumValue
+ }
+
+ /*!
+ This property determines the angle at which the first tickmark is drawn.
+ */
+ property real minimumValueAngle: -145
+
+ /*!
+ This property determines the angle at which the last tickmark is drawn.
+ */
+ property real maximumValueAngle: 145
+
+ /*!
+ The range between \l minimumValueAngle and \l maximumValueAngle, in
+ degrees.
+ */
+ readonly property real angleRange: maximumValueAngle - minimumValueAngle
+
+ /*!
+ The interval at which tickmarks are displayed.
+ */
+ property real tickmarkStepSize: 10
+
+ /*!
+ The distance in pixels from the outside of the control (outerRadius) at
+ which the outermost point of the tickmark line is drawn.
+ */
+ property real tickmarkInset: 0.0
+
+ /*!
+ The amount of tickmarks displayed.
+ */
+ readonly property int tickmarkCount: __tickmarkCount
+
+ /*!
+ The amount of minor tickmarks between each tickmark.
+ */
+ property int minorTickmarkCount: 4
+
+ /*!
+ The distance in pixels from the outside of the control (outerRadius) at
+ which the outermost point of the minor tickmark line is drawn.
+ */
+ property real minorTickmarkInset: 0.0
+
+ /*!
+ The distance in pixels from the outside of the control (outerRadius) at
+ which the center of the value marker text is drawn.
+ */
+ property real labelInset: __style.__protectedScope.toPixels(0.19)
+
+ /*!
+ The interval at which tickmark labels are displayed.
+ */
+ property real labelStepSize: tickmarkStepSize
+
+ /*!
+ The amount of tickmark labels displayed.
+ */
+ readonly property int labelCount: (maximumValue - minimumValue) / labelStepSize + 1
+
+ /*! \internal */
+ readonly property real __tickmarkCount: tickmarkStepSize > 0 ? (maximumValue - minimumValue) / tickmarkStepSize + 1 : 0
+
+ /*!
+ This property determines whether or not the control displays tickmarks,
+ minor tickmarks, and labels.
+ */
+ property bool tickmarksVisible: true
+
+ /*!
+ Returns \a value as an angle in degrees.
+
+ 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.
+ */
+ function valueToAngle(value) {
+ var normalised = (value - minimumValue) / (maximumValue - minimumValue);
+ return (maximumValueAngle - minimumValueAngle) * normalised + minimumValueAngle;
+ }
+}
diff --git a/src/extras/Private/Handle.qml b/src/extras/Private/Handle.qml
new file mode 100644
index 00000000..12e2804d
--- /dev/null
+++ b/src/extras/Private/Handle.qml
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtGraphicalEffects 1.0
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private 1.1
+import QtQuick.Extras.Private.CppUtils 1.0
+
+Control {
+ id: root
+ x: handleArea.centerOfHandle.x - width / 2
+ y: handleArea.centerOfHandle.y - height / 2
+
+ style: Qt.createComponent(StyleSettings.style + "/HandleStyle.qml", root)
+
+ /*!
+ The angle of the handle along the circumference of \l rotationRadius in
+ radians, scaled to be in the range of 0.0 to 1.0.
+ */
+ property alias value: range.value
+
+ RangeModel {
+ id: range
+ minimumValue: 0.0
+ maximumValue: 1.0
+ stepSize: 0
+ value: minimumValue
+ }
+
+ /*!
+ The angle in radians where the dial starts.
+ */
+ property real zeroAngle: 0
+
+ /*!
+ The radius of the rotation of this handle.
+ */
+ property real rotationRadius: 50
+
+ /*!
+ The center of the dial. This is the origin point for the handle's
+ rotation.
+ */
+ property real dialXCenter: 0
+ property real dialYCenter: 0
+
+ /*!
+ This property holds the amount of extra room added to each side of
+ the handle to make it easier to drag on touch devices.
+ */
+ property real allowance: Math.max(width, height) * 1.5
+
+ /*
+ The function used to determine the handle's value from the position of
+ the mouse.
+
+ Can be set to provide custom value calculation. It expects these
+ parameters: \c mouseX, \c mouseY, \c xCenter, \c yCenter, \c zeroAngle
+ */
+ property var valueFromMouse: handleArea.valueFromMouse
+
+ property alias handleArea: handleArea
+
+ MouseArea {
+ id: handleArea
+ // Respond to value changes by calculating the new center of the handle.
+ property point centerOfHandle: MathUtils.centerAlongCircle(dialXCenter, dialYCenter,
+ 0, 0, MathUtils.valueToAngle(value, 1, zeroAngle), rotationRadius);
+
+ anchors.fill: parent
+ anchors.margins: -allowance
+
+ onPositionChanged: {
+ // Whenever the handle is moved with the mouse, update the value.
+ value = root.valueFromMouse(mouse.x + centerOfHandle.x - allowance,
+ mouse.y + centerOfHandle.y - allowance, dialXCenter, dialYCenter, zeroAngle);
+ }
+
+ // A helper function for onPositionChanged.
+ function valueFromMouse(mouseX, mouseY, xCenter, yCenter, zeroAngle) {
+ return MathUtils.angleToValue(
+ MathUtils.halfPi - Math.atan2(mouseX - xCenter, mouseY - yCenter), 1, zeroAngle);
+ }
+ }
+}
diff --git a/src/extras/Private/PieMenuIcon.qml b/src/extras/Private/PieMenuIcon.qml
new file mode 100644
index 00000000..f54e035f
--- /dev/null
+++ b/src/extras/Private/PieMenuIcon.qml
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.3
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Private.CppUtils 1.0
+
+Loader {
+ id: iconLoader
+ active: iconSource != ""
+
+ property PieMenu control: null
+ property QtObject styleData: null
+
+ readonly property string iconSource: styleData && styleData.index < control.__protectedScope.visibleItems.length
+ ? control.__protectedScope.visibleItems[styleData.index].iconSource
+ : ""
+
+ sourceComponent: Image {
+ id: iconImage
+ source: iconSource
+ x: pos.x
+ y: pos.y
+ scale: scaleFactor
+
+ readonly property point pos: MathUtils.centerAlongCircle(
+ iconLoader.parent.width / 2, iconLoader.parent.height / 2, width, height,
+ MathUtils.degToRadOffset(sectionCenterAngle(styleData.index)), control.__style.__iconOffset)
+
+ /*
+ The icons should scale with the menu at some point, so that they
+ stay within the bounds of each section. We down-scale the image by
+ whichever of the following amounts are larger:
+
+ a) The amount by which the largest dimension's diagonal size exceeds
+ the "selectable" radius. The selectable radius is the distance in pixels
+ between lines A and B in the incredibly visually appealing image below:
+
+ __________
+ - B -
+ / \
+ / ____ \
+ | / A \ |
+ --------| |--------
+
+ b) The amount by which the diagonal exceeds the circumference of
+ one section.
+ */
+ readonly property real scaleFactor: {
+ var largestDimension = Math.max(iconImage.sourceSize.width, iconImage.sourceSize.height) * Math.sqrt(2);
+ // TODO: add padding
+ var radiusDifference = largestDimension - control.__style.__selectableRadius;
+ var circumferenceDifference = largestDimension - Math.abs(control.__protectedScope.circumferenceOfSection);
+ if (circumferenceDifference > 0 || radiusDifference > 0) {
+ // We need to down-scale.
+ if (radiusDifference > circumferenceDifference) {
+ return control.__style.__selectableRadius / largestDimension;
+ } else {
+ return Math.abs(control.__protectedScope.circumferenceOfSection) / largestDimension;
+ }
+ }
+ return 1;
+ }
+ }
+}
diff --git a/src/extras/Private/TextSingleton.qml b/src/extras/Private/TextSingleton.qml
new file mode 100644
index 00000000..6e51c66f
--- /dev/null
+++ b/src/extras/Private/TextSingleton.qml
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+pragma Singleton
+import QtQuick 2.1
+
+Text {
+}
diff --git a/src/extras/Private/private.pri b/src/extras/Private/private.pri
new file mode 100644
index 00000000..4f394412
--- /dev/null
+++ b/src/extras/Private/private.pri
@@ -0,0 +1,24 @@
+QT += gui quick
+
+HEADERS += \
+ $$PWD/qquickcircularprogressbar_p.h \
+ $$PWD/qquickflatprogressbar_p.h \
+ $$PWD/qquickmousethief_p.h \
+ $$PWD/qquickstylesettings_p.h \
+ $$PWD/qquickmathutils_p.h
+
+SOURCES += \
+ $$PWD/qquickcircularprogressbar.cpp \
+ $$PWD/qquickflatprogressbar.cpp \
+ $$PWD/qquickmousethief.cpp \
+ $$PWD/qquickstylesettings.cpp \
+ $$PWD/qquickmathutils.cpp
+
+OTHER_FILES += \
+ $$PWD/qmldir \
+ $$PWD/CircularButton.qml \
+ $$PWD/CircularButtonStyleHelper.qml \
+ $$PWD/CircularTickmarkLabel.qml \
+ $$PWD/Handle.qml \
+ $$PWD/PieMenuIcon.qml \
+ $$PWD/TextSingleton.qml
diff --git a/src/extras/Private/qmldir b/src/extras/Private/qmldir
new file mode 100644
index 00000000..3b115bba
--- /dev/null
+++ b/src/extras/Private/qmldir
@@ -0,0 +1 @@
+module QtQuick.Extras.Private
diff --git a/src/extras/Private/qquickcircularprogressbar.cpp b/src/extras/Private/qquickcircularprogressbar.cpp
new file mode 100644
index 00000000..5bdab7d3
--- /dev/null
+++ b/src/extras/Private/qquickcircularprogressbar.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickcircularprogressbar_p.h"
+
+#include <QtGui/QPen>
+#include <QtGui/QPainter>
+#include <QtMath>
+
+QQuickCircularProgressBar::QQuickCircularProgressBar(QQuickItem *parent) :
+ QQuickPaintedItem(parent),
+ mProgress(0),
+ mBarWidth(1),
+ mInset(0),
+ mBackgroundColor(QColor(Qt::transparent)),
+ mMinimumValueAngle(-90 * 16),
+ mMaximumValueAngle(-450 * 16)
+{
+ setFlag(ItemHasContents, true);
+}
+
+QQuickCircularProgressBar::~QQuickCircularProgressBar()
+{
+}
+
+void QQuickCircularProgressBar::paint(QPainter *painter)
+{
+ QPen pen(Qt::red);
+ pen.setWidthF(mBarWidth);
+
+ const QRectF bounds = boundingRect();
+ const qreal smallest = qMin(bounds.width(), bounds.height());
+ QRectF rect = QRectF(pen.widthF() / 2.0, pen.widthF() / 2.0, smallest - pen.widthF(), smallest - pen.widthF());
+ rect.adjust(mInset, mInset, -mInset, -mInset);
+
+ // Make sure the arc is aligned to whole pixels.
+ if (rect.x() - int(rect.x()) > 0) {
+ rect.setX(qCeil(rect.x()));
+ }
+ if (rect.y() - int(rect.y()) > 0) {
+ rect.setY(qCeil(rect.y()));
+ }
+ if (rect.width() - int(rect.width()) > 0) {
+ rect.setWidth(qFloor(rect.width()));
+ }
+ if (rect.height() - int(rect.height()) > 0) {
+ rect.setHeight(qFloor(rect.height()));
+ }
+
+ painter->setRenderHint(QPainter::Antialiasing);
+
+ // QPainter::drawArc uses positive values for counter clockwise - the opposite of our API -
+ // so we must reverse the angles with * -1. Also, our angle origin is at 12 o'clock, whereas
+ // QPainter's is 3 o'clock, hence - 90.
+ const qreal startAngle = ((mMinimumValueAngle - 90) * -1) * 16;
+ if (mBackgroundColor != Qt::transparent) {
+ QBrush bgBrush(mBackgroundColor);
+ QPen bgPen;
+ bgPen.setWidthF(mBarWidth);
+ bgPen.setBrush(bgBrush);
+ painter->setPen(bgPen);
+ painter->drawArc(rect, startAngle, (((mMaximumValueAngle - 90) * -1 * 16) - startAngle));
+ }
+
+ QLinearGradient gradient;
+ gradient.setStart(bounds.width() / 2, mInset);
+ gradient.setFinalStop(bounds.width() / 2, bounds.height() - mInset);
+ gradient.setStops(mGradientStops);
+
+ QBrush brush(gradient);
+ pen.setBrush(brush);
+
+ painter->setPen(pen);
+
+ const qreal spanAngle = progress() * (((mMaximumValueAngle - 90) * -1 * 16) - startAngle);
+ painter->drawArc(rect, startAngle, spanAngle);
+}
+
+qreal QQuickCircularProgressBar::progress() const
+{
+ return mProgress;
+}
+
+void QQuickCircularProgressBar::setProgress(qreal progress)
+{
+ if (mProgress != progress) {
+ mProgress = progress;
+ emit progressChanged(mProgress);
+ update();
+ }
+}
+
+qreal QQuickCircularProgressBar::barWidth() const
+{
+ return mBarWidth;
+}
+
+void QQuickCircularProgressBar::setBarWidth(qreal barWidth)
+{
+ if (mBarWidth != barWidth) {
+ mBarWidth = barWidth;
+ emit barWidthChanged(mBarWidth);
+ update();
+ }
+}
+
+qreal QQuickCircularProgressBar::inset() const
+{
+ return mInset;
+}
+
+void QQuickCircularProgressBar::setInset(qreal inset)
+{
+ if (mInset != inset) {
+ mInset = inset;
+ emit insetChanged(mInset);
+ update();
+ }
+}
+
+qreal QQuickCircularProgressBar::minimumValueAngle() const
+{
+ return mMinimumValueAngle;
+}
+
+void QQuickCircularProgressBar::setMinimumValueAngle(qreal minimumValueAngle)
+{
+ if (mMinimumValueAngle != minimumValueAngle) {
+ mMinimumValueAngle = minimumValueAngle;
+ emit minimumValueAngleChanged(mMinimumValueAngle);
+ update();
+ }
+}
+
+qreal QQuickCircularProgressBar::maximumValueAngle() const
+{
+ return mMinimumValueAngle;
+}
+
+void QQuickCircularProgressBar::setMaximumValueAngle(qreal maximumValueAngle)
+{
+ if (mMaximumValueAngle != maximumValueAngle) {
+ mMaximumValueAngle = maximumValueAngle;
+ emit maximumValueAngleChanged(mMaximumValueAngle);
+ update();
+ }
+}
+
+void QQuickCircularProgressBar::clearStops()
+{
+ mGradientStops.clear();
+}
+
+void QQuickCircularProgressBar::addStop(qreal position, const QColor &color)
+{
+ mGradientStops.append(QGradientStop(position, color));
+}
+
+void QQuickCircularProgressBar::redraw()
+{
+ update();
+}
+
+QColor QQuickCircularProgressBar::backgroundColor() const
+{
+ return mBackgroundColor;
+}
+
+void QQuickCircularProgressBar::setBackgroundColor(const QColor &backgroundColor)
+{
+ if (mBackgroundColor != backgroundColor) {
+ mBackgroundColor = backgroundColor;
+ emit backgroundColorChanged(backgroundColor);
+ update();
+ }
+}
diff --git a/src/extras/Private/qquickcircularprogressbar_p.h b/src/extras/Private/qquickcircularprogressbar_p.h
new file mode 100644
index 00000000..7e9be6ee
--- /dev/null
+++ b/src/extras/Private/qquickcircularprogressbar_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CIRCULARPROGRESSBAR_P_H
+#define CIRCULARPROGRESSBAR_P_H
+
+#include <QtGui/QColor>
+#include <QtGui/QGradientStops>
+#include <QtQuick/QQuickPaintedItem>
+
+class QQuickCircularProgressBar : public QQuickPaintedItem
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged)
+ Q_PROPERTY(qreal barWidth READ barWidth WRITE setBarWidth NOTIFY barWidthChanged)
+ Q_PROPERTY(qreal inset READ inset WRITE setInset NOTIFY insetChanged)
+ Q_PROPERTY(qreal minimumValueAngle READ minimumValueAngle WRITE setMinimumValueAngle NOTIFY minimumValueAngleChanged)
+ Q_PROPERTY(qreal maximumValueAngle READ maximumValueAngle WRITE setMaximumValueAngle NOTIFY maximumValueAngleChanged)
+ // For Flat DialStyle, so that we don't need to create two progress bars
+ Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged)
+
+public:
+ QQuickCircularProgressBar(QQuickItem *parent = 0);
+ ~QQuickCircularProgressBar();
+
+ void paint(QPainter *painter);
+
+ qreal progress() const;
+ void setProgress(qreal progress);
+
+ qreal barWidth() const;
+ void setBarWidth(qreal barWidth);
+
+ qreal inset() const;
+ void setInset(qreal inset);
+
+ qreal minimumValueAngle() const;
+ void setMinimumValueAngle(qreal minimumValueAngle);
+
+ qreal maximumValueAngle() const;
+ void setMaximumValueAngle(qreal maximumValueAngle);
+
+ Q_INVOKABLE void clearStops();
+ Q_INVOKABLE void addStop(qreal position, const QColor &color);
+ Q_INVOKABLE void redraw();
+
+ QColor backgroundColor() const;
+ void setBackgroundColor(const QColor &backgroundColor);
+signals:
+ void progressChanged(qreal progress);
+ void barWidthChanged(qreal barWidth);
+ void insetChanged(qreal inset);
+ void minimumValueAngleChanged(qreal minimumValueAngle);
+ void maximumValueAngleChanged(qreal maximumValueAngle);
+ void backgroundColorChanged(const QColor &backgroundColor);
+private:
+ qreal mProgress;
+ qreal mBarWidth;
+ qreal mInset;
+ QGradientStops mGradientStops;
+ QColor mBackgroundColor;
+ qreal mMinimumValueAngle;
+ qreal mMaximumValueAngle;
+};
+
+#endif // CIRCULARPROGRESSBAR_P_H
diff --git a/src/extras/Private/qquickflatprogressbar.cpp b/src/extras/Private/qquickflatprogressbar.cpp
new file mode 100644
index 00000000..f45a708a
--- /dev/null
+++ b/src/extras/Private/qquickflatprogressbar.cpp
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickflatprogressbar_p.h"
+
+#include <QtCore/QtMath>
+#include <QtGui/QPainter>
+
+QQuickFlatProgressBar::QQuickFlatProgressBar(QQuickItem *parent) :
+ QQuickPaintedItem(parent),
+ mStripeOffset(0),
+ mRadius(0),
+ mIndeterminate(false)
+{
+ mAnimation.setTargetObject(this);
+ mAnimation.setPropertyName("stripeOffset");
+ mAnimation.setEndValue(0);
+ mAnimation.setDuration(800);
+ mAnimation.setLoopCount(-1);
+
+ connect(this, SIGNAL(stripeOffsetChanged(qreal)), this, SLOT(repaint()));
+ connect(this, SIGNAL(progressChanged(qreal)), this, SLOT(repaint()));
+ connect(this, SIGNAL(enabledChanged()), this, SLOT(repaint()));
+ connect(this, SIGNAL(indeterminateChanged(bool)), this, SLOT(repaint()));
+ connect(this, SIGNAL(widthChanged()), this, SLOT(onWidthChanged()));
+ connect(this, SIGNAL(heightChanged()), this, SLOT(onHeightChanged()));
+ connect(this, SIGNAL(visibleChanged()), this, SLOT(onVisibleChanged()));
+}
+
+int QQuickFlatProgressBar::barWidth()
+{
+ // 14 is the design height of stripes on the bar, 10 is design width of stripe
+ return int(height() * 10 / 14);
+}
+
+void QQuickFlatProgressBar::paint(QPainter *painter)
+{
+ // This item should always be rounded to an integer size, so it is safe to use int here.
+ const int w = width();
+ const int h = height();
+
+ painter->setRenderHint(QPainter::Antialiasing, true);
+ painter->setPen(Qt::transparent);
+
+ // Draw the background.
+ painter->setBrush(isIndeterminate() && mProgress > 0 ? QColor(92, 170, 21) : QColor(0, 0, 0, 255 * 0.15));
+ painter->drawRoundedRect(0, 0, w, h, mRadius, mRadius);
+
+ // Draw progress, or indeterminate stripes.
+ painter->setClipPath(mClipPath);
+
+ if (!mIndeterminate) {
+ painter->setBrush(isEnabled() ? QColor(92, 170, 21) : QColor(179, 179, 179));
+ painter->drawRect(0, 0, int(w * mProgress), h);
+ } else {
+ QPainterPath innerClipPath;
+ // 1 is the design margin thickness.
+ const int margin = qMax(1, int(height() * (1.0 / 16.0)));
+ // We take the margin from the radius so that the inner and outer radii match each other visually.
+ innerClipPath.addRoundedRect(margin, margin, width() - margin * 2, height() - margin * 2, mRadius - margin, mRadius - margin);
+ painter->setClipPath(innerClipPath);
+
+ painter->translate(mStripeOffset, 0);
+
+ const qreal stripeWidth = barWidth();
+ // The horizontal distance created by the slant of the stripe.
+ const qreal stripeSlantDistance = h;
+
+ // One stripe width is equal to the height of the bar.
+ QPainterPath stripe;
+ stripe.moveTo(0, h);
+ stripe.lineTo(stripeSlantDistance, 0);
+ stripe.lineTo(stripeSlantDistance + stripeWidth, 0);
+ stripe.lineTo(stripeWidth, h);
+ stripe.closeSubpath();
+
+ painter->setBrush(QBrush(mProgress > 0 ? QColor(255, 255, 255, 77) : Qt::white));
+
+ for (int i = -stripeWidth * 2; i < w + stripeWidth * 2; i += stripeWidth * 2) {
+ painter->translate(i, 0);
+ painter->drawPath(stripe);
+ painter->translate(-i, 0);
+ }
+
+ painter->translate(-mStripeOffset, 0);
+ }
+}
+
+qreal QQuickFlatProgressBar::stripeOffset() const
+{
+ return mStripeOffset;
+}
+
+void QQuickFlatProgressBar::setStripeOffset(qreal pos)
+{
+ if (pos != mStripeOffset) {
+ mStripeOffset = pos;
+ emit stripeOffsetChanged(pos);
+ }
+}
+
+qreal QQuickFlatProgressBar::progress() const
+{
+ return mProgress;
+}
+
+void QQuickFlatProgressBar::setProgress(qreal progress)
+{
+ if (progress != mProgress) {
+ mProgress = progress;
+ emit progressChanged(mProgress);
+ }
+}
+
+bool QQuickFlatProgressBar::isIndeterminate()
+{
+ return mIndeterminate;
+}
+
+void QQuickFlatProgressBar::setIndeterminate(bool indeterminate)
+{
+ if (indeterminate != mIndeterminate) {
+ mIndeterminate = indeterminate;
+ emit indeterminateChanged(mIndeterminate);
+ }
+}
+
+void QQuickFlatProgressBar::repaint()
+{
+ QQuickPaintedItem::update(QRect(0, 0, width(), height()));
+}
+
+void QQuickFlatProgressBar::restartAnimation()
+{
+ mAnimation.stop();
+ mAnimation.setStartValue(-barWidth() * 2);
+ mAnimation.start();
+}
+
+void QQuickFlatProgressBar::onVisibleChanged()
+{
+ if (isVisible()) {
+ restartAnimation();
+ } else {
+ mAnimation.stop();
+ }
+}
+
+void QQuickFlatProgressBar::onWidthChanged()
+{
+ restartAnimation();
+
+ mClipPath = QPainterPath();
+ mClipPath.addRoundedRect(0, 0, width(), height(), mRadius, mRadius);
+}
+
+void QQuickFlatProgressBar::onHeightChanged()
+{
+ restartAnimation();
+
+ // 3 is the design radius, 16 is the design height of the bar
+ const qreal radius = height() * 3 / 16;
+ if (radius != mRadius) {
+ mRadius = radius;
+ }
+
+ mClipPath = QPainterPath();
+ mClipPath.addRoundedRect(0, 0, width(), height(), mRadius, mRadius);
+}
diff --git a/src/extras/Private/qquickflatprogressbar_p.h b/src/extras/Private/qquickflatprogressbar_p.h
new file mode 100644
index 00000000..1c3061e4
--- /dev/null
+++ b/src/extras/Private/qquickflatprogressbar_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FLATPROGRESSBAR_H
+#define FLATPROGRESSBAR_H
+
+#include <QtCore/QPropertyAnimation>
+#include <QtGui/QPainterPath>
+#include <QtQuick/QQuickPaintedItem>
+
+class QQuickFlatProgressBar : public QQuickPaintedItem
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal stripeOffset READ stripeOffset WRITE setStripeOffset NOTIFY stripeOffsetChanged)
+ Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged)
+ Q_PROPERTY(bool indeterminate READ isIndeterminate WRITE setIndeterminate NOTIFY indeterminateChanged)
+public:
+ explicit QQuickFlatProgressBar(QQuickItem *parent = 0);
+
+ void paint(QPainter *painter);
+
+ qreal stripeOffset() const;
+ void setStripeOffset(qreal stripeOffset);
+
+ qreal progress() const;
+ void setProgress(qreal progress);
+
+ bool isIndeterminate();
+ void setIndeterminate(bool indeterminate);
+
+public slots:
+ void repaint();
+ void restartAnimation();
+ void onVisibleChanged();
+ void onWidthChanged();
+ void onHeightChanged();
+
+signals:
+ void stripeOffsetChanged(qreal stripeOffset);
+ void progressChanged(qreal progress);
+ void indeterminateChanged(bool indeterminate);
+
+private:
+ int barWidth();
+
+private:
+ qreal mStripeOffset;
+ qreal mProgress;
+ qreal mRadius;
+ bool mIndeterminate;
+ QPainterPath mClipPath;
+ QPropertyAnimation mAnimation;
+};
+
+#endif // FLATPROGRESSBAR_H
diff --git a/src/extras/Private/qquickmathutils.cpp b/src/extras/Private/qquickmathutils.cpp
new file mode 100644
index 00000000..8f4b2a6b
--- /dev/null
+++ b/src/extras/Private/qquickmathutils.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickmathutils_p.h"
+
+#include <qmath.h>
+
+QQuickMathUtils::QQuickMathUtils(QObject *parent) :
+ QObject(parent)
+{
+}
+
+qreal QQuickMathUtils::pi2() const
+{
+ return M_PI * 2;
+}
+
+/*!
+ Converts the angle \a degrees to radians.
+*/
+qreal QQuickMathUtils::degToRad(qreal degrees) const {
+ return degrees * (M_PI / 180);
+}
+
+/*!
+ Converts the angle \a degrees to radians.
+
+ This function assumes that the angle origin (0) is north, as this
+ is the origin used by all of the Extras. The angle
+ returned will have its angle origin (0) pointing east, in order to be
+ consistent with standard angles used by \l {QtQuick::Canvas}{Canvas},
+ for example.
+*/
+qreal QQuickMathUtils::degToRadOffset(qreal degrees) const {
+ return (degrees - 90) * (M_PI / 180);
+}
+
+/*!
+ Converts the angle \a radians to degrees.
+*/
+qreal QQuickMathUtils::radToDeg(qreal radians) const {
+ return radians * (180 / M_PI);
+}
+
+/*!
+ Converts the angle \a radians to degrees.
+
+ This function assumes that the angle origin (0) is east; as is standard for
+ mathematical operations using radians (this origin is used by
+ \l {QtQuick::Canvas}{Canvas}, for example). The angle returned in degrees
+ will have its angle origin (0) pointing north, which is what the extras
+ expect.
+*/
+qreal QQuickMathUtils::radToDegOffset(qreal radians) const {
+ return radians * (180 / M_PI) + 90;
+}
+
+/*!
+ Returns the top left position of the item if it were centered along
+ a circle according to \a angleOnCircle and \a distanceAlongRadius.
+
+ \a angleOnCircle is from 0.0 - M_PI2.
+ \a distanceAlongRadius is the distance along the radius in M_PIxels.
+*/
+QPointF QQuickMathUtils::centerAlongCircle(qreal xCenter, qreal yCenter,
+ qreal width, qreal height, qreal angleOnCircle, qreal distanceAlongRadius) const {
+ return QPointF(
+ (xCenter - width / 2) + (distanceAlongRadius * cos(angleOnCircle)),
+ (yCenter - height / 2) + (distanceAlongRadius * sin(angleOnCircle)));
+}
+
+/*!
+ Returns \a number rounded to the nearest even integer.
+*/
+qreal QQuickMathUtils::roundEven(qreal number) const {
+ int rounded = qRound(number);
+ return rounded % 2 == 0 ? rounded : rounded + 1;
+}
diff --git a/src/extras/Private/qquickmathutils_p.h b/src/extras/Private/qquickmathutils_p.h
new file mode 100644
index 00000000..35e15a84
--- /dev/null
+++ b/src/extras/Private/qquickmathutils_p.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKMATHUTILS_P
+#define QQUICKMATHUTILS_P
+
+#include <QObject>
+#include <QPointF>
+
+class QQuickMathUtils : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal pi2 READ pi2 CONSTANT)
+public:
+ QQuickMathUtils(QObject *parent = 0);
+
+ qreal pi2() const;
+ Q_INVOKABLE qreal degToRad(qreal degrees) const;
+ Q_INVOKABLE qreal degToRadOffset(qreal degrees) const;
+ Q_INVOKABLE qreal radToDeg(qreal radians) const;
+ Q_INVOKABLE qreal radToDegOffset(qreal radians) const;
+ Q_INVOKABLE QPointF centerAlongCircle(qreal xCenter, qreal yCenter,
+ qreal width, qreal height, qreal angleOnCircle, qreal distanceAlongRadius) const;
+ Q_INVOKABLE qreal roundEven(qreal number) const;
+};
+
+#endif // QQUICKMATHUTILS_P
+
diff --git a/src/extras/Private/qquickmousethief.cpp b/src/extras/Private/qquickmousethief.cpp
new file mode 100644
index 00000000..5fe82672
--- /dev/null
+++ b/src/extras/Private/qquickmousethief.cpp
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickmousethief_p.h"
+
+#include <QtCore/QMetaObject>
+#include <QtQuick/QQuickWindow>
+
+QQuickMouseThief::QQuickMouseThief(QObject *parent) :
+ QObject(parent),
+ mItem(0),
+ mReceivedPressEvent(false),
+ mAcceptCurrentEvent(false)
+{
+}
+
+bool QQuickMouseThief::receivedPressEvent() const
+{
+ return mReceivedPressEvent;
+}
+
+void QQuickMouseThief::setReceivedPressEvent(bool receivedPressEvent)
+{
+ if (receivedPressEvent != mReceivedPressEvent) {
+ mReceivedPressEvent = receivedPressEvent;
+ emit receivedPressEventChanged();
+ }
+}
+
+void QQuickMouseThief::grabMouse(QQuickItem *item)
+{
+ if (item) {
+ mItem = item;
+
+ // Handle the case where someone makes the PieMenu an orphan. E.g.:
+ // property PieMenu pieMenu: PieMenu {}
+ // They have to set the parent explicitly if they want that to work.
+ // This can also be null if the menu is visible when constructed.
+ if (mItem->window()) {
+ // We install an event filter so that we can track release events.
+ // This is because the MouseArea that we steal the mouse from stores the
+ // pressed flag (before item is visible) and we don't, so we don't know
+ // that it's a release.
+ mItem->grabMouse();
+ mItem->window()->installEventFilter(this);
+ } else {
+ // The menu was visible when constructed (visible: true), so install the
+ // event filter later on.
+ connect(mItem, SIGNAL(windowChanged(QQuickWindow*)),
+ this, SLOT(itemWindowChanged(QQuickWindow*)));
+ }
+ }
+}
+
+void QQuickMouseThief::ungrabMouse()
+{
+ if (mItem) {
+ // This can be null if someone does the following:
+ // PieMenu { Component.onCompleted: { visible = true; visible = false; }
+ if (mItem->window()) {
+ if (mItem->window()->mouseGrabberItem() == mItem) {
+ mItem->ungrabMouse();
+ }
+ mItem->window()->removeEventFilter(this);
+ }
+ mItem = 0;
+ }
+}
+
+void QQuickMouseThief::acceptCurrentEvent()
+{
+ mAcceptCurrentEvent = true;
+}
+
+void QQuickMouseThief::itemWindowChanged(QQuickWindow *window)
+{
+ // The window will be null when the application is closing.
+ if (window) {
+ // This can be null if someone does the following:
+ // PieMenu { Component.onCompleted: { visible = true; visible = false; }
+ if (mItem) {
+ mItem->grabMouse();
+ window->installEventFilter(this);
+ }
+ }
+}
+
+bool QQuickMouseThief::eventFilter(QObject *, QEvent *event)
+{
+ if (!mItem)
+ return false;
+
+ // The PieMenu QML code dictates which events are accepted by
+ // setting this property when it responds to our signals.
+ mAcceptCurrentEvent = false;
+
+ if (event->type() == QEvent::MouseButtonRelease) {
+ const QPointF mouseWindowPos = static_cast<QMouseEvent *>(event)->windowPos();
+ emitReleased(mouseWindowPos);
+ // Even if the release should close the menu, we should emit
+ // clicked to be consistent since we have to do it ourselves.
+ bool releaseAccepted = mAcceptCurrentEvent;
+ mAcceptCurrentEvent = false;
+
+ emitClicked(mouseWindowPos);
+ if (!mAcceptCurrentEvent) {
+ // We might not have accepted click, but we may have accepted release.
+ mAcceptCurrentEvent = releaseAccepted;
+ }
+ } else if (event->type() == QEvent::MouseButtonPress) {
+ emitPressed(static_cast<QMouseEvent *>(event)->windowPos());
+ } else if (event->type() == QEvent::TouchEnd) {
+ // The finger(s) were lifted off the screen. We don't get this as a release event since
+ // we're doing our own custom handling, so we handle it here.
+ QTouchEvent *touchEvent = static_cast<QTouchEvent*>(event);
+ const QList<QTouchEvent::TouchPoint> points = touchEvent->touchPoints();
+ // We only care about one finger. If there's more than one, ignore them.
+ if (!points.isEmpty()) {
+ const QPointF pos = points.first().pos();
+ emitReleased(pos);
+ // Even if the release should close the menu, we should emit
+ // clicked to be consistent since we have to do it ourselves.
+ bool releaseAccepted = mAcceptCurrentEvent;
+ mAcceptCurrentEvent = false;
+
+ emitClicked(pos);
+ if (!mAcceptCurrentEvent) {
+ // We might not have accepted click, but we may have accepted release.
+ mAcceptCurrentEvent = releaseAccepted;
+ }
+ }
+ } else if (event->type() == QEvent::TouchBegin) {
+ QTouchEvent *touchEvent = static_cast<QTouchEvent*>(event);
+ const QList<QTouchEvent::TouchPoint> points = touchEvent->touchPoints();
+ if (!points.isEmpty()) {
+ emitPressed(points.first().pos());
+ }
+ } else if (event->type() == QEvent::TouchUpdate) {
+ QTouchEvent *touchEvent = static_cast<QTouchEvent*>(event);
+ const QList<QTouchEvent::TouchPoint> points = touchEvent->touchPoints();
+ if (!points.isEmpty()) {
+ const QPointF mappedPos = mItem->mapFromScene(points.first().pos());
+ emit touchUpdate(mappedPos.x(), mappedPos.y());
+ }
+ }
+ return mAcceptCurrentEvent;
+}
+
+void QQuickMouseThief::emitPressed(const QPointF &pos)
+{
+ setReceivedPressEvent(true);
+
+ // PieMenu can't detect presses outside its own MouseArea,
+ // so we need to provide these as well.
+ QPointF mappedPos = mItem->mapFromScene(pos);
+ emit pressed(mappedPos.x(), mappedPos.y());
+}
+
+void QQuickMouseThief::emitReleased(const QPointF &pos)
+{
+ QPointF mappedPos = mItem->mapFromScene(pos);
+ emit released(mappedPos.x(), mappedPos.y());
+}
+
+void QQuickMouseThief::emitClicked(const QPointF &pos)
+{
+ // mItem can be destroyed if the slots connected to released() caused it to be hidden.
+ // That's fine for us, since PieMenu doesn't need to handle anything if released()
+ // is emitted when the triggerMode is PieMenu.TriggerOnRelease.
+ if (mItem) {
+ QPointF mappedPos = mItem->mapFromScene(pos);
+ // Since we are creating the release events, we must also handle clicks.
+ emit clicked(mappedPos.x(), mappedPos.y());
+ }
+}
diff --git a/src/extras/Private/qquickmousethief_p.h b/src/extras/Private/qquickmousethief_p.h
new file mode 100644
index 00000000..3b1a5a4d
--- /dev/null
+++ b/src/extras/Private/qquickmousethief_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MOUSETHIEF_H
+#define MOUSETHIEF_H
+
+#include <QObject>
+#include <QtQuick/QQuickItem>
+
+class QQuickMouseThief : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool receivedPressEvent READ receivedPressEvent
+ WRITE setReceivedPressEvent NOTIFY receivedPressEventChanged)
+public:
+ explicit QQuickMouseThief(QObject *parent = 0);
+
+ bool receivedPressEvent() const;
+ void setReceivedPressEvent(bool receivedPressEvent);
+
+ Q_INVOKABLE void grabMouse(QQuickItem *item);
+ Q_INVOKABLE void ungrabMouse();
+ Q_INVOKABLE void acceptCurrentEvent();
+signals:
+ /*!
+ Coordinates are relative to the window of mItem.
+ */
+ void pressed(int mouseX, int mouseY);
+
+ void released(int mouseX, int mouseY);
+
+ void clicked(int mouseX, int mouseY);
+
+ void touchUpdate(int mouseX, int mouseY);
+
+ void receivedPressEventChanged();
+
+ void handledEventChanged();
+protected:
+ bool eventFilter(QObject *obj, QEvent *event);
+private slots:
+ void itemWindowChanged(QQuickWindow *window);
+private:
+ void emitPressed(const QPointF &pos);
+ void emitReleased(const QPointF &pos);
+ void emitClicked(const QPointF &pos);
+
+ QQuickItem *mItem;
+ bool mReceivedPressEvent;
+ bool mAcceptCurrentEvent;
+};
+
+#endif // MOUSETHIEF_H
diff --git a/src/extras/Private/qquickstylesettings.cpp b/src/extras/Private/qquickstylesettings.cpp
new file mode 100644
index 00000000..0936e55e
--- /dev/null
+++ b/src/extras/Private/qquickstylesettings.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstylesettings_p.h"
+#include <qqmlengine.h>
+#include <qfileinfo.h>
+#include <qdebug.h>
+#include <qdir.h>
+
+QT_BEGIN_NAMESPACE
+
+static QString defaultStyleName()
+{
+ return QLatin1String("Base");
+}
+
+static QString styleImportName()
+{
+ QString name = qgetenv("QT_QUICK_CONTROLS_STYLE");
+ if (name.isEmpty())
+ name = defaultStyleName();
+ return QFileInfo(name).fileName();
+}
+
+static bool isResource(const QString &path)
+{
+ return path.startsWith(":/");
+}
+
+static QString styleImportPath(QQmlEngine *engine, const QString &styleName)
+{
+ static const char * const stylePaths[] = { "/QtQuick/Extras/Styles", "/QtQuick/Controls/Styles" };
+ QString path = qgetenv("QT_QUICK_CONTROLS_STYLE");
+ QFileInfo info(path);
+ if (isResource(path)) {
+ path = info.path();
+ } else if (info.isRelative()) {
+ bool found = false;
+ QStringList importPaths = engine->importPathList();
+ importPaths.prepend(QStringLiteral(":/ExtrasImports/"));
+
+ foreach (const QString &import, importPaths) {
+ for (unsigned i = 0; i < sizeof(stylePaths) / sizeof(stylePaths[0]); i++) {
+ QDir dir(import + QLatin1String(stylePaths[i]));
+ if (dir.exists(styleName)) {
+ found = true;
+ path = dir.absolutePath();
+ break;
+ }
+ }
+ if (found)
+ break;
+ }
+ if (!found)
+ path = QLatin1String(":/ExtrasImports/QtQuick/Extras/Styles");
+ } else {
+ path = info.absolutePath();
+ }
+ return path;
+}
+
+QQuickStyleSettings::QQuickStyleSettings(QQmlEngine *engine)
+{
+ m_name = styleImportName();
+ m_path = styleImportPath(engine, m_name);
+
+ QString path = styleFilePath();
+
+ if (!QDir(path).exists()) {
+ QString unknownStyle = m_name;
+ m_name = defaultStyleName();
+ m_path = styleImportPath(engine, m_name);
+ qWarning() << "WARNING: Cannot find style" << unknownStyle << "- fallback:" << styleFilePath();
+ }
+
+ connect(this, SIGNAL(styleNameChanged()), SIGNAL(styleChanged()));
+ connect(this, SIGNAL(stylePathChanged()), SIGNAL(styleChanged()));
+}
+
+QUrl QQuickStyleSettings::style() const
+{
+ QUrl result;
+ QString path = styleFilePath();
+ if (isResource(path)) {
+ result.setScheme("qrc");
+ path.remove(0, 1); // remove ':' prefix
+ result.setPath(path);
+ } else
+ result = QUrl::fromLocalFile(path);
+ return result;
+}
+
+QString QQuickStyleSettings::styleName() const
+{
+ return m_name;
+}
+
+void QQuickStyleSettings::setStyleName(const QString &name)
+{
+ if (m_name != name) {
+ m_name = name;
+ emit styleNameChanged();
+ }
+}
+
+QString QQuickStyleSettings::stylePath() const
+{
+ return m_path;
+}
+
+void QQuickStyleSettings::setStylePath(const QString &path)
+{
+ if (m_path != path) {
+ m_path = path;
+ emit stylePathChanged();
+ }
+}
+
+QString QQuickStyleSettings::styleFilePath() const
+{
+ return m_path + QLatin1Char('/') + m_name;
+}
+
+QT_END_NAMESPACE
diff --git a/src/extras/Private/qquickstylesettings_p.h b/src/extras/Private/qquickstylesettings_p.h
new file mode 100644
index 00000000..3cb157a8
--- /dev/null
+++ b/src/extras/Private/qquickstylesettings_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef STYLESETTINGS_P_H
+#define STYLESETTINGS_P_H
+
+#include <QtCore/qurl.h>
+#include <QtCore/qobject.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlEngine;
+
+class QQuickStyleSettings : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QUrl style READ style NOTIFY styleChanged)
+ Q_PROPERTY(QString styleName READ styleName WRITE setStyleName NOTIFY styleNameChanged)
+ Q_PROPERTY(QString stylePath READ stylePath WRITE setStylePath NOTIFY stylePathChanged)
+
+public:
+ QQuickStyleSettings(QQmlEngine *engine);
+
+ QUrl style() const;
+
+ QString styleName() const;
+ void setStyleName(const QString &name);
+
+ QString stylePath() const;
+ void setStylePath(const QString &path);
+
+signals:
+ void styleChanged();
+ void styleNameChanged();
+ void stylePathChanged();
+
+private:
+ QString styleFilePath() const;
+
+ QString m_name;
+ QString m_path;
+};
+
+QT_END_NAMESPACE
+
+#endif // STYLESETTINGS_P_H
diff --git a/src/extras/StatusIndicator.qml b/src/extras/StatusIndicator.qml
new file mode 100644
index 00000000..8be50737
--- /dev/null
+++ b/src/extras/StatusIndicator.qml
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private 1.0
+
+/*!
+ \qmltype StatusIndicator
+ \inqmlmodule QtQuick.Extras
+ \since QtQuick.Extras 1.1
+ \ingroup extras
+ \ingroup extras-non-interactive
+ \brief An indicator that displays active or inactive states.
+
+ \image statusindicator-active.png A StatusIndicator in the active state
+ A StatusIndicator in the active state.
+ \image statusindicator-inactive.png A StatusIndicator in the inactive state
+ A StatusIndicator in the inactive state.
+
+ The StatusIndicator displays active or inactive states. By using different
+ colors via the \l color property, StatusIndicator can provide extra
+ context to these states. For example:
+
+ \table
+ \row
+ \li QML
+ \li Result
+ \row
+ \li
+ \code
+ import QtQuick 2.2
+ import QtQuick.Extras 1.3
+
+ Rectangle {
+ width: 100
+ height: 100
+ color: "#cccccc"
+
+ StatusIndicator {
+ anchors.centerIn: parent
+ color: "green"
+ }
+ }
+ \endcode
+ \li \image statusindicator-green.png "Green StatusIndicator"
+ \endtable
+
+ You can create a custom appearance for a StatusIndicator by assigning a
+ \l {QtQuick.Extras.Styles::}{StatusIndicatorStyle}.
+*/
+
+Control {
+ id: statusIndicator
+
+ style: Qt.createComponent(StyleSettings.style + "/StatusIndicatorStyle.qml", statusIndicator)
+
+ /*!
+ This property specifies whether the indicator is active or inactive.
+
+ The default value is \c false (off).
+
+ \deprecated Use active instead.
+ */
+ property alias on: statusIndicator.active
+
+ /*!
+ \since QtQuick.Extras 1.2
+
+ This property specifies whether the indicator is active or inactive.
+
+ The default value is \c false (inactive).
+ */
+ property bool active: false
+
+ /*!
+ This property specifies the color of the indicator when it is active.
+
+ The default value is \c "red".
+ */
+ property color color: __style.color
+}
diff --git a/src/extras/Styles/Base/Base.pro b/src/extras/Styles/Base/Base.pro
new file mode 100644
index 00000000..fcb6ad95
--- /dev/null
+++ b/src/extras/Styles/Base/Base.pro
@@ -0,0 +1,34 @@
+TARGET = qtquickextrasstylesplugin
+TARGETPATH = QtQuick/Extras/Styles
+
+QT += qml
+
+HEADERS += \
+ basestyleplugin.h
+SOURCES += \
+ basestyleplugin.cpp
+
+BASE_STYLE = \
+ $$PWD/CircularGaugeStyle.qml \
+ $$PWD/CircularButtonStyle.qml \
+ $$PWD/CircularTickmarkLabelStyle.qml \
+ $$PWD/CommonStyleHelper.qml \
+ $$PWD/DelayButtonStyle.qml \
+ $$PWD/DialStyle.qml \
+ $$PWD/GaugeStyle.qml \
+ $$PWD/HandleStyle.qml \
+ $$PWD/HandleStyleHelper.qml \
+ $$PWD/PieMenuStyle.qml \
+ $$PWD/StatusIndicatorStyle.qml \
+ $$PWD/ToggleButtonStyle.qml \
+ $$PWD/TumblerStyle.qml
+
+BASE_STYLE += \
+ $$PWD/images/knob.png \
+ $$PWD/images/needle.png
+
+RESOURCES += \
+ basestyle.qrc
+
+CONFIG += no_cxx_module
+load(qml_plugin)
diff --git a/src/extras/Styles/Base/CircularButtonStyle.qml b/src/extras/Styles/Base/CircularButtonStyle.qml
new file mode 100644
index 00000000..9e29a534
--- /dev/null
+++ b/src/extras/Styles/Base/CircularButtonStyle.qml
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls.Styles 1.1
+import QtQuick.Extras.Styles 1.3
+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
+ onPressedChanged: backgroundCanvas.requestPaint()
+ }
+
+ onPaint: {
+ var ctx = getContext("2d");
+ __buttonHelper.paintBackground(ctx);
+ }
+ }
+ }
+}
diff --git a/src/extras/Styles/Base/CircularGaugeStyle.qml b/src/extras/Styles/Base/CircularGaugeStyle.qml
new file mode 100644
index 00000000..2030f775
--- /dev/null
+++ b/src/extras/Styles/Base/CircularGaugeStyle.qml
@@ -0,0 +1,498 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtGraphicalEffects 1.0
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private 1.0
+
+/*!
+ \qmltype CircularGaugeStyle
+ \inqmlmodule QtQuick.Extras.Styles
+ \since QtQuick.Extras.Styles 1.0
+ \ingroup extrasstyles
+ \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
+
+ /*!
+ \since 1.3
+
+ 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
+
+ /*!
+ \since QtQuick.Extras 1.2
+
+ 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
+ }
+ }
+}
diff --git a/src/extras/Styles/Base/CircularTickmarkLabelStyle.qml b/src/extras/Styles/Base/CircularTickmarkLabelStyle.qml
new file mode 100644
index 00000000..010e9245
--- /dev/null
+++ b/src/extras/Styles/Base/CircularTickmarkLabelStyle.qml
@@ -0,0 +1,304 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.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
+ onMinimumValueChanged: valueTextModel.update()
+ onMaximumValueChanged: valueTextModel.update()
+ onTickmarkStepSizeChanged: valueTextModel.update()
+ 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
+ sourceComponent: tickmarkLabel
+ x: pos.x
+ y: pos.y
+
+ readonly property point pos: panelItem.labelPosFromIndex(index, width, height);
+
+ readonly property int __index: index
+ property QtObject styleData: QtObject {
+ readonly property var value: index != -1 ? labelItemRepeater.model.get(index).value : 0
+ readonly property alias index: tickmarkLabelDelegateLoader.__index
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/extras/Styles/Base/CommonStyleHelper.qml b/src/extras/Styles/Base/CommonStyleHelper.qml
new file mode 100644
index 00000000..4263a743
--- /dev/null
+++ b/src/extras/Styles/Base/CommonStyleHelper.qml
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.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"
+}
diff --git a/src/extras/Styles/Base/DelayButtonStyle.qml b/src/extras/Styles/Base/DelayButtonStyle.qml
new file mode 100644
index 00000000..e416550b
--- /dev/null
+++ b/src/extras/Styles/Base/DelayButtonStyle.qml
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtGraphicalEffects 1.0
+import QtQuick.Controls.Styles 1.1
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private.CppUtils 1.1
+
+/*!
+ \qmltype DelayButtonStyle
+ \inqmlmodule QtQuick.Extras.Styles
+ \since QtQuick.Extras.Styles 1.0
+ \ingroup extrasstyles
+ \brief Provides custom styling for DelayButton.
+
+ You can create a custom DelayButton by replacing the following delegates:
+ \list
+ \li \l foreground
+ \li \l {QtQuick.Controls.Styles::ButtonStyle::label}{label}
+ \endlist
+*/
+
+CircularButtonStyle {
+ id: delayButtonStyle
+
+ /*!
+ \since 1.3
+
+ 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
+ onPressedChanged: backgroundCanvas.requestPaint()
+ 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
+ onActivated: state = "activated"
+ 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
+ onProgressBarGradientChanged: progressBar.updateGradient()
+ }
+ }
+
+ DropShadow {
+ id: progressBarDropShadow
+ anchors.fill: progressBar
+ fast: true
+ // QTBUG-33747
+// cached: !control.pressed
+ radius: 4
+ samples: radius * 2
+ 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
+ }
+ }
+}
diff --git a/src/extras/Styles/Base/DialStyle.qml b/src/extras/Styles/Base/DialStyle.qml
new file mode 100644
index 00000000..3523f500
--- /dev/null
+++ b/src/extras/Styles/Base/DialStyle.qml
@@ -0,0 +1,392 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Private.CppUtils 1.0
+
+/*!
+ \qmltype DialStyle
+ \inqmlmodule QtQuick.Extras.Styles
+ \since QtQuick.Extras.Styles 1.0
+ \ingroup extrasstyles
+ \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
+
+ /*!
+ \since 1.3
+
+ The \l Dial that this style is attached to.
+ */
+ readonly property Dial control: __control
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ 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
+
+ /*!
+ \since 1.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)
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ 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
+
+ /*!
+ \since QtQuick.Extras 1.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
+
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ 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
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ The amount of minor tickmarks between each tickmark.
+
+ \sa tickmarkCount
+ */
+ property int minorTickmarkCount: 0
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ 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
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ 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
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ 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
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ 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
+
+ /*!
+ \since QtQuick.Extras 1.2
+
+ 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.
+
+ 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.
+ */
+ 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);
+ }
+ }
+ }
+
+ /*!
+ \since 1.2
+
+ 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);
+ }
+ }
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ 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)
+ }
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ 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
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ 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
+ }
+ }
+ }
+}
diff --git a/src/extras/Styles/Base/GaugeStyle.qml b/src/extras/Styles/Base/GaugeStyle.qml
new file mode 100644
index 00000000..49ea6f29
--- /dev/null
+++ b/src/extras/Styles/Base/GaugeStyle.qml
@@ -0,0 +1,545 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Styles 1.1
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private 1.0
+
+/*!
+ \qmltype GaugeStyle
+ \inqmlmodule QtQuick.Extras.Styles
+ \since QtQuick.Extras.Styles 1.0
+ \ingroup extrasstyles
+ \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.1
+ import QtQuick.Extras 1.3
+ import QtQuick.Extras.Styles 1.3
+
+ 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
+
+ /*!
+ \since 1.3
+
+ The \l Gauge that this style is attached to.
+ */
+ readonly property Gauge control: __control
+
+ /*!
+ \since QtQuick.Extras.Styles 1.3
+
+ 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
+ }
+ }
+ }
+}
diff --git a/src/extras/Styles/Base/HandleStyle.qml b/src/extras/Styles/Base/HandleStyle.qml
new file mode 100644
index 00000000..38588417
--- /dev/null
+++ b/src/extras/Styles/Base/HandleStyle.qml
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+
+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
+ }
+ }
+}
diff --git a/src/extras/Styles/Base/HandleStyleHelper.qml b/src/extras/Styles/Base/HandleStyleHelper.qml
new file mode 100644
index 00000000..61ad3bb3
--- /dev/null
+++ b/src/extras/Styles/Base/HandleStyleHelper.qml
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.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, handleWidth / 2,
+ handleX, handleY, handleWidth);
+ 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();
+ }
+}
diff --git a/src/extras/Styles/Base/PieMenuStyle.qml b/src/extras/Styles/Base/PieMenuStyle.qml
new file mode 100644
index 00000000..c7cd1dda
--- /dev/null
+++ b/src/extras/Styles/Base/PieMenuStyle.qml
@@ -0,0 +1,393 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtGraphicalEffects 1.0
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Private.CppUtils 1.0
+
+/*!
+ \qmltype PieMenuStyle
+ \inqmlmodule QtQuick.Extras.Styles
+ \since QtQuick.Extras.Styles 1.0
+ \ingroup extrasstyles
+ \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
+
+ /*!
+ \since 1.3
+
+ 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. */
+ property color shadowColor: Qt.rgba(0, 0, 0, 0.26)
+
+ /*! The shadow radius. */
+ property real shadowRadius: 50
+
+ /*! The shadow spread. */
+ 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
+
+ /*!
+ Returns the start of the section at \a itemIndex as an angle in degrees.
+ */
+ function sectionStartAngle(itemIndex) {
+ return MathUtils.radToDegOffset(control.__protectedScope.sectionStartAngle(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));
+ }
+
+ /*!
+ 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
+
+ /*!
+ \since QtQuick.Extras 1.1
+
+ 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.
+ (since QtQuick.Extras 1.3)
+ \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
+ onStartAngleChanged: actionCanvas.requestPaint()
+ onEndAngleChanged: actionCanvas.requestPaint()
+ }
+
+ Connections {
+ target: control
+ 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
+ fast: true
+ radius: shadowRadius
+ spread: shadowSpread
+ transparentBorder: true
+ samples: 12
+ 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
+ }
+ }
+ }
+}
diff --git a/src/extras/Styles/Base/StatusIndicatorStyle.qml b/src/extras/Styles/Base/StatusIndicatorStyle.qml
new file mode 100644
index 00000000..ddfd1b45
--- /dev/null
+++ b/src/extras/Styles/Base/StatusIndicatorStyle.qml
@@ -0,0 +1,237 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtGraphicalEffects 1.0
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+
+/*!
+ \qmltype StatusIndicatorStyle
+ \inqmlmodule QtQuick.Extras.Styles
+ \since QtQuick.Extras.Styles 1.1
+ \ingroup extrasstyles
+ \brief Provides custom styling for StatusIndicatorStyle.
+
+ You can create a custom status indicator by defining the \l indicator
+ component.
+*/
+
+Style {
+ id: pieMenuStyle
+
+ /*!
+ \since 1.3
+
+ The \l StatusIndicator that this style is attached to.
+ */
+ readonly property StatusIndicator control: __control
+
+ /*!
+ \since 1.3
+
+ The color that instances of
+ \l {QtQuick.Extras::}{StatusIndicator} will have.
+ The \l {QtQuick.Extras::StatusIndicator::}{color}
+ property in \l {QtQuick.Extras::}{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 shadowRadius: smallestAxis * 0.4
+ 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
+ onActiveChanged: backgroundCanvas.requestPaint()
+ 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: -shadowRadius
+
+ Canvas {
+ id: colorCanvas
+ anchors.fill: parent
+ anchors.margins: shadowRadius
+
+ Connections {
+ target: control
+ onActiveChanged: colorCanvas.requestPaint()
+ 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
+ // Don't set fast here because Qt < 5.3 will run into QTBUG-36931
+ radius: shadowRadius
+ samples: Math.min(32, radius)
+ cached: true
+ anchors.fill: shadowGuard
+ visible: control.active
+ }
+
+ Canvas {
+ id: foregroundCanvas
+ anchors.fill: backgroundCanvas
+
+ Connections {
+ target: control
+ onActiveChanged: foregroundCanvas.requestPaint()
+ 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, width * 0.25, width / 2, height / 2, width * 0.25);
+ 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
+ }
+ }
+}
diff --git a/src/extras/Styles/Base/ToggleButtonStyle.qml b/src/extras/Styles/Base/ToggleButtonStyle.qml
new file mode 100644
index 00000000..507c0314
--- /dev/null
+++ b/src/extras/Styles/Base/ToggleButtonStyle.qml
@@ -0,0 +1,294 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtGraphicalEffects 1.0
+import QtQuick.Controls.Styles 1.1
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Private.CppUtils 1.0
+
+/*!
+ \qmltype ToggleButtonStyle
+ \inqmlmodule QtQuick.Extras.Styles
+ \since QtQuick.Extras.Styles 1.0
+ \ingroup extrasstyles
+ \brief Provides custom styling for ToggleButton.
+
+ You can create a custom toggle button by replacing the same delegates that
+ \l {QtQuick.Controls.Styles::ButtonStyle}{ButtonStyle} provides.
+*/
+
+CircularButtonStyle {
+ id: circularButtonStyle
+
+ /*!
+ \since 1.3
+
+ 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
+ onPressedChanged: {
+ backgroundCanvas.requestPaint();
+ }
+
+ onCheckedChanged: {
+ uncheckedCanvas.requestPaint();
+ checkedCanvas.requestPaint();
+ }
+ }
+
+ Connections {
+ target: circularButtonStyle
+
+ onCheckedGradientChanged: checkedCanvas.requestPaint()
+ onCheckedDropShadowColorChanged: checkedCanvas.requestPaint()
+ onUncheckedGradientChanged: uncheckedCanvas.requestPaint()
+ onUncheckedDropShadowColorChanged: uncheckedCanvas.requestPaint()
+ onInactiveGradientChanged: {
+ checkedCanvas.requestPaint();
+ uncheckedCanvas.requestPaint();
+ }
+ }
+
+ Connections {
+ target: circularButtonStyle.checkedGradient
+ onUpdated: checkedCanvas.requestPaint()
+ }
+
+ Connections {
+ target: circularButtonStyle.uncheckedGradient
+ onUpdated: uncheckedCanvas.requestPaint()
+ }
+
+ Connections {
+ target: circularButtonStyle.inactiveGradient
+ 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
+ radius: 4
+ samples: 8
+ color: uncheckedDropShadowColor
+ source: uncheckedCanvas
+ visible: !control.checked
+ }
+
+ DropShadow {
+ id: checkedDropShadow
+ anchors.fill: checkedCanvas
+ cached: true
+ radius: 4
+ samples: 8
+ 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
+ }
+ }
+}
diff --git a/src/extras/Styles/Base/TumblerStyle.qml b/src/extras/Styles/Base/TumblerStyle.qml
new file mode 100644
index 00000000..3ebcb7a2
--- /dev/null
+++ b/src/extras/Styles/Base/TumblerStyle.qml
@@ -0,0 +1,330 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtGraphicalEffects 1.0
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private 1.0
+
+/*!
+ \qmltype TumblerStyle
+ \inqmlmodule QtQuick.Extras.Styles
+ \since QtQuick.Extras.Styles 1.2
+ \ingroup extrasstyles
+ \brief Provides custom styling for Tumbler.
+
+ \note TumblerStyle requires Qt 5.3.2 or later.
+
+ 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
+
+ /*!
+ \since 1.3
+
+ The \l Tumbler that this style is attached to.
+ */
+ readonly property Tumbler control: __control
+
+ /*!
+ This property holds the spacing between each delegate.
+ */
+ 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
+ radius: __padding
+ samples: Math.min(32, radius * 2)
+ }
+ }
+
+ /*!
+ 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
+ }
+}
diff --git a/src/extras/Styles/Base/basestyle.qrc b/src/extras/Styles/Base/basestyle.qrc
new file mode 100644
index 00000000..2bcf0328
--- /dev/null
+++ b/src/extras/Styles/Base/basestyle.qrc
@@ -0,0 +1,19 @@
+<RCC>
+ <qresource prefix="/ExtrasImports/QtQuick/Extras/Styles/Base">
+ <file>TumblerStyle.qml</file>
+ <file>ToggleButtonStyle.qml</file>
+ <file>StatusIndicatorStyle.qml</file>
+ <file>PieMenuStyle.qml</file>
+ <file>HandleStyleHelper.qml</file>
+ <file>HandleStyle.qml</file>
+ <file>GaugeStyle.qml</file>
+ <file>DialStyle.qml</file>
+ <file>DelayButtonStyle.qml</file>
+ <file>CommonStyleHelper.qml</file>
+ <file>CircularTickmarkLabelStyle.qml</file>
+ <file>CircularGaugeStyle.qml</file>
+ <file>CircularButtonStyle.qml</file>
+ <file>images/needle.png</file>
+ <file>images/knob.png</file>
+ </qresource>
+</RCC>
diff --git a/src/extras/Styles/Base/basestyleplugin.cpp b/src/extras/Styles/Base/basestyleplugin.cpp
new file mode 100644
index 00000000..ef894910
--- /dev/null
+++ b/src/extras/Styles/Base/basestyleplugin.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "basestyleplugin.h"
+
+QT_BEGIN_NAMESPACE
+
+QtQuickExtrasStylesPlugin::QtQuickExtrasStylesPlugin(QObject *parent) :
+ QQmlExtensionPlugin(parent)
+{
+}
+
+void QtQuickExtrasStylesPlugin::registerTypes(const char *uri)
+{
+ Q_INIT_RESOURCE(basestyle);
+ const QString prefix = "qrc:/ExtrasImports/QtQuick/Extras/Styles";
+ // register version 1.0
+ qmlRegisterType(QUrl(prefix + "/Base/CircularButtonStyle.qml"), uri, 1, 0, "CircularButtonStyle");
+ qmlRegisterType(QUrl(prefix + "/Base/CircularGaugeStyle.qml"), uri, 1, 0, "CircularGaugeStyle");
+ qmlRegisterType(QUrl(prefix + "/Base/CircularTickmarkLabelStyle.qml"), uri, 1, 0, "CircularTickmarkLabelStyle");
+ qmlRegisterType(QUrl(prefix + "/Base/CommonStyleHelper.qml"), uri, 1, 0, "CommonStyleHelper");
+ qmlRegisterType(QUrl(prefix + "/Base/DelayButtonStyle.qml"), uri, 1, 0, "DelayButtonStyle");
+ qmlRegisterType(QUrl(prefix + "/Base/DialStyle.qml"), uri, 1, 0, "DialStyle");
+ qmlRegisterType(QUrl(prefix + "/Base/GaugeStyle.qml"), uri, 1, 0, "GaugeStyle");
+ qmlRegisterType(QUrl(prefix + "/Base/HandleStyleHelper.qml"), uri, 1, 0, "HandleStyleHelper");
+ qmlRegisterType(QUrl(prefix + "/Base/HandleStyle.qml"), uri, 1, 0, "HandleStyle");
+ qmlRegisterType(QUrl(prefix + "/Base/PieMenuStyle.qml"), uri, 1, 0, "PieMenuStyle");
+ qmlRegisterType(QUrl(prefix + "/Base/ToggleButtonStyle.qml"), uri, 1, 0, "ToggleButtonStyle");
+ // register version 1.1
+ qmlRegisterType(QUrl(prefix + "/Base/DialStyle.qml"), uri, 1, 1, "DialStyle");
+ qmlRegisterType(QUrl(prefix + "/Base/StatusIndicatorStyle.qml"), uri, 1, 1, "StatusIndicatorStyle");
+ // register version 1.2
+ qmlRegisterType(QUrl(prefix + "/Base/TumblerStyle.qml"), uri, 1, 2, "TumblerStyle");
+ // register version 1.3
+ qmlRegisterType(QUrl(prefix + "/Base/PieMenuStyle.qml"), uri, 1, 3, "PieMenuStyle");
+}
+
+QT_END_NAMESPACE
diff --git a/src/extras/Styles/Base/basestyleplugin.h b/src/extras/Styles/Base/basestyleplugin.h
new file mode 100644
index 00000000..4f1fb6d1
--- /dev/null
+++ b/src/extras/Styles/Base/basestyleplugin.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef STYLES_PLUGIN_H
+#define STYLES_PLUGIN_H
+
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+#include <QtQml/qqmlengine.h>
+
+QT_BEGIN_NAMESPACE
+
+class QtQuickExtrasStylesPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
+public:
+ explicit QtQuickExtrasStylesPlugin(QObject *parent = 0);
+
+ void registerTypes(const char *uri);
+};
+
+QT_END_NAMESPACE
+
+#endif // STYLES_PLUGIN_H
diff --git a/src/extras/Styles/Base/images/knob.png b/src/extras/Styles/Base/images/knob.png
new file mode 100644
index 00000000..ecac4d09
--- /dev/null
+++ b/src/extras/Styles/Base/images/knob.png
Binary files differ
diff --git a/src/extras/Styles/Base/images/needle.png b/src/extras/Styles/Base/images/needle.png
new file mode 100644
index 00000000..8237e516
--- /dev/null
+++ b/src/extras/Styles/Base/images/needle.png
Binary files differ
diff --git a/src/extras/Styles/Base/qmldir b/src/extras/Styles/Base/qmldir
new file mode 100644
index 00000000..509cd05c
--- /dev/null
+++ b/src/extras/Styles/Base/qmldir
@@ -0,0 +1,4 @@
+module QtQuick.Extras.Styles
+plugin qtquickextrasstylesplugin
+classname QtQuickExtrasStylesPlugin
+depends QtGraphicalEffects 1.0
diff --git a/src/extras/Styles/Flat/ApplicationWindowStyle.qml b/src/extras/Styles/Flat/ApplicationWindowStyle.qml
new file mode 100644
index 00000000..8ae620b0
--- /dev/null
+++ b/src/extras/Styles/Flat/ApplicationWindowStyle.qml
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.3 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+
+Base.ApplicationWindowStyle {
+ panel: Item {
+ readonly property alias contentArea: contentArea
+ readonly property alias menuBarArea: menuBarArea
+ readonly property alias toolBarArea: toolBarArea
+ readonly property alias statusBarArea: statusBarArea
+ readonly property bool hasToolBar: !!control.toolBar && control.toolBar.Accessible.role === Accessible.ToolBar
+
+ Rectangle {
+ id: background
+ visible: !styleData.hasColor
+ color: FlatStyle.backgroundColor
+ }
+
+ Item {
+ id: contentArea
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: statusBarArea.top
+ anchors.topMargin: toolBarArea.implicitHeight
+ }
+
+ Item {
+ id: toolBarArea
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ implicitHeight: childrenRect.height
+ height: visibleChildren.length > 0 ? implicitHeight : 0
+
+ Loader {
+ visible: active
+ active: !hasToolBar && !!control.menuBar
+ anchors.left: parent.left
+ anchors.right: parent.right
+ sourceComponent: ToolBar {
+ __menu: proxyMenu.items.length > 1 ? proxyMenu :
+ proxyMenu.items.length === 1 ? proxyMenu.items[0] : null
+ }
+ }
+ }
+
+ Item {
+ id: statusBarArea
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ implicitHeight: childrenRect.height
+ height: visibleChildren.length > 0 ? implicitHeight : 0
+ }
+
+ Item {
+ id: menuBarArea
+ visible: false
+
+ Menu {
+ id: proxyMenu
+ items: control.menuBar ? control.menuBar.menus : []
+ }
+
+ Binding {
+ target: control.toolBar
+ property: "__menu"
+ value: proxyMenu.items.length > 1 ? proxyMenu :
+ proxyMenu.items.length === 1 ? proxyMenu.items[0] : null
+ when: hasToolBar
+ }
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/BusyIndicatorStyle.qml b/src/extras/Styles/Flat/BusyIndicatorStyle.qml
new file mode 100644
index 00000000..d2809b02
--- /dev/null
+++ b/src/extras/Styles/Flat/BusyIndicatorStyle.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls.Styles 1.2 as Base
+
+Base.BusyIndicatorStyle {
+ indicator: Item {
+ id: indicator
+
+ function resolveSize() {
+ // Small: 26, Medium: 52, Large: 104
+ var sizeHint = control.styleHints ? control.styleHints['size'] : undefined
+ if (sizeHint === "small" || !sizeHint && control.width > 0 && control.width < 52)
+ return "Small"
+ if (sizeHint === "large" || !sizeHint && control.width >= 104)
+ return "Large"
+ return "Medium"
+ }
+
+ anchors.centerIn: parent
+ implicitWidth: image.sourceSize.width
+ implicitHeight: image.sourceSize.height
+
+ opacity: control.running ? 1 : 0
+ Behavior on opacity { OpacityAnimator { duration: 250 } }
+
+ Image {
+ id: image
+ anchors.centerIn: parent
+ anchors.alignWhenCentered: true
+ source: "images/BusyIndicator_Normal-" + indicator.resolveSize() + ".png"
+
+ RotationAnimator on rotation {
+ from: 0
+ to: 360
+ duration: 1000
+ loops: Animation.Infinite
+ running: indicator.visible && (control.running || indicator.opacity > 0)
+ }
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/ButtonStyle.qml b/src/extras/Styles/Flat/ButtonStyle.qml
new file mode 100644
index 00000000..d0d4ca7b
--- /dev/null
+++ b/src/extras/Styles/Flat/ButtonStyle.qml
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Private 1.0
+import QtQuick.Controls.Styles.Flat 1.0
+
+Base.ButtonStyle {
+ padding { top: 0; left: 0; right: 0; bottom: 0 }
+
+ readonly property bool __hovered: !Settings.hasTouchScreen && control.hovered
+
+ background: Rectangle {
+ property bool down: control.pressed || (control.checkable && control.checked)
+
+ implicitWidth: Math.round(100 * FlatStyle.scaleFactor)
+ implicitHeight: Math.round(26 * FlatStyle.scaleFactor)
+ radius: FlatStyle.radius
+
+ color: {
+ if (control.isDefault) {
+ if (control.checkable && control.checked) {
+ if (!control.enabled)
+ return Qt.rgba(0, 0, 0, 0.25);
+
+ if (control.pressed)
+ return control.activeFocus ? FlatStyle.checkedFocusedAndPressedColor : FlatStyle.checkedAndPressedColorAlt;
+
+ return control.activeFocus ? FlatStyle.checkedFocusedAndPressedColor : FlatStyle.pressedColor;
+ } else {
+ // Normal state.
+ if (!control.enabled)
+ return Qt.rgba(0, 0, 0, 0.15);
+
+ if (control.pressed)
+ return control.activeFocus ? FlatStyle.checkedFocusedAndPressedColor : FlatStyle.pressedColor;
+
+ if (control.activeFocus)
+ return control.pressed ? FlatStyle.checkedFocusedAndPressedColor : FlatStyle.focusedColor;
+
+ return FlatStyle.styleColor;
+ }
+ }
+
+ // Non-default button.
+ if (control.checkable && control.checked) {
+ if (!control.enabled)
+ return Qt.rgba(0, 0, 0, 0.1);
+
+ if (control.pressed)
+ return control.activeFocus ? FlatStyle.checkedFocusedAndPressedColor : FlatStyle.checkedAndPressedColor;
+
+ return control.activeFocus ? FlatStyle.focusedAndPressedColor : FlatStyle.pressedColorAlt;
+ }
+
+ if (control.pressed)
+ return control.activeFocus ? FlatStyle.focusedAndPressedColor : FlatStyle.pressedColorAlt;
+
+ if (!control.activeFocus && __hovered)
+ return FlatStyle.hoveredColor;
+
+ return "transparent";
+ }
+
+ border.color: {
+ if (!control.isDefault) {
+ if (!control.enabled)
+ return Qt.rgba(0, 0, 0, (control.checkable && control.checked ? 0.3 : 0.2));
+
+ if (control.activeFocus && !control.pressed && !control.checked)
+ return FlatStyle.focusedColor;
+
+ if (!__hovered && !control.checked && !control.pressed)
+ return FlatStyle.styleColor;
+ }
+
+ return "transparent";
+ }
+
+ border.width: control.activeFocus ? FlatStyle.twoPixels : FlatStyle.onePixel
+ }
+
+ label: Item {
+ readonly property bool isDown: control.pressed || (control.checkable && control.checked)
+ readonly property bool hasIcon: icon.status === Image.Ready || icon.status === Image.Loading
+ readonly property bool hasMenu: !!control.menu
+ readonly property bool hasText: !!control.text
+ readonly property int labelSpacing: Math.round(10 * FlatStyle.scaleFactor)
+ implicitWidth: icon.implicitWidth + label.implicitWidth + indicator.implicitHeight
+ + (hasIcon || hasText ? labelSpacing : 0) + (hasIcon && hasText ? labelSpacing : 0)
+ implicitHeight: Math.max(Math.max(icon.implicitHeight, label.implicitHeight), indicator.height)
+ baselineOffset: label.y + label.baselineOffset
+ Image {
+ id: icon
+ visible: hasIcon
+ source: control.iconSource
+ // center align when only icon, otherwise left align
+ anchors.left: parent.left
+ anchors.leftMargin: hasMenu || hasText ? labelSpacing : parent.width / 2 - width / 2
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ Text {
+ id: label
+ visible: hasText
+ text: control.text
+ elide: Text.ElideRight
+ font.family: FlatStyle.fontFamily
+ renderType: FlatStyle.__renderType
+ opacity: !enabled && !control.isDefault ? FlatStyle.disabledOpacity : 1.0
+ color: control.isDefault ? FlatStyle.selectedTextColor :
+ !enabled ? FlatStyle.disabledColor :
+ isDown ? FlatStyle.selectedTextColor :
+ control.activeFocus ? FlatStyle.focusedTextColor :
+ __hovered ? FlatStyle.selectedTextColor : FlatStyle.styleColor
+ horizontalAlignment: hasMenu != hasIcon ? Qt.AlignLeft : Qt.AlignHCenter
+ verticalAlignment: Qt.AlignVCenter
+ anchors.fill: parent
+ anchors.leftMargin: labelSpacing + (hasIcon ? labelSpacing + icon.width : 0)
+ anchors.rightMargin: hasMenu ? indicator.width : labelSpacing
+ }
+ Item {
+ id: indicator
+ visible: hasMenu
+ implicitWidth: Math.round(28 * FlatStyle.scaleFactor)
+ implicitHeight: Math.round(26 * FlatStyle.scaleFactor)
+ // center align when only menu, otherwise right align
+ anchors.right: parent.right
+ anchors.rightMargin: !hasIcon && !hasText ? parent.width / 2 - width / 2 : 0
+ anchors.verticalCenter: parent.verticalCenter
+
+ opacity: control.enabled ? 1.0 : 0.2
+ property color color: !control.enabled ? FlatStyle.disabledColor :
+ control.activeFocus && !control.pressed ? FlatStyle.focusedColor :
+ control.activeFocus || control.pressed || __hovered ? FlatStyle.selectedTextColor : FlatStyle.styleColor
+
+ Rectangle {
+ x: Math.round(7 * FlatStyle.scaleFactor)
+ y: Math.round(7 * FlatStyle.scaleFactor)
+ width: Math.round(14 * FlatStyle.scaleFactor)
+ height: FlatStyle.twoPixels
+ color: indicator.color
+ }
+ Rectangle {
+ x: Math.round(7 * FlatStyle.scaleFactor)
+ y: Math.round(12 * FlatStyle.scaleFactor)
+ width: Math.round(14 * FlatStyle.scaleFactor)
+ height: FlatStyle.twoPixels
+ color: indicator.color
+ }
+ Rectangle {
+ x: Math.round(7 * FlatStyle.scaleFactor)
+ y: Math.round(17 * FlatStyle.scaleFactor)
+ width: Math.round(14 * FlatStyle.scaleFactor)
+ height: FlatStyle.twoPixels
+ color: indicator.color
+ }
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/CalendarStyle.qml b/src/extras/Styles/Flat/CalendarStyle.qml
new file mode 100644
index 00000000..b41e3c8e
--- /dev/null
+++ b/src/extras/Styles/Flat/CalendarStyle.qml
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.3
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Private.CppUtils 1.0
+
+Base.CalendarStyle {
+ // This style doesn't support a grid.
+ gridVisible: false
+ // gridColor == frame color
+ gridColor: control.enabled ? FlatStyle.mediumFrameColor : FlatStyle.alphaFrameColor
+ // This ensures the week number separator is hidden.
+ __gridLineWidth: 0
+
+ // Used in conjunction with the control height.
+ // These values are taken from the flat style specs.
+ readonly property real __headerFontRatio: 18 / 264
+ readonly property real __weekNumberFontRatio: 9 / 264
+ readonly property real __dayFontRatio: 13 / 264
+
+ navigationBar: Rectangle {
+ implicitHeight: Math.round(control.height * 0.2121)
+ color: control.enabled ? FlatStyle.styleColor : FlatStyle.mediumFrameColor
+
+ MouseArea {
+ id: previousMonth
+ width: parent.height
+ height: width
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+ onClicked: control.showPreviousMonth()
+
+ Rectangle {
+ anchors.fill: parent
+ color: FlatStyle.selectedTextColor
+ opacity: previousMonth.pressed ? 0.25 : 0
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 80
+ }
+ }
+ }
+
+ LeftArrowIcon {
+ width: Math.round(parent.width * 0.3)
+ height: Math.round(parent.width * 0.3)
+ anchors.centerIn: parent
+ }
+ }
+ Label {
+ id: dateText
+ text: styleData.title
+ color: FlatStyle.selectedTextColor
+ elide: Text.ElideRight
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ font.pixelSize: control.height * __headerFontRatio
+ font.family: FlatStyle.fontFamily
+ font.weight: Font.Light
+ renderType: FlatStyle.__renderType
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: previousMonth.right
+ anchors.leftMargin: 2
+ anchors.right: nextMonth.left
+ anchors.rightMargin: 2
+ }
+ MouseArea {
+ id: nextMonth
+ width: parent.height
+ height: width
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+ onClicked: control.showNextMonth()
+
+ Rectangle {
+ anchors.fill: parent
+ color: FlatStyle.selectedTextColor
+ opacity: nextMonth.pressed ? 0.25 : 0
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 100
+ }
+ }
+ }
+
+ LeftArrowIcon {
+ width: Math.round(parent.width * 0.3)
+ height: Math.round(parent.width * 0.3)
+ anchors.centerIn: parent
+ scale: -1
+ }
+ }
+ }
+
+ dayDelegate: Item {
+ Rectangle {
+ id: rect
+ // There should always be at least 1 pixel margin between circles.
+ width: MathUtils.roundEven(Math.min(parent.width, parent.height) - 1)
+ height: width
+ anchors.centerIn: parent
+ radius: width / 2
+ color: (styleData.date !== undefined && styleData.selected
+ ? (control.enabled ? FlatStyle.styleColor : FlatStyle.disabledColor)
+ : "transparent")
+ border.width: styleData.today ? FlatStyle.onePixel : 0
+ border.color: !control.enabled ? FlatStyle.alphaFrameColor : FlatStyle.styleColor
+ opacity: control.enabled ? 1 : 0.15
+ }
+
+ Label {
+ id: dayDelegateText
+ text: styleData.date.getDate()
+ anchors.fill: rect
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ fontSizeMode: Text.Fit
+ font.pixelSize: control.height * __dayFontRatio
+ font.family: FlatStyle.fontFamily
+ font.weight: Font.Light
+ renderType: FlatStyle.__renderType
+ opacity: !control.enabled ? (!styleData.valid || !styleData.visibleMonth ? 0.3 : 0.6) :
+ (!styleData.valid || !styleData.visibleMonth ? 0.3 : 1)
+ color: !control.enabled ? FlatStyle.disabledColor
+ : (styleData.selected ? FlatStyle.selectedTextColor : FlatStyle.textColor)
+ }
+ }
+
+ weekNumberDelegate: Item {
+ implicitWidth: control.width * 0.14
+
+ Label {
+ text: styleData.weekNumber
+ anchors.centerIn: parent
+ anchors.verticalCenterOffset: control.height * (__dayFontRatio - __weekNumberFontRatio) / 2
+ fontSizeMode: Text.Fit
+ font.pixelSize: control.height * __weekNumberFontRatio
+ renderType: FlatStyle.__renderType
+ color: !control.enabled ? FlatStyle.disabledColor : FlatStyle.styleColor
+ opacity: !control.enabled ? FlatStyle.disabledOpacity : 1
+ }
+ }
+
+ dayOfWeekDelegate: Item {
+ implicitHeight: control.height * 0.13
+
+ Label {
+ text: localeDayName.length == 0 || localeDayName.length > 1
+ ? control.__locale.dayName(styleData.dayOfWeek, Locale.ShortFormat)[0]
+ : localeDayName
+ color: !control.enabled ? FlatStyle.disabledColor : FlatStyle.styleColor
+ opacity: !control.enabled ? FlatStyle.disabledOpacity : 1
+ font.family: FlatStyle.fontFamily
+ anchors.fill: parent
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ fontSizeMode: Text.Fit
+ font.pixelSize: control.height * __headerFontRatio
+ renderType: FlatStyle.__renderType
+
+ property string localeDayName: control.__locale.dayName(styleData.dayOfWeek, Locale.NarrowFormat)
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/CheckBoxDrawer.qml b/src/extras/Styles/Flat/CheckBoxDrawer.qml
new file mode 100644
index 00000000..5955b6fe
--- /dev/null
+++ b/src/extras/Styles/Flat/CheckBoxDrawer.qml
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.3
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Private 1.0
+import QtQuick.Controls.Styles.Flat 1.0
+
+// Internal, for use with CheckBoxStyle and GroupBoxStyle
+Item {
+ implicitWidth: Math.round(26 * FlatStyle.scaleFactor)
+ implicitHeight: implicitWidth
+
+ property bool controlEnabled: false
+ property bool controlActiveFocus: false
+ property bool controlPressed: false
+ property bool controlHovered: false
+ property bool controlChecked: false
+ property alias backgroundVisible: background.visible
+
+ onControlActiveFocusChanged: checkCanvas.requestPaint()
+ onControlEnabledChanged: checkCanvas.requestPaint()
+ onControlPressedChanged: checkCanvas.requestPaint()
+
+ Rectangle {
+ id: background
+ anchors.centerIn: parent
+ width: Math.round(20 * FlatStyle.scaleFactor)
+ height: width
+ radius: FlatStyle.radius
+ color: controlEnabled ? (controlPressed ? FlatStyle.lightFrameColor : FlatStyle.backgroundColor) : FlatStyle.disabledFillColor
+ border.color: !controlEnabled ? FlatStyle.disabledFillColor :
+ (controlPressed ? FlatStyle.darkFrameColor :
+ (controlActiveFocus ? FlatStyle.focusedColor :
+ (controlHovered ? FlatStyle.styleColor : FlatStyle.lightFrameColor)))
+ border.width: controlActiveFocus &&
+ !controlPressed ? FlatStyle.twoPixels : FlatStyle.onePixel
+ }
+
+ Canvas {
+ id: checkCanvas
+ anchors.centerIn: parent
+ width: Math.round(20 * FlatStyle.scaleFactor)
+ height: width
+ visible: controlChecked
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ ctx.beginPath();
+ ctx.moveTo(0.417 * width, 0.783 * height);
+ ctx.lineTo(0.152 * width, 0.519 * height);
+ ctx.lineTo(0.248 * width, 0.423 * height);
+ ctx.lineTo(0.417 * width, 0.593 * height);
+ ctx.lineTo(0.75 * width, 0.26 * height);
+ ctx.lineTo(0.846 * width, 0.355 * height);
+ ctx.lineTo();
+ ctx.closePath();
+ ctx.fillStyle = !controlEnabled ? FlatStyle.mediumFrameColor :
+ (controlPressed ? FlatStyle.checkedAndPressedColor :
+ (controlActiveFocus ? FlatStyle.focusedColor : FlatStyle.styleColor));
+ ctx.fill();
+ }
+ }
+
+}
diff --git a/src/extras/Styles/Flat/CheckBoxStyle.qml b/src/extras/Styles/Flat/CheckBoxStyle.qml
new file mode 100644
index 00000000..65377365
--- /dev/null
+++ b/src/extras/Styles/Flat/CheckBoxStyle.qml
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Controls.Private 1.0
+
+Base.CheckBoxStyle {
+ spacing: Math.round(8 * FlatStyle.scaleFactor)
+
+ indicator: CheckBoxDrawer {
+ controlEnabled: control.enabled
+ controlActiveFocus: control.activeFocus
+ controlPressed: control.pressed
+ controlHovered: !Settings.hasTouchScreen && control.hovered
+ controlChecked: control.checked
+ }
+
+ label: Text {
+ text: control.text
+ font.family: FlatStyle.fontFamily
+ renderType: FlatStyle.__renderType
+ anchors.verticalCenter: parent.verticalCenter
+ opacity: enabled ? 1.0 : FlatStyle.disabledOpacity
+ color: !enabled ? FlatStyle.disabledColor :
+ control.activeFocus ? FlatStyle.focusedTextColor : FlatStyle.defaultTextColor
+ }
+}
diff --git a/src/extras/Styles/Flat/CircularButtonStyle.qml b/src/extras/Styles/Flat/CircularButtonStyle.qml
new file mode 100644
index 00000000..774870e6
--- /dev/null
+++ b/src/extras/Styles/Flat/CircularButtonStyle.qml
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick.Extras.Styles 1.3 as Base
+
+Base.CircularButtonStyle { }
diff --git a/src/extras/Styles/Flat/CircularGaugeStyle.qml b/src/extras/Styles/Flat/CircularGaugeStyle.qml
new file mode 100644
index 00000000..d18cdea5
--- /dev/null
+++ b/src/extras/Styles/Flat/CircularGaugeStyle.qml
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Private.CppUtils 1.1
+import QtQuick.Extras.Styles 1.3 as Base
+
+Base.CircularGaugeStyle {
+ id: circularGaugeStyle
+
+ tickmarkInset: __thickArcTickmarklessMargin + __thickArcLineWidth / 2 - __tickmarkLength / 2
+ minorTickmarkInset: __thickArcTickmarklessMargin + __thickArcLineWidth / 2 - (__tickmarkLength / 2) / 2
+ labelInset: Math.max(textMetrics.width, textMetrics.height) / 2
+
+ // A stroked arc starts losing its shape when it is very thick, so prevent that from happening.
+ readonly property real __thickArcLineWidth: Math.min(22 * FlatStyle.scaleFactor, Math.round(outerRadius * 0.2))
+ readonly property real __thickArcTickmarklessMargin: labelInset * 2
+ readonly property real __tickmarkLength: __thickArcLineWidth * 0.5
+ readonly property real __tickmarkWidth: FlatStyle.onePixel
+ readonly property real __fontSize: Math.max(6, __protectedScope.toPixels(0.12))
+ // TODO: add this to Utils or something; it's not specific to this control
+ readonly property real __antialiasingAdjustment: FlatStyle.onePixel
+
+ Text {
+ id: textMetrics
+ font.pixelSize: __fontSize
+ text: control.maximumValue.toFixed(0)
+ visible: false
+ }
+
+ background: Item {
+ implicitWidth: Math.round(160 * FlatStyle.scaleFactor)
+ implicitHeight: Math.round(160 * FlatStyle.scaleFactor)
+
+ readonly property real thinArcLineWidth: FlatStyle.onePixel
+ readonly property bool tickmarklessVariant: false
+ readonly property real arcDistance: thinArcLineWidth * 3
+
+ Connections {
+ target: control
+ onValueChanged: thickArc.requestPaint()
+ onMinimumValueChanged: thickArc.requestPaint()
+ onMaximumValueChanged: thickArc.requestPaint()
+ onEnabledChanged: {
+ thickArc.requestPaint();
+ thinArc.requestPaint();
+ }
+ }
+
+ // TODO: test performance of this on the Pi
+ Canvas {
+ id: thickArc
+ anchors.fill: parent
+ anchors.margins: Math.floor(tickmarklessVariant ? arcDistance : __thickArcTickmarklessMargin)
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ ctx.lineWidth = __thickArcLineWidth;
+ var radius = Math.floor(width / 2 - ctx.lineWidth / 2 - __antialiasingAdjustment);
+ if (radius < 0)
+ return;
+
+ ctx.beginPath();
+ ctx.globalAlpha = control.enabled ? 1 : 0.2;
+ ctx.strokeStyle = control.enabled ? FlatStyle.styleColor : FlatStyle.disabledColor;
+ var startAngle = MathUtils.degToRad(minimumValueAngle - 90);
+ var endAngle = MathUtils.degToRad(needleRotation - 90);
+ ctx.arc(Math.floor(width / 2), Math.floor(height / 2), radius, startAngle, endAngle, false);
+ ctx.stroke();
+ }
+ }
+
+ Canvas {
+ id: thinArc
+ anchors.fill: parent
+ anchors.margins: Math.floor(tickmarklessVariant ? 0 : thickArc.anchors.margins + __thickArcLineWidth + arcDistance)
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ ctx.lineWidth = thinArcLineWidth;
+ var radius = width / 2 - ctx.lineWidth / 2 - __antialiasingAdjustment;
+ if (radius < 0)
+ return;
+
+ ctx.beginPath();
+ ctx.globalAlpha = control.enabled ? 1 : 0.2;
+ ctx.strokeStyle = control.enabled ? FlatStyle.styleColor : FlatStyle.disabledColor;
+ var startAngle = MathUtils.degToRad(minimumValueAngle - 90);
+ var endAngle = MathUtils.degToRad(maximumValueAngle - 90);
+ ctx.arc(Math.floor(width / 2), Math.floor(height / 2), radius, startAngle, endAngle, false);
+ ctx.stroke();
+ }
+ }
+ }
+
+ needle: null
+ foreground: null
+
+ tickmark: Rectangle {
+ implicitWidth: __tickmarkWidth
+ implicitHeight: __tickmarkLength
+ antialiasing: true
+ color: control.value < styleData.value || isEdgeTickmark ? (control.enabled ? FlatStyle.styleColor : FlatStyle.disabledColor) : FlatStyle.selectedTextColor
+ opacity: control.value < styleData.value || isEdgeTickmark ? (control.enabled ? 1 : 0.2) : 0.5
+ visible: (!isEdgeTickmark) || (control.value < styleData.value)
+ || (styleData.value === control.minimumValue && control.value === control.minimumValue)
+
+ readonly property bool isEdgeTickmark: styleData.value === control.minimumValue || styleData.value === control.maximumValue
+ }
+
+ minorTickmark: Rectangle {
+ implicitWidth: __tickmarkWidth
+ implicitHeight: __tickmarkLength / 2
+ antialiasing: true
+ color: control.enabled ? FlatStyle.styleColor : FlatStyle.disabledColor
+ visible: control.value < styleData.value
+ opacity: control.enabled ? 1 : 0.2
+ }
+
+ tickmarkLabel: Text {
+ font.pixelSize: __fontSize
+ text: styleData.value
+ color: control.enabled ? FlatStyle.defaultTextColor : FlatStyle.disabledColor
+ opacity: control.enabled ? 1 : FlatStyle.disabledOpacity
+ antialiasing: true
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+}
diff --git a/src/extras/Styles/Flat/CircularTickmarkLabelStyle.qml b/src/extras/Styles/Flat/CircularTickmarkLabelStyle.qml
new file mode 100644
index 00000000..8127608b
--- /dev/null
+++ b/src/extras/Styles/Flat/CircularTickmarkLabelStyle.qml
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick.Extras.Styles 1.3 as Base
+
+Base.CircularTickmarkLabelStyle {}
diff --git a/src/extras/Styles/Flat/ComboBoxStyle.qml b/src/extras/Styles/Flat/ComboBoxStyle.qml
new file mode 100644
index 00000000..b263c9cd
--- /dev/null
+++ b/src/extras/Styles/Flat/ComboBoxStyle.qml
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Extras.Private 1.0
+
+Base.ComboBoxStyle {
+ id: style
+
+ padding {
+ top: 0
+ left: Math.round(FlatStyle.scaleFactor * (control.editable ? 10 : 6))
+ right: 0
+ bottom: 0
+ }
+
+ font.family: FlatStyle.fontFamily
+ textColor: !control.enabled ? FlatStyle.mediumFrameColor :
+ control.editable ? FlatStyle.defaultTextColor :
+ control.pressed ? FlatStyle.selectedTextColor :
+ control.activeFocus ? FlatStyle.focusedTextColor : FlatStyle.styleColor
+ selectionColor: FlatStyle.highlightColor
+ selectedTextColor: FlatStyle.selectedTextColor
+
+ dropDownButtonWidth: Math.round(28 * FlatStyle.scaleFactor)
+
+ background: Item {
+ id: background
+ anchors.fill: parent
+ implicitWidth: Math.round(100 * FlatStyle.scaleFactor)
+ implicitHeight: Math.round(26 * FlatStyle.scaleFactor)
+
+ Rectangle {
+ anchors.fill: parent
+ radius: FlatStyle.radius
+
+ visible: !control.editable
+ opacity: control.enabled ? 1.0 : control.editable ? 0.1 : 0.2
+
+ color: control.editable && !control.enabled ? FlatStyle.disabledColor :
+ control.activeFocus && control.pressed ? FlatStyle.focusedAndPressedColor :
+ control.pressed ? FlatStyle.pressedColorAlt : "transparent"
+
+ border.width: control.activeFocus ? FlatStyle.twoPixels : FlatStyle.onePixel
+ border.color: !control.enabled ? FlatStyle.disabledColor :
+ control.activeFocus && control.pressed ? FlatStyle.focusedAndPressedColor :
+ control.activeFocus ? FlatStyle.highlightColor :
+ control.pressed ? FlatStyle.pressedColorAlt : FlatStyle.styleColor
+ }
+
+ Item {
+ clip: true
+ visible: control.editable
+ width: style.dropDownButtonWidth
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+
+ Rectangle {
+ width: background.width
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ radius: FlatStyle.radius
+ color: !control.enabled ? FlatStyle.lightFrameColor :
+ control.activeFocus && control.pressed ? FlatStyle.focusedAndPressedColor :
+ control.activeFocus ? FlatStyle.focusedColor :
+ control.pressed ? FlatStyle.pressedColor : FlatStyle.styleColor
+ }
+ }
+
+ LeftArrowIcon {
+ width: Math.round(14 * FlatStyle.scaleFactor)
+ height: Math.round(14 * FlatStyle.scaleFactor)
+ anchors.right: parent.right
+ anchors.rightMargin: width / 2
+ anchors.verticalCenter: parent.verticalCenter
+ rotation: control.pressed ? 90 : -90
+ color: control.editable || control.pressed ? FlatStyle.selectedTextColor
+ : control.activeFocus ? FlatStyle.focusedColor
+ : control.enabled ? FlatStyle.styleColor : FlatStyle.disabledColor
+ opacity: control.enabled || control.editable ? 1.0 : 0.2
+ }
+ }
+
+ __editor: Item {
+ clip: true
+ anchors.fill: parent
+ anchors.bottomMargin: anchors.margins + 1 // ### FIXME: compensate the -1 margin in ComboBoxStyle:
+ Rectangle {
+ anchors.fill: parent
+ anchors.rightMargin: -Math.round(3 * FlatStyle.scaleFactor)
+
+ radius: FlatStyle.radius
+ color: !control.enabled ? FlatStyle.disabledColor : FlatStyle.backgroundColor
+ opacity: control.enabled ? 1.0 : 0.1
+
+ border.width: control.activeFocus ? FlatStyle.twoPixels : FlatStyle.onePixel
+ border.color: !control.enabled ? FlatStyle.disabledColor :
+ control.activeFocus ? FlatStyle.highlightColor :
+ control.pressed ? FlatStyle.pressedColorAlt : FlatStyle.styleColor
+ }
+ }
+
+ __dropDownStyle: MenuStyle {
+ font: style.font
+ __maxPopupHeight: 600
+ __menuItemType: "comboboxitem"
+ __scrollerStyle: ScrollViewStyle { }
+
+ itemDelegate.background: Item {
+ Rectangle {
+ anchors.fill: parent
+ color: !!styleData.pressed || styleData.selected ? FlatStyle.disabledColor : "transparent"
+ opacity: !!styleData.pressed || styleData.selected ? 0.15 : 1.0
+ }
+ Rectangle {
+ color: FlatStyle.darkFrameColor
+ width: parent.width
+ height: FlatStyle.onePixel
+ anchors.bottom: parent.bottom
+ visible: styleData.index < control.__menu.items.length - 1 // TODO
+ }
+ }
+ }
+
+ __selectionHandle: SelectionHandleStyle { }
+ __cursorHandle: CursorHandleStyle { }
+}
diff --git a/src/extras/Styles/Flat/CursorHandleStyle.qml b/src/extras/Styles/Flat/CursorHandleStyle.qml
new file mode 100644
index 00000000..4efe5c15
--- /dev/null
+++ b/src/extras/Styles/Flat/CursorHandleStyle.qml
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls.Styles.Flat 1.0
+
+TextHandle {
+ x: -Math.round(FlatStyle.scaleFactor)
+ type: TextHandle.CursorHandle
+ color: FlatStyle.selectionHandleColor
+ scaleFactor: FlatStyle.scaleFactor
+ visible: styleData.hasSelection
+}
diff --git a/src/extras/Styles/Flat/DelayButtonStyle.qml b/src/extras/Styles/Flat/DelayButtonStyle.qml
new file mode 100644
index 00000000..2e438497
--- /dev/null
+++ b/src/extras/Styles/Flat/DelayButtonStyle.qml
@@ -0,0 +1,291 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras.Styles 1.1 as Base
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Private.CppUtils 1.1
+
+Base.DelayButtonStyle {
+ id: delayButtonStyle
+
+ StateGroup {
+ id: privateScope
+
+ property color buttonColor
+ property color borderColor
+ property color textColor
+ property color progressBarColor
+ readonly property real progressBarWidth: Math.round(4 * FlatStyle.scaleFactor)
+ readonly property real progressBarSpacing: Math.round(16 * FlatStyle.scaleFactor)
+ readonly property bool hovered: control.hovered && (!Settings.hasTouchScreen && !Settings.isMobile)
+
+ states: [
+ State {
+ name: "normal"
+ when: control.enabled && !control.activeFocus && !control.pressed && !privateScope.hovered && !control.checked
+
+ PropertyChanges {
+ target: privateScope
+ buttonColor: "white"
+ borderColor: FlatStyle.styleColor
+ textColor: FlatStyle.styleColor
+ progressBarColor: borderColor
+ }
+ },
+ State {
+ name: "disabled"
+ when: !control.enabled
+
+ PropertyChanges {
+ target: privateScope
+ buttonColor: FlatStyle.disabledFillColor
+ borderColor: "transparent"
+ textColor: "white"
+ progressBarColor: buttonColor
+ }
+ },
+ State {
+ name: "hovered"
+ when: !control.activeFocus && !control.pressed && privateScope.hovered
+
+ PropertyChanges {
+ target: privateScope
+ buttonColor: FlatStyle.hoveredColor
+ borderColor: "transparent"
+ textColor: "white"
+ progressBarColor: buttonColor
+ }
+ },
+ State {
+ name: "focused"
+ when: control.activeFocus && !control.pressed && !control.checked
+
+ PropertyChanges {
+ target: privateScope
+ buttonColor: "white"
+ borderColor: FlatStyle.highlightColor
+ textColor: borderColor
+ progressBarColor: borderColor
+ }
+ },
+ State {
+ name: "pressed"
+ when: !control.activeFocus && control.pressed && !control.checked
+
+ PropertyChanges {
+ target: privateScope
+ buttonColor: FlatStyle.pressedColorAlt
+ borderColor: "transparent"
+ textColor: "white"
+ progressBarColor: buttonColor
+ }
+ },
+ State {
+ name: "focusedAndPressed"
+ when: control.activeFocus && control.pressed && !control.checked
+
+ PropertyChanges {
+ target: privateScope
+ buttonColor: FlatStyle.focusedAndPressedColor
+ borderColor: "transparent"
+ textColor: "white"
+ progressBarColor: buttonColor
+ }
+ },
+ State {
+ name: "checked"
+ when: !control.activeFocus && !control.pressed && !privateScope.hovered && control.checked
+
+ PropertyChanges {
+ target: privateScope
+ buttonColor: FlatStyle.pressedColorAlt
+ borderColor: "transparent"
+ textColor: "white"
+ progressBarColor: buttonColor
+ }
+ },
+ State {
+ name: "checkedAndPressed"
+ when: !control.activeFocus && control.pressed && control.checked
+
+ PropertyChanges {
+ target: privateScope
+ buttonColor: FlatStyle.checkedAndPressedColorAlt
+ borderColor: "transparent"
+ textColor: "white"
+ progressBarColor: buttonColor
+ }
+ },
+ State {
+ name: "checkedAndFocused"
+ when: control.activeFocus && !control.pressed && control.checked
+
+ PropertyChanges {
+ target: privateScope
+ buttonColor: FlatStyle.focusedAndPressedColor
+ borderColor: "transparent"
+ textColor: "white"
+ progressBarColor: buttonColor
+ }
+ },
+ State {
+ name: "checkedPressedAndFocused"
+ when: control.activeFocus && control.pressed && control.checked
+
+ PropertyChanges {
+ target: privateScope
+ buttonColor: FlatStyle.checkedFocusedAndPressedColor
+ borderColor: "transparent"
+ textColor: "white"
+ progressBarColor: buttonColor
+ }
+ }
+ ]
+ }
+
+ label: Text {
+ text: control.text
+ anchors.fill: parent
+ anchors.margins: privateScope.progressBarWidth + privateScope.progressBarSpacing
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ wrapMode: Text.Wrap
+ fontSizeMode: Text.Fit
+ font.family: FlatStyle.fontFamily
+ font.weight: Font.Light
+ renderType: FlatStyle.__renderType
+ color: privateScope.textColor
+ font.pixelSize: TextSingleton.font.pixelSize * 1.5
+ }
+
+ background: Item {
+ implicitWidth: Math.round(160 * FlatStyle.scaleFactor)
+ implicitHeight: Math.round(160 * FlatStyle.scaleFactor)
+
+ Item {
+ id: container
+ width: Math.min(parent.width, parent.height)
+ height: width
+ anchors.centerIn: parent
+
+ Rectangle {
+ id: body
+ anchors.fill: parent
+ anchors.margins: privateScope.progressBarWidth + privateScope.progressBarSpacing
+ radius: width / 2
+ color: privateScope.buttonColor
+ border.color: privateScope.borderColor
+ border.width: FlatStyle.onePixel
+ }
+
+ CircularProgressBar {
+ id: progressBar
+ anchors.fill: parent
+ antialiasing: true
+ barWidth: privateScope.progressBarWidth
+ progress: control.progress
+ minimumValueAngle: 0
+ maximumValueAngle: 360
+
+ // TODO: Add gradient property if/when we drop support for building with 5.1.
+ Component.onCompleted: {
+ clearStops()
+ addStop(0, privateScope.progressBarColor)
+ redraw()
+ }
+
+ Connections {
+ target: privateScope
+ onProgressBarColorChanged: {
+ progressBar.clearStops()
+ progressBar.addStop(0, privateScope.progressBarColor)
+ progressBar.redraw()
+ }
+ }
+
+ states: [
+ State {
+ name: "normal"
+ when: control.progress < 1
+
+ PropertyChanges {
+ target: progressBar
+ opacity: 1
+ }
+ },
+ State {
+ name: "flashing"
+ when: control.progress === 1
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: "normal"
+ to: "flashing"
+
+ SequentialAnimation {
+ loops: Animation.Infinite
+
+ NumberAnimation {
+ target: progressBar
+ property: "opacity"
+ from: 1
+ to: 0
+ duration: 500
+ easing.type: Easing.InOutSine
+ }
+ NumberAnimation {
+ target: progressBar
+ property: "opacity"
+ from: 0
+ to: 1
+ duration: 500
+ easing.type: Easing.InOutSine
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+
+ foreground: null
+}
diff --git a/src/extras/Styles/Flat/DialStyle.qml b/src/extras/Styles/Flat/DialStyle.qml
new file mode 100644
index 00000000..3e841d9b
--- /dev/null
+++ b/src/extras/Styles/Flat/DialStyle.qml
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Private.CppUtils 1.1
+import QtQuick.Extras.Styles 1.3 as Base
+
+Base.DialStyle {
+ id: dialStyle
+
+ handleInset: handleSize * 1.5 + Math.min(control.width, control.height) * 0.15
+
+ readonly property int handleSize: Math.max(6, Math.round(Math.min(control.width, control.height) * 0.05))
+
+ background: Item {
+ implicitWidth: Math.round(160 * FlatStyle.scaleFactor)
+ implicitHeight: Math.round(160 * FlatStyle.scaleFactor)
+
+ CircularProgressBar {
+ id: progressBar
+ anchors.fill: parent
+ progress: control.value
+ minimumValueAngle: -150
+ maximumValueAngle: 150
+ barWidth: handleSize / 2
+ backgroundColor: FlatStyle.grooveColor
+
+ function updateColor() {
+ clearStops();
+ addStop(0, control.enabled ? (control.activeFocus ? FlatStyle.focusedColor : FlatStyle.styleColor) : FlatStyle.mediumFrameColor);
+ redraw();
+ }
+
+ Component.onCompleted: updateColor()
+
+ Connections {
+ target: control
+ onEnabledChanged: progressBar.updateColor()
+ onActiveFocusChanged: progressBar.updateColor()
+ }
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ anchors.margins: parent.width * 0.15
+ radius: width / 2
+ color: "white"
+ border.width: control.enabled && control.activeFocus ? FlatStyle.twoPixels : FlatStyle.onePixel
+ border.color: control.enabled ? (control.activeFocus ? FlatStyle.focusedColor : FlatStyle.styleColor) : FlatStyle.mediumFrameColor
+ }
+ }
+
+ handle: Rectangle {
+ color: control.enabled ? (control.activeFocus ? FlatStyle.focusedColor : FlatStyle.styleColor) : FlatStyle.mediumFrameColor
+ width: handleSize
+ height: width
+ radius: height / 2
+ }
+
+ tickmark: null
+}
diff --git a/src/extras/Styles/Flat/Flat.pro b/src/extras/Styles/Flat/Flat.pro
new file mode 100644
index 00000000..6f70c7a8
--- /dev/null
+++ b/src/extras/Styles/Flat/Flat.pro
@@ -0,0 +1,67 @@
+TARGET = qtquickextrasflatplugin
+TARGETPATH = QtQuick/Controls/Styles/Flat
+
+QT += qml quick
+
+HEADERS += \
+ flatstyleplugin.h \
+ qquicktexthandle.h
+SOURCES += \
+ flatstyleplugin.cpp \
+ qquicktexthandle.cpp
+
+FLAT_STYLE += \
+ $$PWD/FlatStyle.qml \
+ $$PWD/ApplicationWindowStyle.qml \
+ $$PWD/BusyIndicatorStyle.qml \
+ $$PWD/ButtonStyle.qml \
+ $$PWD/CalendarStyle.qml \
+ $$PWD/CheckBoxStyle.qml \
+ $$PWD/CheckBoxDrawer.qml \
+ $$PWD/CircularButtonStyle.qml \
+ $$PWD/CircularGaugeStyle.qml \
+ $$PWD/CircularTickmarkLabelStyle.qml \
+ $$PWD/ComboBoxStyle.qml \
+ $$PWD/CursorHandleStyle.qml \
+ $$PWD/DelayButtonStyle.qml \
+ $$PWD/DialStyle.qml \
+ $$PWD/FocusFrameStyle.qml \
+ $$PWD/GaugeStyle.qml \
+ $$PWD/GroupBoxStyle.qml \
+ $$PWD/LeftArrowIcon.qml \
+ $$PWD/MenuBarStyle.qml \
+ $$PWD/MenuStyle.qml \
+ $$PWD/PieMenuStyle.qml \
+ $$PWD/ProgressBarStyle.qml \
+ $$PWD/RadioButtonStyle.qml \
+ $$PWD/ScrollViewStyle.qml \
+ $$PWD/SelectionHandleStyle.qml \
+ $$PWD/SliderStyle.qml \
+ $$PWD/SpinBoxStyle.qml \
+ $$PWD/StatusBarStyle.qml \
+ $$PWD/StatusIndicatorStyle.qml \
+ $$PWD/SwitchStyle.qml \
+ $$PWD/TabViewStyle.qml \
+ $$PWD/TableViewStyle.qml \
+ $$PWD/TextAreaStyle.qml \
+ $$PWD/TextFieldStyle.qml \
+ $$PWD/ToggleButtonStyle.qml \
+ $$PWD/ToolBarStyle.qml \
+ $$PWD/ToolButtonStyle.qml \
+ $$PWD/ToolButtonBackground.qml \
+ $$PWD/ToolButtonIndicator.qml \
+ $$PWD/TumblerStyle.qml
+
+FLAT_STYLE += \
+ $$PWD/images/BusyIndicator_Normal-Large.png \
+ $$PWD/images/BusyIndicator_Normal-Medium.png \
+ $$PWD/images/BusyIndicator_Normal-Small.png \
+ $$PWD/fonts/OpenSans-Light.ttf \
+ $$PWD/fonts/OpenSans-Regular.ttf \
+ $$PWD/fonts/OpenSans-Semibold.ttf \
+ $$PWD/fonts/LICENSE.txt \
+
+RESOURCES += flatstyle.qrc
+
+CONFIG += no_cxx_module
+load(qml_plugin)
diff --git a/src/extras/Styles/Flat/FlatStyle.qml b/src/extras/Styles/Flat/FlatStyle.qml
new file mode 100644
index 00000000..60e03d4e
--- /dev/null
+++ b/src/extras/Styles/Flat/FlatStyle.qml
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+pragma Singleton
+
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Private 1.0
+
+QtObject {
+ readonly property string fontFamily: __openSansRegularLoader.name
+
+ readonly property color backgroundColor: "#ffffff"
+ readonly property color defaultTextColor: "#333333"
+ readonly property color styleColor: "#5caa15"
+ readonly property color strokeColor: "#328930"
+ readonly property color hoveredColor: "#7dbb44"
+ readonly property color focusedColor: "#4da6d8"
+ readonly property color focusedTextColor: "#1288cb"
+ readonly property color focusedAndPressedColor: "#4595c2"
+ readonly property color focusedStrokeColor: "#2f86bb"
+ readonly property color focusedAndPressedStrokeColor: "#266b96"
+ readonly property color checkedFocusedAndPressedColor: "#3a7ca2"
+ readonly property color checkedAndPressedColor: "#4a8811"
+ readonly property color checkedAndPressedColorAlt: "#3c6f0e"
+ readonly property color pressedColor: "#457f10"
+ readonly property color pressedColorAlt: "#539913"
+ readonly property color pressedStrokeColor: "#286e26"
+ readonly property color invalidColor: "#dd0000"
+ readonly property color disabledColor: "#000000"
+ readonly property color disabledFillColor: "#d9d9d9"
+ readonly property color highlightColor: "#4da6d8"
+ readonly property color selectedTextColor: "#ffffff"
+ readonly property color textSelectionColor: "#ceeaff"
+ readonly property color textColor: "#1a1a1a"
+ readonly property color grooveColor: "#14000000"
+ readonly property color lightFrameColor: "#cccccc"
+ readonly property color mediumFrameColor: "#b3b3b3"
+ readonly property color darkFrameColor: "#999999"
+ readonly property color alphaFrameColor: "#33000000"
+ readonly property color selectionHandleColor: "#0668ec"
+ readonly property color flatFrameColor: "#f2f2f2"
+ readonly property real disabledOpacity: 0.3
+ readonly property real defaultFontSize: 13
+
+ // 16 is the implicitHeight of text on a PC monitor. This should scale well
+ // to other devices. For example, if the implicitHeight is 64 on a touch
+ // device, the scale factor will be x4.
+ readonly property real scaleFactor: Math.max(1, TextSingleton.implicitHeight / 16)
+
+ readonly property real onePixel: Math.max(1, Math.round(scaleFactor * 1))
+ readonly property real twoPixels: Math.max(2, Math.round(scaleFactor * 2))
+ readonly property int radius: Math.round(scaleFactor * 3)
+
+ property FontLoader __openSansDemiBoldLoader: FontLoader {
+ source: "fonts/OpenSans-Semibold.ttf"
+ }
+
+ property FontLoader __openSansRegularLoader: FontLoader {
+ source: "fonts/OpenSans-Regular.ttf"
+ }
+
+ property FontLoader __openSansLightLoader: FontLoader {
+ source: "fonts/OpenSans-Light.ttf"
+ }
+
+ readonly property int __renderType: Text.QtRendering
+}
diff --git a/src/extras/Styles/Flat/FocusFrameStyle.qml b/src/extras/Styles/Flat/FocusFrameStyle.qml
new file mode 100644
index 00000000..eb4fa009
--- /dev/null
+++ b/src/extras/Styles/Flat/FocusFrameStyle.qml
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick.Controls.Private 1.0 as Private
+
+Private.FocusFrameStyle { }
diff --git a/src/extras/Styles/Flat/GaugeStyle.qml b/src/extras/Styles/Flat/GaugeStyle.qml
new file mode 100644
index 00000000..d5bf986b
--- /dev/null
+++ b/src/extras/Styles/Flat/GaugeStyle.qml
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Extras.Styles 1.3 as Base
+import QtQuick.Extras.Private 1.0
+
+Base.GaugeStyle {
+ id: gaugeStyle
+
+ readonly property int __totalValueBarWidth: Math.round(22 * FlatStyle.scaleFactor + __lineSpacing + __lineWidth)
+ readonly property int __actualValueBarWidth: __totalValueBarWidth - __lineSpacing - __lineWidth
+ readonly property int __lineWidth: FlatStyle.onePixel
+ readonly property int __lineSpacing: Math.round(3 * FlatStyle.scaleFactor)
+
+ background: Item {
+ Rectangle {
+ color: control.enabled ? FlatStyle.styleColor : FlatStyle.disabledColor
+ opacity: control.enabled ? 1 : 0.2
+ width: __lineWidth
+ height: parent.height
+ x: control.tickmarkAlignment === Qt.AlignLeft || control.tickmarkAlignment === Qt.AlignTop ? parent.width - width : 0
+ }
+ }
+
+ valueBar: Item {
+ implicitWidth: __totalValueBarWidth
+
+ Rectangle {
+ color: control.enabled ? FlatStyle.styleColor : FlatStyle.disabledColor
+ opacity: control.enabled ? 1 : 0.2
+ x: control.tickmarkAlignment === Qt.AlignRight || control.tickmarkAlignment === Qt.AlignBottom ? __lineWidth + __lineSpacing : 0
+ implicitWidth: __actualValueBarWidth
+ height: parent.height
+ }
+ }
+
+ foreground: null
+
+ tickmark: Item {
+ id: tickmarkItem
+ implicitWidth: Math.round(12 * FlatStyle.scaleFactor)
+ implicitHeight: FlatStyle.onePixel
+
+ Rectangle {
+ x: control.tickmarkAlignment === Qt.AlignLeft || control.tickmarkAlignment === Qt.AlignTop
+ ? parent.width + __actualValueBarWidth / 2 - width / 2
+ : -__actualValueBarWidth / 2 - width / 2
+ // Length of the tickmark is the same as the spacing between the tickmarks and labels.
+ width: parent.width
+ height: parent.height
+ color: gaugeStyle.valuePosition > styleData.valuePosition + height ? FlatStyle.selectedTextColor : (control.enabled ? FlatStyle.styleColor : FlatStyle.disabledColor)
+ opacity: gaugeStyle.valuePosition > styleData.valuePosition + height ? 0.5 : (control.enabled ? 1 : 0.2)
+ visible: (styleData.index === 0 && gaugeStyle.valuePosition === 0) ||
+ (styleData.index !== 0 && (gaugeStyle.valuePosition <= styleData.valuePosition || gaugeStyle.valuePosition > styleData.valuePosition + height))
+ }
+ }
+
+ minorTickmark: Item {
+ implicitWidth: Math.round(6 * FlatStyle.scaleFactor)
+ implicitHeight: FlatStyle.onePixel
+
+ Rectangle {
+ x: control.tickmarkAlignment === Qt.AlignLeft || control.tickmarkAlignment === Qt.AlignTop
+ ? parent.width + __actualValueBarWidth / 2 - width / 2
+ : -__actualValueBarWidth / 2 - width / 2
+ width: parent.width
+ height: parent.height
+ color: control.enabled ? FlatStyle.styleColor : FlatStyle.disabledColor
+ opacity: control.enabled ? 1 : 0.2
+ visible: gaugeStyle.valuePosition <= styleData.valuePosition
+ }
+ }
+
+ tickmarkLabel: Item {
+ implicitWidth: textLabel.implicitWidth
+ implicitHeight: textLabel.implicitHeight
+
+ Label {
+ id: textLabel
+ text: control.formatValue(styleData.value)
+ font: control.font
+ color: control.enabled ? FlatStyle.defaultTextColor : FlatStyle.disabledColor
+ opacity: control.enabled ? 1 : FlatStyle.disabledOpacity
+ renderType: FlatStyle.__renderType
+ Connections {
+ target: control
+ // Setting an anchor to undefined leaves it in the position it was in last.
+ // We don't want that, as we want the label's y pos to be at zero when it's not anchored.
+ // Using a binding here whose when property is true when control.orientation === Qt.Horizontal
+ // doesn't work.
+ onOrientationChanged: textLabel.y = 0
+ }
+ anchors.baseline: control.orientation === Qt.Vertical ? parent.verticalCenter : undefined
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/GroupBoxStyle.qml b/src/extras/Styles/Flat/GroupBoxStyle.qml
new file mode 100644
index 00000000..65f8cf19
--- /dev/null
+++ b/src/extras/Styles/Flat/GroupBoxStyle.qml
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls.Private 1.0 as Private
+import QtQuick.Controls.Styles.Flat 1.0
+
+Private.GroupBoxStyle {
+ id: root
+
+ readonly property int spacing: Math.round(8 * FlatStyle.scaleFactor)
+
+ padding {
+ left: spacing
+ right: spacing
+ bottom: spacing
+ }
+
+ textColor: !control.enabled ? FlatStyle.disabledColor : check.activeFocus ? FlatStyle.focusedTextColor : FlatStyle.defaultTextColor
+
+ panel: Item {
+ anchors.fill: parent
+
+ Rectangle {
+ id: background
+ radius: FlatStyle.radius
+ border.width: control.flat ? 0 : FlatStyle.onePixel
+ border.color: FlatStyle.lightFrameColor
+ color: control.flat ? FlatStyle.flatFrameColor : "transparent"
+ anchors.fill: parent
+ anchors.topMargin: Math.max(indicator.height, label.height) + root.spacing / 2
+ }
+
+ // TODO:
+ Binding {
+ target: root
+ property: "padding.top"
+ value: background.anchors.topMargin + root.spacing
+ }
+
+ CheckBoxDrawer {
+ id: indicator
+ visible: control.checkable
+ controlEnabled: control.enabled
+ controlActiveFocus: check.activeFocus
+ controlPressed: check.pressed
+ controlChecked: control.checked
+ anchors.left: parent.left
+ // compensate padding around check indicator
+ anchors.leftMargin: Math.round(-3 * FlatStyle.scaleFactor)
+ }
+
+ Text {
+ id: label
+ anchors.left: control.checkable ? indicator.right : parent.left
+ anchors.right: parent.right
+ anchors.verticalCenter: indicator.verticalCenter
+ anchors.leftMargin: control.checkable ? root.spacing / 2 : 0
+ text: control.title
+ color: root.textColor
+ renderType: FlatStyle.__renderType
+ elide: Text.ElideRight
+ font.family: FlatStyle.fontFamily
+ font.pixelSize: 16 * FlatStyle.scaleFactor
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/LeftArrowIcon.qml b/src/extras/Styles/Flat/LeftArrowIcon.qml
new file mode 100644
index 00000000..de64f3c9
--- /dev/null
+++ b/src/extras/Styles/Flat/LeftArrowIcon.qml
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.3
+
+Canvas {
+ implicitWidth: 32
+ implicitHeight: 32
+
+ property color color: "white"
+
+ onColorChanged: requestPaint()
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ ctx.beginPath();
+ ctx.moveTo(0.66321495 * width, 0.06548707 * height);
+ ctx.lineTo(0.2191097 * width, 0.50959232 * height);
+ ctx.lineTo(0.66628301 * width, 0.95676556 * height);
+ ctx.lineTo(0.77673409 * width, 0.84631453 * height);
+ ctx.lineTo(0.44001181 * width, 0.50959232 * height);
+ ctx.lineTo(0.77366599 * width, 0.1759381 * height);
+ ctx.fillStyle = color;
+ ctx.fill();
+ }
+}
diff --git a/src/extras/Styles/Flat/MenuBarStyle.qml b/src/extras/Styles/Flat/MenuBarStyle.qml
new file mode 100644
index 00000000..4be92cbc
--- /dev/null
+++ b/src/extras/Styles/Flat/MenuBarStyle.qml
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick.Controls.Styles 1.2 as Base
+
+Base.MenuBarStyle {
+ __isNative: false
+ background: null
+ itemDelegate: null
+}
diff --git a/src/extras/Styles/Flat/MenuStyle.qml b/src/extras/Styles/Flat/MenuStyle.qml
new file mode 100644
index 00000000..54a7e33f
--- /dev/null
+++ b/src/extras/Styles/Flat/MenuStyle.qml
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+
+Base.MenuStyle {
+ id: style
+ font.family: FlatStyle.fontFamily
+ __leftLabelMargin: Math.round(30 * FlatStyle.scaleFactor)
+
+ frame: Rectangle {
+ border.color: FlatStyle.darkFrameColor
+ border.width: FlatStyle.onePixel
+ }
+
+ itemDelegate.background: Rectangle {
+ color: !!styleData.pressed || styleData.selected ? FlatStyle.disabledColor : "transparent"
+ opacity: !!styleData.pressed || styleData.selected ? 0.15 : 1.0
+ }
+
+ itemDelegate.label: Text {
+ text: formatMnemonic(styleData.text, styleData.underlineMnemonic)
+ renderType: FlatStyle.__renderType
+ color: FlatStyle.defaultTextColor
+ font.family: FlatStyle.fontFamily
+ font.pixelSize: FlatStyle.defaultFontSize
+ verticalAlignment: Text.AlignVCenter
+ height: Math.round(26 * FlatStyle.scaleFactor)
+ }
+
+ itemDelegate.shortcut: Text {
+ text: styleData.shortcut
+ renderType: FlatStyle.__renderType
+ color: FlatStyle.defaultTextColor
+ font.family: FlatStyle.fontFamily
+ font.pixelSize: FlatStyle.defaultFontSize
+ }
+
+ itemDelegate.checkmarkIndicator: CheckBoxDrawer {
+ visible: styleData.checked
+ controlEnabled: styleData.enabled
+ controlChecked: styleData.checked
+ backgroundVisible: false
+ x: -4 // ### FIXME: compensate hardcoded "x: 4" in MenuStyle
+ y: FlatStyle.onePixel
+ }
+
+ itemDelegate.submenuIndicator: LeftArrowIcon {
+ scale: -1
+ color: "#000000"
+ width: Math.round(10 * FlatStyle.scaleFactor)
+ height: Math.round(10 * FlatStyle.scaleFactor)
+ baselineOffset: Math.round(7 * FlatStyle.scaleFactor)
+ }
+
+ separator: Rectangle {
+ color: FlatStyle.lightFrameColor
+ width: parent.width
+ implicitHeight: FlatStyle.onePixel
+ }
+}
diff --git a/src/extras/Styles/Flat/PieMenuStyle.qml b/src/extras/Styles/Flat/PieMenuStyle.qml
new file mode 100644
index 00000000..9b314610
--- /dev/null
+++ b/src/extras/Styles/Flat/PieMenuStyle.qml
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.3
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Extras.Styles 1.3 as Base
+import QtQuick.Extras.Private 1.0
+
+Base.PieMenuStyle {
+ id: pieMenuStyle
+ shadowRadius: 0
+ shadowSpread: 0
+ shadowColor: "transparent"
+ backgroundColor: FlatStyle.styleColor
+ selectionColor: FlatStyle.styleColor
+ startAngle: -78
+ endAngle: 78
+ cancelRadius: radius * 0.4352
+
+ __implicitWidth: Math.round(85 * 2 * FlatStyle.scaleFactor)
+ __implicitHeight: __implicitWidth
+
+ title: null
+
+ menuItem: Item {
+ readonly property var __styleData: styleData
+
+ Canvas {
+ id: actionCanvas
+ antialiasing: true
+ anchors.fill: parent
+ anchors.margins: -1
+
+ Connections {
+ target: pieMenuStyle
+ onStartAngleChanged: actionCanvas.requestPaint()
+ onEndAngleChanged: actionCanvas.requestPaint()
+ }
+
+ Connections {
+ target: __styleData
+ onPressedChanged: actionCanvas.requestPaint()
+ }
+
+ readonly property bool stroke: !__styleData.hovered
+ readonly property real spacingThickness: Math.max(4 * FlatStyle.scaleFactor, radius * 0.05)
+ // It's actually one, but stroking always goes 50/50 on the inside/outside, so this is
+ // an easy way of making it one pixel without having to mess around with more drawing code.
+ // This will work as long as the fill and stroke colors are both completely opaque.
+ readonly property real lineWidth: FlatStyle.twoPixels
+ // The following properties are all for either side of a radius/circumference, so the total is actually double.
+ readonly property real outerMenuItemSpacing: Math.asin(spacingThickness / (2 * radius))
+ readonly property real innerMenuItemSpacing: Math.asin(spacingThickness / (2 * cancelRadius))
+ // The total angle to subtract from the circumference of the inner radius arc
+ readonly property real innerRadiusStrokeCircumferenceAdjustment: Math.asin(lineWidth / (2 * cancelRadius))
+ readonly property real outerRadiusStrokeCircumferenceAdjustment: Math.asin(lineWidth / (2 * radius))
+
+ onStrokeChanged: actionCanvas.requestPaint()
+
+ function drawRingSection(ctx, x, y, section, r, ringWidth, ringColor) {
+ if (stroke) {
+ ctx.strokeStyle = ringColor;
+ ctx.fillStyle = "white";
+ } else {
+ ctx.fillStyle = ringColor;
+ }
+
+ ctx.beginPath();
+
+ if (stroke)
+ ctx.lineWidth = lineWidth;
+ var start = control.__protectedScope.sectionStartAngle(section);
+ var end = control.__protectedScope.sectionEndAngle(section);
+ // Adjust the radius to account for stroke being 50% inside/50% outside.
+ var radius = !stroke ? r : r - ctx.lineWidth / 2;
+ // Add spacing between the items, while still accounting for reversed menus.
+ if (start > end) {
+ start -= outerMenuItemSpacing;
+ end += outerMenuItemSpacing;
+ if (stroke) {
+ start -= outerRadiusStrokeCircumferenceAdjustment;
+ end += outerRadiusStrokeCircumferenceAdjustment;
+ }
+ } else {
+ start += outerMenuItemSpacing;
+ end -= outerMenuItemSpacing;
+ if (stroke) {
+ start += outerRadiusStrokeCircumferenceAdjustment;
+ end -= outerRadiusStrokeCircumferenceAdjustment;
+ }
+ }
+
+ ctx.arc(x, y, radius, start, end, start > end);
+
+ start = control.__protectedScope.sectionStartAngle(section);
+ end = control.__protectedScope.sectionEndAngle(section);
+ radius = !stroke ? ringWidth : ringWidth + ctx.lineWidth / 2;
+ if (start > end) {
+ start -= innerMenuItemSpacing;
+ end += innerMenuItemSpacing;
+ if (stroke) {
+ start -= innerRadiusStrokeCircumferenceAdjustment;
+ end += innerRadiusStrokeCircumferenceAdjustment;
+ }
+ } else {
+ start += innerMenuItemSpacing;
+ end -= innerMenuItemSpacing;
+ if (stroke) {
+ start += innerRadiusStrokeCircumferenceAdjustment;
+ end -= innerRadiusStrokeCircumferenceAdjustment;
+ }
+ }
+
+ ctx.arc(x, y, radius, end, start, start <= end);
+ ctx.closePath();
+
+ if (stroke)
+ ctx.stroke();
+
+ ctx.fill();
+ }
+
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+ drawRingSection(ctx, width / 2, height / 2, styleData.index, radius, cancelRadius,
+ __styleData.pressed ? FlatStyle.pressedColorAlt : (stroke ? backgroundColor : selectionColor));
+ }
+ }
+
+ PieMenuIcon {
+ control: pieMenuStyle.control
+ styleData: __styleData
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/ProgressBarStyle.qml b/src/extras/Styles/Flat/ProgressBarStyle.qml
new file mode 100644
index 00000000..f0b5bdd4
--- /dev/null
+++ b/src/extras/Styles/Flat/ProgressBarStyle.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private.CppUtils 1.1
+
+Base.ProgressBarStyle {
+ background: Item {
+ implicitWidth: Math.round(100 * FlatStyle.scaleFactor)
+ implicitHeight: Math.round(16 * FlatStyle.scaleFactor)
+
+ FlatProgressBar {
+ enabled: control.enabled
+ width: Math.round(parent.width)
+ height: Math.round(parent.height)
+ indeterminate: control.indeterminate
+ progress: (control.value - control.minimumValue) / (control.maximumValue - control.minimumValue)
+ }
+ }
+
+ progress: null
+}
diff --git a/src/extras/Styles/Flat/RadioButtonStyle.qml b/src/extras/Styles/Flat/RadioButtonStyle.qml
new file mode 100644
index 00000000..779e8636
--- /dev/null
+++ b/src/extras/Styles/Flat/RadioButtonStyle.qml
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+
+Base.RadioButtonStyle {
+ spacing: Math.round(8 * FlatStyle.scaleFactor)
+
+ indicator: Item {
+ implicitWidth: Math.round(26 * FlatStyle.scaleFactor)
+ implicitHeight: implicitWidth
+
+ Rectangle {
+ id: outer
+ anchors.centerIn: parent
+ width: Math.round(20 * FlatStyle.scaleFactor)
+ height: width
+ radius: width / 2
+ color: control.enabled ? (control.pressed ? FlatStyle.lightFrameColor : FlatStyle.backgroundColor) : FlatStyle.disabledFillColor
+ border.color: !control.enabled ? FlatStyle.disabledFillColor :
+ (control.pressed ? FlatStyle.darkFrameColor :
+ (control.activeFocus ? FlatStyle.focusedColor :
+ (!Settings.hasTouchScreen && control.hovered ? FlatStyle.styleColor : FlatStyle.lightFrameColor)))
+ border.width: control.activeFocus && !control.pressed ? FlatStyle.twoPixels : FlatStyle.onePixel
+ }
+
+ Rectangle {
+ id: inner
+ anchors.centerIn: parent
+ implicitWidth: Math.round(FlatStyle.scaleFactor * 8)
+ width: implicitWidth + (outer.width % 2 + implicitWidth % 2) % 2
+ height: width
+ radius: width / 2
+ visible: control.checked
+ color: !control.enabled ? FlatStyle.mediumFrameColor :
+ (control.activeFocus ? FlatStyle.focusedColor :
+ (control.pressed ? FlatStyle.checkedAndPressedColor : FlatStyle.styleColor))
+ }
+ }
+
+ label: Text {
+ text: control.text
+ font.family: FlatStyle.fontFamily
+ renderType: FlatStyle.__renderType
+ anchors.verticalCenter: parent.verticalCenter
+ opacity: enabled ? 1.0 : FlatStyle.disabledOpacity
+ color: !enabled ? FlatStyle.disabledColor :
+ control.activeFocus ? FlatStyle.focusedTextColor : FlatStyle.defaultTextColor
+ }
+}
diff --git a/src/extras/Styles/Flat/ScrollViewStyle.qml b/src/extras/Styles/Flat/ScrollViewStyle.qml
new file mode 100644
index 00000000..7e94b7db
--- /dev/null
+++ b/src/extras/Styles/Flat/ScrollViewStyle.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Controls.Private 1.0
+
+Base.ScrollViewStyle {
+ readonly property int barWidth: 2 * Math.round(FlatStyle.scaleFactor)
+ readonly property int frameWidth: control.frameVisible ? Math.max(1, Math.round(FlatStyle.scaleFactor)) : 0
+ padding {
+ top: frameWidth
+ left: frameWidth
+ right: frameWidth
+ bottom: frameWidth
+ }
+ corner: null
+ transientScrollBars: true
+ frame: Rectangle {
+ color: control["backgroundVisible"] ? FlatStyle.backgroundColor : "transparent"
+ border.color: FlatStyle.mediumFrameColor
+ border.width: frameWidth
+ visible: control.frameVisible
+ }
+ scrollBarBackground: Item {
+ implicitWidth: 2 * barWidth
+ implicitHeight: 2 * barWidth
+ }
+ handle: Item {
+ implicitWidth: barWidth
+ implicitHeight: barWidth
+ Rectangle {
+ color: FlatStyle.darkFrameColor
+ radius: barWidth / 2
+ anchors.fill: parent
+ anchors.topMargin: styleData.horizontal ? 0 : barWidth
+ anchors.leftMargin: styleData.horizontal ? barWidth : 0
+ anchors.rightMargin: styleData.horizontal ? barWidth : 0
+ anchors.bottomMargin: styleData.horizontal ? 0 : barWidth
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/SelectionHandleStyle.qml b/src/extras/Styles/Flat/SelectionHandleStyle.qml
new file mode 100644
index 00000000..954e4f8b
--- /dev/null
+++ b/src/extras/Styles/Flat/SelectionHandleStyle.qml
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls.Styles.Flat 1.0
+
+TextHandle {
+ x: -width
+ type: TextHandle.SelectionHandle
+ color: FlatStyle.selectionHandleColor
+ scaleFactor: FlatStyle.scaleFactor
+}
diff --git a/src/extras/Styles/Flat/SliderStyle.qml b/src/extras/Styles/Flat/SliderStyle.qml
new file mode 100644
index 00000000..191612c5
--- /dev/null
+++ b/src/extras/Styles/Flat/SliderStyle.qml
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private 1.0
+
+Base.SliderStyle {
+ handle: Item {
+ width: Math.round(26 * FlatStyle.scaleFactor)
+ height: width
+
+ readonly property bool focusedOnly: control.activeFocus && !control.pressed
+
+ Rectangle {
+ id: handleBorder
+ width: parent.width
+ height: width
+ radius: width / 2
+ color: focusedOnly ? FlatStyle.focusedColor :
+ control.hovered && !control.pressed ? FlatStyle.styleColor : "#000000"
+ opacity: (control.activeFocus || control.hovered) && !control.pressed ? 1.0 : 0.2
+ }
+
+ Rectangle {
+ id: handleBody
+ readonly property real borderThickness: focusedOnly ? FlatStyle.twoPixels : FlatStyle.onePixel
+ x: borderThickness
+ y: borderThickness
+ width: parent.width - 2 * borderThickness
+ height: width
+ border.color: "white"
+ border.width: (width - parent.width * 10 / 26) / 2
+ radius: width / 2
+ color: !control.enabled ? FlatStyle.disabledFillColor :
+ focusedOnly ? FlatStyle.focusedColor : FlatStyle.styleColor
+ }
+
+ Rectangle {
+ id: pressedDarkness
+ anchors.fill: parent
+ radius: width / 2
+ color: "#000000"
+ opacity: 0.2
+ visible: control.pressed
+ }
+ }
+
+ groove: Item {
+ implicitWidth: Math.round(100 * FlatStyle.scaleFactor)
+ height: Math.round(4 * FlatStyle.scaleFactor)
+ anchors.verticalCenter: parent.verticalCenter
+
+ Rectangle {
+ id: emptyGroove
+ width: parent.width
+ height: parent.height
+ radius: Math.round(2 * FlatStyle.scaleFactor)
+ color: "#000000"
+ opacity: control.enabled ? 0.2 : 0.12
+ }
+
+ Rectangle {
+ id: filledGroove
+ color: control.enabled ? FlatStyle.styleColor : FlatStyle.mediumFrameColor
+ width: styleData.handlePosition
+ height: parent.height
+ radius: emptyGroove.radius
+ }
+ }
+
+ // TODO: tickmarks
+}
diff --git a/src/extras/Styles/Flat/SpinBoxStyle.qml b/src/extras/Styles/Flat/SpinBoxStyle.qml
new file mode 100644
index 00000000..1b182da5
--- /dev/null
+++ b/src/extras/Styles/Flat/SpinBoxStyle.qml
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Controls.Private 1.0
+
+Base.SpinBoxStyle {
+ padding { top: 0; left: 0; right: 0; bottom: 0 }
+ renderType: FlatStyle.__renderType
+
+ panel: Item {
+ property int horizontalAlignment: Qt.AlignHCenter
+ property int verticalAlignment: Qt.AlignVCenter
+
+ property color foregroundColor: !control.enabled ? FlatStyle.mediumFrameColor : FlatStyle.defaultTextColor
+ property color selectionColor: FlatStyle.highlightColor
+ property color selectedTextColor: FlatStyle.selectedTextColor
+ property var margins: QtObject {
+ readonly property real top: 2 * FlatStyle.scaleFactor
+ readonly property real left: decrement.width
+ readonly property real right: increment.width
+ readonly property real bottom: 2 * FlatStyle.scaleFactor
+ }
+
+ property rect upRect: Qt.rect(increment.x, increment.y, increment.width, increment.height)
+ property rect downRect: Qt.rect(decrement.x, decrement.y, decrement.width, decrement.height)
+
+ property font font
+ font.family: FlatStyle.fontFamily
+
+ implicitWidth: Math.round(100 * FlatStyle.scaleFactor)
+ implicitHeight: Math.round(26 * FlatStyle.scaleFactor)
+
+ Item {
+ id: decrement
+ clip: true
+ width: Math.round(28 * FlatStyle.scaleFactor)
+ height: parent.height
+
+ Rectangle {
+ width: parent.width + FlatStyle.radius
+ height: parent.height
+ color: !control.enabled ? FlatStyle.lightFrameColor :
+ control.activeFocus && styleData.downPressed ? FlatStyle.checkedFocusedAndPressedColor :
+ control.activeFocus ? FlatStyle.highlightColor :
+ styleData.downPressed ? FlatStyle.checkedAndPressedColor : FlatStyle.styleColor
+ radius: FlatStyle.radius
+ }
+
+ Rectangle {
+ color: FlatStyle.backgroundColor
+ width: Math.round(10 * FlatStyle.scaleFactor)
+ height: Math.round(2 * FlatStyle.scaleFactor)
+ anchors.horizontalCenter: parent.left
+ anchors.horizontalCenterOffset: Math.round(14 * FlatStyle.scaleFactor)
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Item {
+ id: increment
+ clip: true
+ width: Math.round(28 * FlatStyle.scaleFactor)
+ height: parent.height
+ anchors.right: parent.right
+
+ Rectangle {
+ width: parent.width + FlatStyle.radius
+ height: parent.height
+ anchors.right: parent.right
+ color: !control.enabled ? FlatStyle.lightFrameColor :
+ control.activeFocus && styleData.upPressed ? FlatStyle.checkedFocusedAndPressedColor :
+ control.activeFocus ? FlatStyle.highlightColor :
+ styleData.upPressed ? FlatStyle.checkedAndPressedColor : FlatStyle.styleColor
+ radius: FlatStyle.radius
+ }
+
+ Rectangle {
+ color: FlatStyle.backgroundColor
+ width: Math.round(10 * FlatStyle.scaleFactor)
+ height: Math.round(2 * FlatStyle.scaleFactor)
+ anchors.horizontalCenter: parent.right
+ anchors.horizontalCenterOffset: Math.round(-14 * FlatStyle.scaleFactor)
+ anchors.verticalCenter: parent.verticalCenter
+ }
+
+ Rectangle {
+ color: FlatStyle.backgroundColor
+ width: Math.round(2 * FlatStyle.scaleFactor)
+ height: Math.round(10 * FlatStyle.scaleFactor)
+ anchors.horizontalCenter: parent.right
+ anchors.horizontalCenterOffset: Math.round(-14 * FlatStyle.scaleFactor)
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Rectangle {
+ id: frame
+ anchors.fill: parent
+ anchors.leftMargin: decrement.width
+ anchors.rightMargin: increment.width
+ color: !control.enabled ? "transparent" :
+ control.activeFocus ? FlatStyle.highlightColor : FlatStyle.mediumFrameColor
+
+ Rectangle {
+ id: field
+ anchors.fill: parent
+ anchors.topMargin: Math.round((!control.enabled ? 0 : control.activeFocus ? 2 : 1) * FlatStyle.scaleFactor)
+ anchors.bottomMargin: Math.round((!control.enabled ? 0 : control.activeFocus ? 2 : 1) * FlatStyle.scaleFactor)
+ color: !control.enabled ? FlatStyle.disabledColor : FlatStyle.backgroundColor
+ opacity: !control.enabled ? 0.1 : 1.0
+ }
+ }
+ }
+
+ __selectionHandle: null
+ __cursorHandle: null
+}
diff --git a/src/extras/Styles/Flat/StatusBarStyle.qml b/src/extras/Styles/Flat/StatusBarStyle.qml
new file mode 100644
index 00000000..e2bc77ff
--- /dev/null
+++ b/src/extras/Styles/Flat/StatusBarStyle.qml
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick.Controls.Styles 1.2 as Base
+
+Base.StatusBarStyle { }
diff --git a/src/extras/Styles/Flat/StatusIndicatorStyle.qml b/src/extras/Styles/Flat/StatusIndicatorStyle.qml
new file mode 100644
index 00000000..fb527665
--- /dev/null
+++ b/src/extras/Styles/Flat/StatusIndicatorStyle.qml
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.3
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Private 1.0
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Extras.Styles 1.3 as Base
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Private.CppUtils 1.0
+
+Base.StatusIndicatorStyle {
+ color: FlatStyle.focusedTextColor
+
+ indicator: Item {
+ implicitWidth: Math.max(12, MathUtils.roundEven(12 * FlatStyle.scaleFactor))
+ implicitHeight: MathUtils.roundEven(implicitWidth / 2)
+
+ Rectangle {
+ // Math.max because the control could be manually resized to be too small.
+ width: Math.max(12, MathUtils.roundEven(parent.width))
+ height: MathUtils.roundEven(width / 2)
+ radius: Math.max(2, height * 0.2)
+ anchors.centerIn: parent
+ color: !control.enabled || !control.active ? FlatStyle.disabledColor : control.color
+ opacity: control.enabled ? (control.active ? 1 : 0.3) : (control.active ? FlatStyle.disabledOpacity : 0.15)
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/SwitchStyle.qml b/src/extras/Styles/Flat/SwitchStyle.qml
new file mode 100644
index 00000000..3918c474
--- /dev/null
+++ b/src/extras/Styles/Flat/SwitchStyle.qml
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+
+Base.SwitchStyle {
+ readonly property int __knobHeight: Math.round(26 * FlatStyle.scaleFactor)
+
+ groove: Item {
+ implicitWidth: Math.round(46 * FlatStyle.scaleFactor)
+ implicitHeight: __knobHeight
+ Rectangle {
+ radius: height / 2
+ y: 1 * FlatStyle.scaleFactor
+ implicitWidth: parent.implicitWidth
+ implicitHeight: Math.round(24 * FlatStyle.scaleFactor)
+ border.width: (control.activeFocus ? FlatStyle.twoPixels : FlatStyle.onePixel)
+ border.color: control.activeFocus ? FlatStyle.highlightColor : control.enabled && control.checked ? FlatStyle.styleColor : FlatStyle.mediumFrameColor
+ color: !control.checked ? "transparent" :
+ !control.enabled ? FlatStyle.disabledFillColor :
+ control.activeFocus ? FlatStyle.highlightColor : FlatStyle.styleColor
+ }
+ }
+
+ handle: Item {
+ implicitWidth: __knobHeight
+ implicitHeight: __knobHeight
+ Rectangle {
+ id: knobShadow
+ x: 1 * FlatStyle.scaleFactor
+ y: 1 * FlatStyle.scaleFactor
+ radius: height / 2
+ width: parent.width
+ height: parent.height
+ color: "#000000"
+ opacity: 0.1
+ }
+ Rectangle {
+ id: knob
+ radius: height / 2
+ width: parent.width
+ height: parent.height
+ border.width: (control.activeFocus ? FlatStyle.twoPixels : FlatStyle.onePixel)
+ border.color: !control.enabled ? FlatStyle.mediumFrameColor :
+ control.pressed && control.activeFocus ? FlatStyle.focusedAndPressedStrokeColor :
+ control.activeFocus ? FlatStyle.focusedStrokeColor :
+ control.checked ? FlatStyle.strokeColor : FlatStyle.darkFrameColor
+ color: !control.enabled ? FlatStyle.disabledFillColor : control.pressed ? FlatStyle.lightFrameColor : FlatStyle.backgroundColor
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/TabViewStyle.qml b/src/extras/Styles/Flat/TabViewStyle.qml
new file mode 100644
index 00000000..c680f762
--- /dev/null
+++ b/src/extras/Styles/Flat/TabViewStyle.qml
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Controls.Private 1.0
+
+Base.TabViewStyle {
+ readonly property int frameWidth: Math.round(FlatStyle.scaleFactor)
+
+ tabOverlap: -frameWidth
+ frameOverlap: frameWidth
+
+ frame: Rectangle {
+ visible: control.frameVisible
+ color: FlatStyle.backgroundColor
+ border.color: FlatStyle.lightFrameColor
+ }
+
+ tab: Item {
+ readonly property int totalWidth: styleData.availableWidth + tabOverlap * (control.count - 1)
+ readonly property int tabWidth: Math.max(1, totalWidth / Math.max(1, control.count))
+ readonly property int remainder: (styleData.index == control.count - 1 && tabWidth > 0) ? totalWidth % tabWidth : 0
+
+ implicitWidth: tabWidth + remainder
+ implicitHeight: Math.round(40 * FlatStyle.scaleFactor)
+
+ Rectangle {
+ anchors.fill: parent
+ visible: styleData.pressed || !styleData.selected || styleData.activeFocus
+ opacity: styleData.enabled ? 1.0 : FlatStyle.disabledOpacity
+ color: styleData.activeFocus ? (styleData.pressed ? FlatStyle.checkedFocusedAndPressedColor : FlatStyle.focusedColor) :
+ styleData.pressed ? FlatStyle.pressedColor :
+ styleData.selected ? FlatStyle.backgroundColor :
+ !styleData.enabled ? FlatStyle.disabledColor : FlatStyle.styleColor
+ }
+
+ Text {
+ text: styleData.title
+ anchors.fill: parent
+ anchors.leftMargin: Math.round(5 * FlatStyle.scaleFactor)
+ anchors.rightMargin: anchors.leftMargin
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ font.family: FlatStyle.fontFamily
+ renderType: FlatStyle.__renderType
+ elide: Text.ElideRight
+ opacity: !styleData.enabled && styleData.selected ? FlatStyle.disabledOpacity : 1.0
+ color: !styleData.enabled && styleData.selected ? FlatStyle.disabledColor :
+ styleData.selected && styleData.enabled && !styleData.activeFocus && !styleData.pressed ? FlatStyle.styleColor : FlatStyle.selectedTextColor
+ }
+ }
+
+ tabBar: Rectangle {
+ color: FlatStyle.backgroundColor
+ border.color: control.frameVisible ? FlatStyle.lightFrameColor : "transparent"
+ anchors.fill: parent
+ Rectangle {
+ height: frameWidth
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.margins: frameWidth
+ y: control.tabPosition == Qt.TopEdge ? parent.height - height : 0
+ color: FlatStyle.backgroundColor
+ visible: control.frameVisible
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/TableViewStyle.qml b/src/extras/Styles/Flat/TableViewStyle.qml
new file mode 100644
index 00000000..c64628e8
--- /dev/null
+++ b/src/extras/Styles/Flat/TableViewStyle.qml
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.4
+import QtQuick.Controls 1.3
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Private 1.0
+import QtQuick.Controls.Styles.Flat 1.0
+
+Base.ScrollViewStyle {
+ readonly property TableView control: __control
+
+ readonly property color backgroundColor: "transparent"
+ readonly property color alternateBackgroundColor: FlatStyle.disabledColor
+
+ readonly property color textColor: FlatStyle.defaultTextColor
+ readonly property color highlightedTextColor: FlatStyle.styleColor
+
+ transientScrollBars: true
+
+ readonly property bool activateItemOnSingleClick: false
+
+ readonly property real __alternateBackgroundOpacity: 0.07
+ readonly property real __selectedBackgroundOpacity: 0.2
+ readonly property real __focusedBackgroundOpacity: 0.4
+ readonly property real __columnMargin: Math.round(20 * FlatStyle.scaleFactor)
+
+ frame: Item {
+ visible: control.frameVisible && control.alternatingRowColors
+ Rectangle {
+ anchors.bottom: parent.bottom
+ width: parent.width
+ height: 1
+ color: FlatStyle.mediumFrameColor
+ }
+ }
+
+ property Component headerDelegate: Rectangle {
+ height: Math.round(56 * FlatStyle.scaleFactor)
+ color: control.enabled ? FlatStyle.styleColor : FlatStyle.mediumFrameColor
+ Text {
+ anchors.fill: parent
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: styleData.textAlignment
+ anchors.leftMargin: __columnMargin
+ text: styleData.value
+ elide: Text.ElideRight
+ color: FlatStyle.selectedTextColor
+ font {
+ family: FlatStyle.fontFamily
+ pixelSize: FlatStyle.defaultFontSize * FlatStyle.scaleFactor
+ }
+
+ renderType: FlatStyle.__renderType
+ }
+
+ Rectangle {
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ height: Math.round(36 * FlatStyle.scaleFactor)
+ width: FlatStyle.onePixel
+ color: "white"
+ opacity: styleData.column !== control.columnCount - 1 ? 0.4 : 0
+ }
+ }
+
+ property Component rowDelegate: Item {
+ height: 46 * FlatStyle.scaleFactor
+ readonly property color selectedColor: styleData.hasActiveFocus ?
+ FlatStyle.focusedColor : FlatStyle.styleColor
+ readonly property bool selected: control.enabled && (styleData.hasActiveFocus || styleData.selected)
+
+ Rectangle {
+ id: bg
+ color: selected ? selectedColor :
+ styleData.alternate ? alternateBackgroundColor : backgroundColor
+ opacity: !control.enabled ? (styleData.alternate ? __alternateBackgroundOpacity : 1.0) :
+ styleData.hasActiveFocus ? __focusedBackgroundOpacity :
+ styleData.selected ? (styleData.alternate ? __selectedBackgroundOpacity : __alternateBackgroundOpacity) :
+ (styleData.alternate ? __alternateBackgroundOpacity : 1.0)
+ anchors.fill: parent
+ }
+
+ Rectangle {
+ // Bottom separator
+ visible: !control.alternatingRowColors
+ color: selected ? selectedColor : FlatStyle.mediumFrameColor
+ height: Math.round(1 * FlatStyle.scaleFactor)
+ width: parent.width
+ anchors.bottom: parent.bottom
+ }
+
+ Rectangle {
+ // Top separator. Only visible if the current row is selected. It hides
+ // the previous row's bottom separator when this row is selected or focused
+ visible: selected && !control.alternatingRowColors
+ color: selectedColor
+ height: Math.round(1 * FlatStyle.scaleFactor)
+ width: parent.width
+ anchors.bottom: parent.top
+ }
+ }
+
+ property Component itemDelegate: Item {
+ height: Math.round(46 * FlatStyle.scaleFactor)
+ implicitWidth: label.implicitWidth + __columnMargin
+
+ Text {
+ id: label
+ text: styleData.value !== undefined ? styleData.value : ""
+ elide: styleData.elideMode
+ color: !control.enabled ? FlatStyle.disabledColor :
+ styleData.hasActiveFocus ? FlatStyle.focusedTextColor :
+ styleData.textColor
+ opacity: !control.enabled ? FlatStyle.disabledOpacity : 1.0
+ font {
+ family: FlatStyle.fontFamily
+ pixelSize: FlatStyle.defaultFontSize * FlatStyle.scaleFactor
+ weight: control.enabled && (styleData.selected || styleData.hasActiveFocus) ?
+ Font.DemiBold : Font.Normal
+ }
+ renderType: FlatStyle.__renderType
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.leftMargin: __columnMargin
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+}
diff --git a/src/extras/Styles/Flat/TextAreaStyle.qml b/src/extras/Styles/Flat/TextAreaStyle.qml
new file mode 100644
index 00000000..52275f2f
--- /dev/null
+++ b/src/extras/Styles/Flat/TextAreaStyle.qml
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Private 1.0
+import QtQuick.Controls.Styles.Flat 1.0
+
+ScrollViewStyle {
+ readonly property TextArea control: __control
+
+ property font font
+ readonly property color textColor: !control.enabled ? FlatStyle.darkFrameColor : FlatStyle.defaultTextColor
+ readonly property color selectionColor: FlatStyle.textSelectionColor
+ readonly property color selectedTextColor: FlatStyle.defaultTextColor
+ readonly property color backgroundColor: "transparent"
+ readonly property int renderType: FlatStyle.__renderType
+ readonly property real textMargin: Math.round(10 * FlatStyle.scaleFactor)
+
+ font.family: FlatStyle.fontFamily
+
+ frame: Rectangle {
+ anchors.fill: parent
+ implicitWidth: Math.round(150 * FlatStyle.scaleFactor)
+ implicitHeight: Math.round(170 * FlatStyle.scaleFactor)
+ radius: control.frameVisible ? FlatStyle.radius : 0
+ border.width: (control.activeFocus ? FlatStyle.twoPixels : enabled ? FlatStyle.onePixel : 0)
+ border.color: !control.frameVisible ? "transparent" : control.activeFocus ? FlatStyle.highlightColor : FlatStyle.darkFrameColor
+ color: !control.backgroundVisible ? "transparent" : enabled ? FlatStyle.backgroundColor : FlatStyle.disabledColor
+ opacity: enabled ? 1.0 : 0.15
+ }
+
+ property Component __selectionHandle: SelectionHandleStyle { }
+ property Component __cursorHandle: CursorHandleStyle { }
+}
diff --git a/src/extras/Styles/Flat/TextFieldStyle.qml b/src/extras/Styles/Flat/TextFieldStyle.qml
new file mode 100644
index 00000000..060e63d1
--- /dev/null
+++ b/src/extras/Styles/Flat/TextFieldStyle.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Controls.Private 1.0
+
+Base.TextFieldStyle {
+ font.family: FlatStyle.fontFamily
+
+ textColor: !control.enabled ? FlatStyle.mediumFrameColor : FlatStyle.defaultTextColor
+ placeholderTextColor: FlatStyle.mediumFrameColor
+ selectionColor: FlatStyle.textSelectionColor
+ selectedTextColor: FlatStyle.defaultTextColor
+ renderType: FlatStyle.__renderType
+
+ padding {
+ top: 0
+ left: Math.round(FlatStyle.scaleFactor * 10)
+ right: Math.round(FlatStyle.scaleFactor * 10)
+ bottom: 0
+ }
+
+ background: Rectangle {
+ implicitWidth: Math.round(150 * FlatStyle.scaleFactor)
+ implicitHeight: Math.max(Math.round(26 * FlatStyle.scaleFactor), Math.round(control.__contentHeight * 1.2))
+ radius: FlatStyle.radius
+ border.width: (control.activeFocus ? FlatStyle.twoPixels : enabled ? FlatStyle.onePixel : 0)
+ border.color: control.activeFocus ? FlatStyle.highlightColor : FlatStyle.darkFrameColor
+ color: enabled ? FlatStyle.backgroundColor : FlatStyle.disabledColor
+ opacity: enabled ? 1.0 : 0.15
+ }
+
+ __selectionHandle: SelectionHandleStyle { }
+ __cursorHandle: CursorHandleStyle { }
+}
diff --git a/src/extras/Styles/Flat/ToggleButtonStyle.qml b/src/extras/Styles/Flat/ToggleButtonStyle.qml
new file mode 100644
index 00000000..3b120e1d
--- /dev/null
+++ b/src/extras/Styles/Flat/ToggleButtonStyle.qml
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Styles 1.3 as Base
+
+Base.ToggleButtonStyle {
+ label: Label {
+ text: control.text
+ color: FlatStyle.mediumFrameColor
+ font.family: FlatStyle.fontFamily
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ renderType: FlatStyle.__renderType
+ }
+
+ background: Item {
+ implicitWidth: Math.round(100 * FlatStyle.scaleFactor)
+ implicitHeight: Math.round(52 * FlatStyle.scaleFactor)
+
+ readonly property real outerLightLineWidth: Math.max(4, Math.round(innerRect.radius * 0.5))
+ readonly property real thinDarkLineWidth: Math.max(1, FlatStyle.onePixel)
+ readonly property color indicatorColor: control.enabled ? (control.checked ? FlatStyle.styleColor : FlatStyle.invalidColor) : FlatStyle.lightFrameColor
+ readonly property bool hovered: control.hovered && (!Settings.hasTouchScreen && !Settings.isMobile)
+
+ Rectangle {
+ id: innerRect
+ color: control.enabled ? (control.pressed ? FlatStyle.lightFrameColor : "white") : Qt.rgba(0, 0, 0, 0.07)
+ border.color: control.enabled ? (hovered ? indicatorColor : FlatStyle.mediumFrameColor) : "#d8d8d8" // TODO: specs don't mention having a border for disabled toggle buttons
+ border.width: !control.activeFocus ? thinDarkLineWidth : 0
+ radius: Math.round(3 * FlatStyle.scaleFactor)
+ anchors.fill: parent
+
+ Item {
+ id: clipItem
+ x: control.checked ? width : 0
+ width: indicatorRect.width / 2
+ height: indicatorRect.height / 2
+ clip: true
+
+ Rectangle {
+ id: indicatorRect
+ x: control.checked ? -parent.width : 0
+ color: indicatorColor
+ radius: innerRect.radius
+ width: innerRect.width
+ height: Math.round(8 * FlatStyle.scaleFactor) * 2
+ }
+ }
+ }
+
+ Rectangle {
+ anchors.fill: innerRect
+ color: "transparent"
+ radius: innerRect.radius
+ border.color: FlatStyle.focusedColor
+ border.width: 2 * FlatStyle.scaleFactor
+ visible: control.activeFocus
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/ToolBarStyle.qml b/src/extras/Styles/Flat/ToolBarStyle.qml
new file mode 100644
index 00000000..0b6aa688
--- /dev/null
+++ b/src/extras/Styles/Flat/ToolBarStyle.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Controls.Private 1.0
+
+Base.ToolBarStyle {
+ padding {
+ top: 0
+ left: Math.round(FlatStyle.scaleFactor * 10)
+ right: Math.round(FlatStyle.scaleFactor * 10)
+ bottom: 0
+ }
+
+ menuButton: Item {
+ implicitWidth: Math.round(FlatStyle.scaleFactor * 26)
+ implicitHeight: Math.round(FlatStyle.scaleFactor * 26)
+
+ ToolButtonBackground {
+ anchors.fill: parent
+ buttonEnabled: control.enabled
+ buttonHasActiveFocus: control.activeFocus
+ buttonPressed: styleData.pressed
+ buttonChecked: false
+ buttonHovered: !Settings.hasTouchScreen && styleData.hovered
+ }
+
+ ToolButtonIndicator {
+ buttonEnabled: control.enabled
+ buttonHasActiveFocus: styleData.activeFocus
+ buttonPressedOrChecked: styleData.pressed
+ anchors.centerIn: parent
+ }
+ }
+
+ background: Rectangle {
+ implicitHeight: Math.max(1, Math.round(FlatStyle.scaleFactor * 40))
+ color: FlatStyle.flatFrameColor
+ }
+}
diff --git a/src/extras/Styles/Flat/ToolButtonBackground.qml b/src/extras/Styles/Flat/ToolButtonBackground.qml
new file mode 100644
index 00000000..7dcd1ee0
--- /dev/null
+++ b/src/extras/Styles/Flat/ToolButtonBackground.qml
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Private 1.0
+import QtQuick.Controls.Styles.Flat 1.0
+
+// Internal, for use with ToolButtonStyle and ToolBarStyle
+Rectangle {
+ id: background
+
+ property bool buttonEnabled: false
+ property bool buttonHasActiveFocus: false
+ property bool buttonHovered: false
+ property bool buttonChecked: false
+ property bool buttonPressed: false
+
+ color: {
+ if (buttonChecked) {
+ if (!buttonEnabled)
+ return "transparent";
+ if (buttonHasActiveFocus)
+ return buttonPressed ? FlatStyle.checkedFocusedAndPressedColor : FlatStyle.focusedAndPressedColor;
+ if (buttonPressed)
+ return Qt.rgba(0, 0, 0, 0.1);
+ return "transparent";
+ }
+
+ if (!buttonEnabled)
+ return "transparent";
+ if (buttonHasActiveFocus)
+ return buttonPressed ? FlatStyle.focusedAndPressedColor : "transparent";
+ if (buttonPressed)
+ return Qt.rgba(0, 0, 0, 0.1);
+ return "transparent";
+ }
+ border.color: {
+ if (buttonChecked) {
+ if (!buttonEnabled)
+ return Qt.rgba(0, 0, 0, 0.1);
+ if (buttonHasActiveFocus)
+ return "transparent";
+ if (buttonPressed)
+ return Qt.rgba(0, 0, 0, 0.2);
+ if (buttonHovered)
+ return Qt.rgba(0, 0, 0, 0.3);
+ return Qt.rgba(0, 0, 0, 0.2);
+ }
+
+ if (!buttonEnabled)
+ return "transparent";
+ if (buttonHasActiveFocus && !buttonPressed)
+ return FlatStyle.focusedColor;
+ if (buttonHovered && !buttonPressed)
+ return Qt.rgba(0, 0, 0, 0.2);
+ return "transparent";
+ }
+ border.width: buttonHasActiveFocus ? FlatStyle.twoPixels : FlatStyle.onePixel
+ radius: FlatStyle.radius
+}
diff --git a/src/extras/Styles/Flat/ToolButtonIndicator.qml b/src/extras/Styles/Flat/ToolButtonIndicator.qml
new file mode 100644
index 00000000..1c6ffc74
--- /dev/null
+++ b/src/extras/Styles/Flat/ToolButtonIndicator.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Private 1.0
+import QtQuick.Controls.Styles.Flat 1.0
+
+// Internal, for use with ToolButtonStyle and ToolBarStyle
+Item {
+ id: toolButtonIndicator
+ implicitWidth: Math.round(26 * FlatStyle.scaleFactor)
+ implicitHeight: Math.round(26 * FlatStyle.scaleFactor)
+
+ property bool buttonEnabled: false
+ property bool buttonHasActiveFocus: false
+ property bool buttonPressedOrChecked: false
+
+ Column {
+ anchors.centerIn: parent
+ spacing: Math.round(2 * FlatStyle.scaleFactor)
+
+ Repeater {
+ model: toolButtonIndicator.visible ? 3 : 0
+
+ Rectangle {
+ width: Math.round(4 * FlatStyle.scaleFactor)
+ height: width
+ radius: width / 2
+ color: !buttonEnabled ? FlatStyle.disabledColor : buttonPressedOrChecked && buttonHasActiveFocus
+ ? FlatStyle.selectedTextColor : buttonHasActiveFocus
+ ? FlatStyle.focusedColor : FlatStyle.defaultTextColor
+ opacity: !buttonEnabled ? FlatStyle.disabledOpacity : 1
+ }
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/ToolButtonStyle.qml b/src/extras/Styles/Flat/ToolButtonStyle.qml
new file mode 100644
index 00000000..60866e91
--- /dev/null
+++ b/src/extras/Styles/Flat/ToolButtonStyle.qml
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2 as Base
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Controls.Private 1.0
+
+Base.ButtonStyle {
+ padding { top: 0; left: 0; right: 0; bottom: 0 }
+
+ panel: Item {
+ id: panelItem
+
+ readonly property bool isDown: control.pressed || (control.checkable && control.checked)
+ readonly property bool hasIcon: icon.status === Image.Ready || icon.status === Image.Loading
+ readonly property bool hasMenu: !!control.menu
+ readonly property bool hasText: !!control.text
+ readonly property real margins: 10 * FlatStyle.scaleFactor
+
+ ToolButtonBackground {
+ id: background
+ anchors.fill: parent
+ buttonEnabled: control.enabled
+ buttonHasActiveFocus: control.activeFocus
+ buttonPressed: control.pressed
+ buttonChecked: control.checkable && control.checked
+ buttonHovered: !Settings.hasTouchScreen && control.hovered
+ }
+
+ implicitWidth: icon.implicitWidth + label.implicitWidth + indicator.implicitHeight
+ + (hasIcon || hasText ? panelItem.margins : 0) + (hasIcon && hasText ? panelItem.margins : 0)
+ implicitHeight: Math.max(background.height, Math.max(icon.implicitHeight, Math.max(label.implicitHeight, indicator.height)))
+ baselineOffset: label.y + label.baselineOffset
+
+ Image {
+ id: icon
+ visible: hasIcon
+ source: control.iconSource
+ anchors.leftMargin: panelItem.margins
+ anchors.verticalCenter: parent.verticalCenter
+ // center align when only icon, otherwise left align
+ anchors.left: hasMenu || hasText ? parent.left : undefined
+ anchors.horizontalCenter: !hasMenu && !hasText ? parent.horizontalCenter : undefined
+ }
+ Text {
+ id: label
+ visible: hasText
+ text: control.text
+ elide: Text.ElideRight
+ font.family: FlatStyle.fontFamily
+ renderType: FlatStyle.__renderType
+ color: !enabled ? FlatStyle.disabledColor : panelItem.isDown && control.activeFocus
+ ? FlatStyle.selectedTextColor : control.activeFocus
+ ? FlatStyle.focusedColor : FlatStyle.defaultTextColor
+ opacity: !enabled ? FlatStyle.disabledOpacity : 1.0
+ horizontalAlignment: hasMenu && !hasIcon ? Qt.AlignLeft : Qt.AlignHCenter
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: icon.right
+ anchors.right: indicator.left
+ anchors.leftMargin: hasIcon ? panelItem.margins : 0
+ anchors.rightMargin: hasMenu ? 0 : panelItem.margins
+ }
+ ToolButtonIndicator {
+ id: indicator
+ visible: panelItem.hasMenu
+ buttonEnabled: control.enabled
+ buttonHasActiveFocus: control.activeFocus
+ buttonPressedOrChecked: panelItem.isDown
+ anchors.verticalCenter: parent.verticalCenter
+ // center align when only menu, otherwise right align
+ anchors.right: hasIcon || hasText ? parent.right : undefined
+ anchors.horizontalCenter: !hasIcon && !hasText ? parent.horizontalCenter : undefined
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/TumblerStyle.qml b/src/extras/Styles/Flat/TumblerStyle.qml
new file mode 100644
index 00000000..cede9fee
--- /dev/null
+++ b/src/extras/Styles/Flat/TumblerStyle.qml
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Controls.Private 1.0
+import QtQuick.Controls.Styles.Flat 1.0
+import QtQuick.Extras.Styles 1.3 as Base
+
+Base.TumblerStyle {
+ id: tumblerStyle
+
+ padding.left: 0
+ padding.right: 0
+ padding.top: __frameHeight
+ padding.bottom: __frameHeight
+
+ visibleItemCount: 5
+
+ readonly property real __frameHeight: FlatStyle.onePixel
+
+ background: null
+
+ foreground: null
+
+ columnForeground: Item {
+ Item {
+ anchors.centerIn: parent
+ width: parent.width
+ height: tumblerStyle.__delegateHeight
+
+ Rectangle {
+ width: parent.width * 0.8
+ anchors.horizontalCenter: parent.horizontalCenter
+ height: __frameHeight
+ color: control.enabled ? FlatStyle.styleColor : FlatStyle.disabledColor
+ opacity: control.enabled ? 1 : 0.2
+ anchors.top: parent.top
+ visible: !styleData.activeFocus
+ }
+
+ Rectangle {
+ width: parent.width * 0.8
+ anchors.horizontalCenter: parent.horizontalCenter
+ height: __frameHeight
+ color: control.enabled ? FlatStyle.styleColor : FlatStyle.disabledColor
+ opacity: control.enabled ? 1 : 0.2
+ anchors.top: parent.bottom
+ visible: !styleData.activeFocus
+ }
+ }
+ }
+
+ highlight: Item {
+ id: highlightItem
+ implicitHeight: (control.height - padding.top - padding.bottom) / tumblerStyle.visibleItemCount
+
+ Rectangle {
+ color: styleData.activeFocus ? FlatStyle.highlightColor : "white"
+ width: parent.width
+ height: parent.height
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ }
+
+ separator: null
+
+ frame: Item {
+ Rectangle {
+ height: __frameHeight
+ width: parent.width
+ color: FlatStyle.disabledColor
+ opacity: control.enabled ? 0.2 : 0.1
+ }
+
+ Rectangle {
+ height: __frameHeight
+ width: parent.width
+ anchors.bottom: parent.bottom
+ color: FlatStyle.disabledColor
+ opacity: control.enabled ? 0.2 : 0.1
+ }
+ }
+
+ delegate: Item {
+ id: delegateItem
+ implicitHeight: (control.height - padding.top - padding.bottom) / tumblerStyle.visibleItemCount
+
+ Text {
+ id: label
+ text: styleData.value
+ color: control.enabled ? (styleData.activeFocus ? FlatStyle.focusedTextColor : FlatStyle.defaultTextColor) : FlatStyle.disabledColor
+ opacity: control.enabled ? enabledOpacity : FlatStyle.disabledOpacity
+ font.pixelSize: Math.round(TextSingleton.font.pixelSize * 1.3)
+ font.family: FlatStyle.fontFamily
+ renderType: FlatStyle.__renderType
+ anchors.centerIn: parent
+
+ readonly property real enabledOpacity: 1.1 - Math.abs(styleData.displacement * 2) / tumblerStyle.visibleItemCount * (230 / 255)
+ }
+
+ Loader {
+ id: block
+ y: styleData.displacement < 0 ? 0 : (1 - offset) * parent.height
+ width: parent.width
+ height: parent.height * offset
+ clip: true
+ active: Math.abs(styleData.displacement) <= 1
+
+ property real offset: Math.max(0, 1 - Math.abs(styleData.displacement))
+
+ sourceComponent: Rectangle {
+ // Use a Rectangle that is the same color as the highlight in order to avoid rendering text on top of text.
+ color: styleData.activeFocus ? FlatStyle.highlightColor : "white"
+ anchors.fill: parent
+
+ Text {
+ id: focusText
+ y: styleData.displacement < 0 ? 0 : parent.height - height
+ width: parent.width
+ height: delegateItem.height
+ color: control.enabled ? (styleData.activeFocus ? "white" : FlatStyle.defaultTextColor) : FlatStyle.disabledColor
+ opacity: control.enabled ? 1 : FlatStyle.disabledOpacity
+ text: styleData.value
+ font.pixelSize: Math.round(TextSingleton.font.pixelSize * 1.5)
+ font.family: FlatStyle.fontFamily
+ renderType: FlatStyle.__renderType
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
+ }
+ }
+}
diff --git a/src/extras/Styles/Flat/flatstyle.qrc b/src/extras/Styles/Flat/flatstyle.qrc
new file mode 100644
index 00000000..3084d51e
--- /dev/null
+++ b/src/extras/Styles/Flat/flatstyle.qrc
@@ -0,0 +1,51 @@
+<RCC>
+ <qresource prefix="/ExtrasImports/QtQuick/Controls/Styles/Flat">
+ <file>ApplicationWindowStyle.qml</file>
+ <file>BusyIndicatorStyle.qml</file>
+ <file>ButtonStyle.qml</file>
+ <file>CalendarStyle.qml</file>
+ <file>CheckBoxDrawer.qml</file>
+ <file>CheckBoxStyle.qml</file>
+ <file>CircularButtonStyle.qml</file>
+ <file>CircularGaugeStyle.qml</file>
+ <file>CircularTickmarkLabelStyle.qml</file>
+ <file>ComboBoxStyle.qml</file>
+ <file>CursorHandleStyle.qml</file>
+ <file>DelayButtonStyle.qml</file>
+ <file>DialStyle.qml</file>
+ <file>FlatStyle.qml</file>
+ <file>FocusFrameStyle.qml</file>
+ <file>GaugeStyle.qml</file>
+ <file>GroupBoxStyle.qml</file>
+ <file>LeftArrowIcon.qml</file>
+ <file>MenuBarStyle.qml</file>
+ <file>MenuStyle.qml</file>
+ <file>PieMenuStyle.qml</file>
+ <file>ProgressBarStyle.qml</file>
+ <file>RadioButtonStyle.qml</file>
+ <file>ScrollViewStyle.qml</file>
+ <file>SelectionHandleStyle.qml</file>
+ <file>SliderStyle.qml</file>
+ <file>SpinBoxStyle.qml</file>
+ <file>StatusBarStyle.qml</file>
+ <file>StatusIndicatorStyle.qml</file>
+ <file>SwitchStyle.qml</file>
+ <file>TabViewStyle.qml</file>
+ <file>TableViewStyle.qml</file>
+ <file>TextAreaStyle.qml</file>
+ <file>TextFieldStyle.qml</file>
+ <file>ToggleButtonStyle.qml</file>
+ <file>ToolBarStyle.qml</file>
+ <file>ToolButtonBackground.qml</file>
+ <file>ToolButtonIndicator.qml</file>
+ <file>ToolButtonStyle.qml</file>
+ <file>TumblerStyle.qml</file>
+ <file>images/BusyIndicator_Normal-Large.png</file>
+ <file>images/BusyIndicator_Normal-Medium.png</file>
+ <file>images/BusyIndicator_Normal-Small.png</file>
+ <file>fonts/LICENSE.txt</file>
+ <file>fonts/OpenSans-Light.ttf</file>
+ <file>fonts/OpenSans-Regular.ttf</file>
+ <file>fonts/OpenSans-Semibold.ttf</file>
+ </qresource>
+</RCC>
diff --git a/src/extras/Styles/Flat/flatstyleplugin.cpp b/src/extras/Styles/Flat/flatstyleplugin.cpp
new file mode 100644
index 00000000..e3bffd5c
--- /dev/null
+++ b/src/extras/Styles/Flat/flatstyleplugin.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "flatstyleplugin.h"
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qdebug.h>
+
+#include "qquicktexthandle.h"
+
+static void initResources()
+{
+ Q_INIT_RESOURCE(flatstyle);
+}
+
+extern "C" {
+ Q_DECL_EXPORT bool qt_quick_controls_style_init()
+ {
+ initResources();
+ return true;
+ }
+
+ Q_DECL_EXPORT const char* qt_quick_controls_style_path()
+ {
+ return "qrc:/ExtrasImports/QtQuick/Controls/Styles/";
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+QtQuickExtrasStylesPlugin::QtQuickExtrasStylesPlugin(QObject *parent) :
+ QQmlExtensionPlugin(parent)
+{
+}
+
+void QtQuickExtrasStylesPlugin::registerTypes(const char *uri)
+{
+ Q_INIT_RESOURCE(flatstyle);
+
+ const QString prefix = "qrc:/ExtrasImports/QtQuick/Controls/Styles/Flat/";
+ // register version 1.0
+ qmlRegisterSingletonType(QUrl(prefix + "FlatStyle.qml"), uri, 1, 0, "FlatStyle");
+ qmlRegisterType(QUrl(prefix + "ApplicationWindowStyle.qml"), uri, 1, 0, "ApplicationWindowStyle");
+ qmlRegisterType(QUrl(prefix + "BusyIndicatorStyle.qml"), uri, 1, 0, "BusyIndicatorStyle");
+ qmlRegisterType(QUrl(prefix + "ButtonStyle.qml"), uri, 1, 0, "ButtonStyle");
+ qmlRegisterType(QUrl(prefix + "CalendarStyle.qml"), uri, 1, 0, "CalendarStyle");
+ qmlRegisterType(QUrl(prefix + "CheckBoxStyle.qml"), uri, 1, 0, "CheckBoxStyle");
+ qmlRegisterType(QUrl(prefix + "CheckBoxDrawer.qml"), uri, 1, 0, "CheckBoxDrawer");
+ qmlRegisterType(QUrl(prefix + "CircularButtonStyle.qml"), uri, 1, 0, "CircularButtonStyle");
+ qmlRegisterType(QUrl(prefix + "CircularGaugeStyle.qml"), uri, 1, 0, "CircularGaugeStyle");
+ qmlRegisterType(QUrl(prefix + "CircularTickmarkLabelStyle.qml"), uri, 1, 0, "CircularTickmarkLabelStyle");
+ qmlRegisterType(QUrl(prefix + "ComboBoxStyle.qml"), uri, 1, 0, "ComboBoxStyle");
+ qmlRegisterType(QUrl(prefix + "CursorHandleStyle.qml"), uri, 1, 0, "CursorHandleStyle");
+ qmlRegisterType(QUrl(prefix + "DelayButtonStyle.qml"), uri, 1, 0, "DelayButtonStyle");
+ qmlRegisterType(QUrl(prefix + "FocusFrameStyle.qml"), uri, 1, 0, "FocusFrameStyle");
+ qmlRegisterType(QUrl(prefix + "GaugeStyle.qml"), uri, 1, 0, "GaugeStyle");
+ qmlRegisterType(QUrl(prefix + "GroupBoxStyle.qml"), uri, 1, 0, "GroupBoxStyle");
+ qmlRegisterType(QUrl(prefix + "LeftArrowIcon.qml"), uri, 1, 0, "LeftArrowIcon");
+ qmlRegisterType(QUrl(prefix + "MenuBarStyle.qml"), uri, 1, 0, "MenuBarStyle");
+ qmlRegisterType(QUrl(prefix + "PieMenuStyle.qml"), uri, 1, 0, "PieMenuStyle");
+ qmlRegisterType(QUrl(prefix + "ProgressBarStyle.qml"), uri, 1, 0, "ProgressBarStyle");
+ qmlRegisterType(QUrl(prefix + "RadioButtonStyle.qml"), uri, 1, 0, "RadioButtonStyle");
+ qmlRegisterType(QUrl(prefix + "ScrollViewStyle.qml"), uri, 1, 0, "ScrollViewStyle");
+ qmlRegisterType(QUrl(prefix + "SelectionHandleStyle.qml"), uri, 1, 0, "SelectionHandleStyle");
+ qmlRegisterType(QUrl(prefix + "SliderStyle.qml"), uri, 1, 0, "SliderStyle");
+ qmlRegisterType(QUrl(prefix + "SpinBoxStyle.qml"), uri, 1, 0, "SpinBoxStyle");
+ qmlRegisterType(QUrl(prefix + "StatusBarStyle.qml"), uri, 1, 0, "StatusBarStyle");
+ qmlRegisterType(QUrl(prefix + "StatusIndicatorStyle.qml"), uri, 1, 0, "StatusIndicatorStyle");
+ qmlRegisterType(QUrl(prefix + "SwitchStyle.qml"), uri, 1, 0, "SwitchStyle");
+ qmlRegisterType(QUrl(prefix + "TabViewStyle.qml"), uri, 1, 0, "TabViewStyle");
+ qmlRegisterType(QUrl(prefix + "TableViewStyle.qml"), uri, 1, 0, "TableViewStyle");
+ qmlRegisterType(QUrl(prefix + "TextAreaStyle.qml"), uri, 1, 0, "TextAreaStyle");
+ qmlRegisterType(QUrl(prefix + "TextFieldStyle.qml"), uri, 1, 0, "TextFieldStyle");
+ qmlRegisterType(QUrl(prefix + "ToggleButtonStyle.qml"), uri, 1, 0, "ToggleButtonStyle");
+ qmlRegisterType(QUrl(prefix + "ToolBarStyle.qml"), uri, 1, 0, "ToolBarStyle");
+ qmlRegisterType(QUrl(prefix + "ToolButtonStyle.qml"), uri, 1, 0, "ToolButtonStyle");
+ qmlRegisterType(QUrl(prefix + "ToolButtonBackground.qml"), uri, 1, 0, "ToolButtonBackground");
+ qmlRegisterType(QUrl(prefix + "ToolButtonIndicator.qml"), uri, 1, 0, "ToolButtonIndicator");
+ qmlRegisterType(QUrl(prefix + "TumblerStyle.qml"), uri, 1, 0, "TumblerStyle");
+ qmlRegisterType<QQuickTextHandle>("QtQuick.Controls.Styles.Flat", 1, 0, "TextHandle");
+}
+
+QT_END_NAMESPACE
diff --git a/src/extras/Styles/Flat/flatstyleplugin.h b/src/extras/Styles/Flat/flatstyleplugin.h
new file mode 100644
index 00000000..4f1fb6d1
--- /dev/null
+++ b/src/extras/Styles/Flat/flatstyleplugin.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef STYLES_PLUGIN_H
+#define STYLES_PLUGIN_H
+
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+#include <QtQml/qqmlengine.h>
+
+QT_BEGIN_NAMESPACE
+
+class QtQuickExtrasStylesPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
+public:
+ explicit QtQuickExtrasStylesPlugin(QObject *parent = 0);
+
+ void registerTypes(const char *uri);
+};
+
+QT_END_NAMESPACE
+
+#endif // STYLES_PLUGIN_H
diff --git a/src/extras/Styles/Flat/fonts/LICENSE.txt b/src/extras/Styles/Flat/fonts/LICENSE.txt
new file mode 100644
index 00000000..d6456956
--- /dev/null
+++ b/src/extras/Styles/Flat/fonts/LICENSE.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/src/extras/Styles/Flat/fonts/OpenSans-Light.ttf b/src/extras/Styles/Flat/fonts/OpenSans-Light.ttf
new file mode 100644
index 00000000..0d381897
--- /dev/null
+++ b/src/extras/Styles/Flat/fonts/OpenSans-Light.ttf
Binary files differ
diff --git a/src/extras/Styles/Flat/fonts/OpenSans-Regular.ttf b/src/extras/Styles/Flat/fonts/OpenSans-Regular.ttf
new file mode 100644
index 00000000..db433349
--- /dev/null
+++ b/src/extras/Styles/Flat/fonts/OpenSans-Regular.ttf
Binary files differ
diff --git a/src/extras/Styles/Flat/fonts/OpenSans-Semibold.ttf b/src/extras/Styles/Flat/fonts/OpenSans-Semibold.ttf
new file mode 100644
index 00000000..1a7679e3
--- /dev/null
+++ b/src/extras/Styles/Flat/fonts/OpenSans-Semibold.ttf
Binary files differ
diff --git a/src/extras/Styles/Flat/images/BusyIndicator_Normal-Large.png b/src/extras/Styles/Flat/images/BusyIndicator_Normal-Large.png
new file mode 100644
index 00000000..6f9e6e25
--- /dev/null
+++ b/src/extras/Styles/Flat/images/BusyIndicator_Normal-Large.png
Binary files differ
diff --git a/src/extras/Styles/Flat/images/BusyIndicator_Normal-Medium.png b/src/extras/Styles/Flat/images/BusyIndicator_Normal-Medium.png
new file mode 100644
index 00000000..2922e2a3
--- /dev/null
+++ b/src/extras/Styles/Flat/images/BusyIndicator_Normal-Medium.png
Binary files differ
diff --git a/src/extras/Styles/Flat/images/BusyIndicator_Normal-Small.png b/src/extras/Styles/Flat/images/BusyIndicator_Normal-Small.png
new file mode 100644
index 00000000..c1e1b1f1
--- /dev/null
+++ b/src/extras/Styles/Flat/images/BusyIndicator_Normal-Small.png
Binary files differ
diff --git a/src/extras/Styles/Flat/qmldir b/src/extras/Styles/Flat/qmldir
new file mode 100644
index 00000000..2b6390a4
--- /dev/null
+++ b/src/extras/Styles/Flat/qmldir
@@ -0,0 +1,3 @@
+module QtQuick.Controls.Styles.Flat
+plugin qtquickextrasflatplugin
+classname QtQuickExtrasFlatPlugin
diff --git a/src/extras/Styles/Flat/qquicktexthandle.cpp b/src/extras/Styles/Flat/qquicktexthandle.cpp
new file mode 100644
index 00000000..57029b8f
--- /dev/null
+++ b/src/extras/Styles/Flat/qquicktexthandle.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquicktexthandle.h"
+
+QQuickTextHandle::QQuickTextHandle(QQuickItem *parent) :
+ QQuickPaintedItem(parent)
+{
+ setAntialiasing(true);
+}
+
+QQuickTextHandle::~QQuickTextHandle()
+{
+}
+
+void QQuickTextHandle::paint(QPainter *painter)
+{
+ painter->save();
+ paintBulb(painter, QColor(0, 0, 0, 38), true);
+ painter->restore();
+
+ paintBulb(painter, mColor, false);
+ painter->fillRect((mType == SelectionHandle ? 10 : 1), 0, 2, 23, mColor);
+}
+
+QQuickTextHandle::TextHandleType QQuickTextHandle::type() const
+{
+ return mType;
+}
+
+void QQuickTextHandle::setType(QQuickTextHandle::TextHandleType type)
+{
+ if (mType != type) {
+ mType = type;
+ update();
+ emit typeChanged();
+ }
+}
+
+QColor QQuickTextHandle::color() const
+{
+ return mColor;
+}
+
+void QQuickTextHandle::setColor(const QColor &color)
+{
+ if (mColor != color) {
+ mColor = color;
+ update();
+ emit colorChanged();
+ }
+}
+
+qreal QQuickTextHandle::scaleFactor() const
+{
+ return mScaleFactor;
+}
+
+void QQuickTextHandle::setScaleFactor(qreal scaleFactor)
+{
+ if (mScaleFactor != scaleFactor) {
+ mScaleFactor = scaleFactor;
+ setImplicitWidth(qRound(28 * mScaleFactor));
+ // + 2 for shadows
+ setImplicitHeight(qRound((32 + 2) * mScaleFactor));
+ update();
+ emit scaleFactorChanged();
+ }
+}
+
+void QQuickTextHandle::paintBulb(QPainter *painter, const QColor &color, bool isShadow)
+{
+ painter->scale(mScaleFactor, mScaleFactor);
+ QPainterPath path;
+
+ if (mType == SelectionHandle) {
+ painter->translate(16, isShadow ? 2 : 0);
+ path.moveTo(10.242, 28.457);
+ path.cubicTo(7.8980000000000015, 30.799, 4.099000000000001, 30.799,1.7560000000000002, 28.457);
+ path.cubicTo(-0.5859999999999999, 26.115000000000002, -0.5859999999999999,22.314, 1.7560000000000002, 19.973);
+ path.cubicTo(4.748, 16.980999999999998, 11.869, 18.343999999999998, 11.869, 18.343999999999998);
+ path.cubicTo(11.869, 18.343999999999998, 13.244, 25.455, 10.242, 28.457);
+
+ } else {
+ if (isShadow)
+ painter->translate(0, 2);
+ path.moveTo(2.757,28.457);
+ path.cubicTo(5.101,30.799,8.899000000000001,30.799,11.243,28.457);
+ path.cubicTo(13.585,26.115000000000002,13.585,22.314,11.243,19.973);
+ path.cubicTo(8.251,16.98,1.13,18.344,1.13,18.344);
+ path.cubicTo(1.13,18.344,-0.245,25.455,2.757,28.457);
+ }
+
+ painter->fillPath(path, QBrush(color));
+}
+
diff --git a/src/extras/Styles/Flat/qquicktexthandle.h b/src/extras/Styles/Flat/qquicktexthandle.h
new file mode 100644
index 00000000..4df6d42d
--- /dev/null
+++ b/src/extras/Styles/Flat/qquicktexthandle.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKTEXTHANDLE_H
+#define QQUICKTEXTHANDLE_H
+
+#include <QPainter>
+#include <QQuickPaintedItem>
+
+class QQuickTextHandle : public QQuickPaintedItem
+{
+ Q_OBJECT
+ Q_PROPERTY(TextHandleType type READ type WRITE setType NOTIFY typeChanged)
+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+ Q_PROPERTY(qreal scaleFactor READ scaleFactor WRITE setScaleFactor NOTIFY scaleFactorChanged)
+ Q_ENUMS(TextHandleType)
+public:
+ enum TextHandleType {
+ CursorHandle = 0,
+ SelectionHandle = 1
+ };
+
+ QQuickTextHandle(QQuickItem *parent = 0);
+ ~QQuickTextHandle();
+
+ void paint(QPainter *painter) Q_DECL_OVERRIDE;
+
+ TextHandleType type() const;
+ void setType(TextHandleType type);
+
+ QColor color() const;
+ void setColor(const QColor &color);
+
+ qreal scaleFactor() const;
+ void setScaleFactor(qreal scaleFactor);
+
+Q_SIGNALS:
+ void typeChanged();
+ void colorChanged();
+ void scaleFactorChanged();
+
+private:
+ void paintBulb(QPainter *painter, const QColor &color, bool isShadow);
+
+ TextHandleType mType;
+ QColor mColor;
+ qreal mScaleFactor;
+};
+
+#endif // QQUICKTEXTHANDLE_H
diff --git a/src/extras/Styles/styles.pro b/src/extras/Styles/styles.pro
new file mode 100644
index 00000000..8f05bcd0
--- /dev/null
+++ b/src/extras/Styles/styles.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+
+SUBDIRS += Base \
+ Flat
diff --git a/src/extras/ToggleButton.qml b/src/extras/ToggleButton.qml
new file mode 100644
index 00000000..8e0d313e
--- /dev/null
+++ b/src/extras/ToggleButton.qml
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private 1.0
+
+/*!
+ \qmltype ToggleButton
+ \inqmlmodule QtQuick.Extras
+ \since QtQuick.Extras 1.0
+ \ingroup extras
+ \ingroup extras-interactive
+ \brief A push button that toggles between two states.
+
+ \image togglebutton-unchecked.png An unchecked ToggleButton
+ An unchecked ToggleButton.
+ \image togglebutton-checked.png A checked ToggleButton
+ A checked ToggleButton.
+
+ The ToggleButton is a simple extension of Qt Quick Controls' Button, using
+ the checked property to toggle between two states: \e checked and
+ \e unchecked. It enhances the visibility of a checkable button's state by
+ placing color-coded indicators around the button.
+
+ You can create a custom appearance for a ToggleButton by assigning a
+ \l {QtQuick.Extras.Styles::}{ToggleButtonStyle}.
+*/
+
+Button {
+ id: button
+ checkable: true
+ style: Qt.createComponent(StyleSettings.style + "/ToggleButtonStyle.qml", button)
+}
diff --git a/src/extras/Tumbler.qml b/src/extras/Tumbler.qml
new file mode 100644
index 00000000..cdf21c4d
--- /dev/null
+++ b/src/extras/Tumbler.qml
@@ -0,0 +1,464 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Private 1.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Layouts 1.0
+
+/*!
+ \qmltype Tumbler
+ \inqmlmodule QtQuick.Extras
+ \since QtQuick.Extras 1.2
+ \ingroup extras
+ \ingroup extras-interactive
+ \brief A control that can have several spinnable wheels, each with items
+ that can be selected.
+
+ \image tumbler.png A Tumbler
+
+ \note Tumbler requires Qt 5.3.2 or later.
+
+ The Tumbler control is used with one or more TumblerColumn items, which
+ define the content of each column:
+
+ \code
+ Tumbler {
+ TumblerColumn {
+ model: 5
+ }
+ TumblerColumn {
+ model: [0, 1, 2, 3, 4]
+ }
+ TumblerColumn {
+ model: ["A", "B", "C", "D", "E]
+ }
+ }
+ \endcode
+
+ You can also use a traditional model with roles:
+
+ \code
+ Rectangle {
+ width: 220
+ height: 350
+ color: "#494d53"
+
+ ListModel {
+ id: listModel
+
+ ListElement {
+ foo: "A"
+ bar: "B"
+ baz: "C"
+ }
+ ListElement {
+ foo: "A"
+ bar: "B"
+ baz: "C"
+ }
+ ListElement {
+ foo: "A"
+ bar: "B"
+ baz: "C"
+ }
+ }
+
+ Tumbler {
+ anchors.centerIn: parent
+
+ TumblerColumn {
+ model: listModel
+ role: "foo"
+ }
+ TumblerColumn {
+ model: listModel
+ role: "bar"
+ }
+ TumblerColumn {
+ model: listModel
+ role: "baz"
+ }
+ }
+ }
+ \endcode
+
+ \section1 Limitations
+
+ For technical reasons, the model count must be equal to or greater than
+ \l {QtQuick.Extras.Styles::TumblerStyle}{visibleItemCount}
+ plus one. The
+ \l {QtQuick.Extras.Styles::TumblerStyle::}{visibleItemCount}
+ must also be an odd number.
+
+ You can create a custom appearance for a Tumbler by assigning a
+ \l {QtQuick.Extras.Styles::}{TumblerStyle}. To style
+ individual columns, use the \l {TumblerColumn::delegate}{delegate} and
+ \l {TumblerColumn::highlight}{highlight} properties of TumblerColumn.
+*/
+
+Control {
+ id: tumbler
+
+ style: Qt.createComponent(StyleSettings.style + "/TumblerStyle.qml", tumbler)
+
+ ListModel {
+ id: columnModel
+ }
+
+ /*!
+ \qmlproperty int Tumbler::columnCount
+
+ The number of columns in the Tumbler.
+ */
+ readonly property alias columnCount: columnModel.count
+
+ /*! \internal */
+ function __isValidColumnIndex(index) {
+ return index >= 0 && index < columnCount/* && columnRepeater.children.length === columnCount*/;
+ }
+
+ /*! \internal */
+ function __isValidColumnAndItemIndex(columnIndex, itemIndex) {
+ return __isValidColumnIndex(columnIndex) && itemIndex >= 0 && itemIndex < __viewAt(columnIndex).count;
+ }
+
+ /*!
+ Returns the current index of the column at \a columnIndex, or \c null
+ if the \a index is invalid.
+ */
+ function currentIndexAt(columnIndex) {
+ if (!__isValidColumnIndex(columnIndex))
+ return -1;
+
+ return columnModel.get(columnIndex).columnObject.currentIndex;
+ }
+
+ /*!
+ Sets the current index of the column at \a columnIndex to \a itemIndex.
+
+ Does nothing if \a columnIndex or \a itemIndex are invalid.
+ */
+ function setCurrentIndexAt(columnIndex, itemIndex) {
+ if (!__isValidColumnAndItemIndex(columnIndex, itemIndex))
+ return;
+
+ var view = columnRepeater.itemAt(columnIndex).view;
+ if (view.currentIndex !== itemIndex) {
+ // Hack to work around the pathview jumping when the index is changed.
+ // TODO: doesn't seem to be necessary anymore?
+ view.highlightMoveDuration = 0;
+ view.currentIndex = itemIndex;
+ view.highlightMoveDuration = Qt.binding(function(){ return __highlightMoveDuration; });
+ }
+ }
+
+ /*!
+ Returns the column at \a columnIndex or \c null if the \a index is
+ invalid.
+ */
+ function getColumn(columnIndex) {
+ if (!__isValidColumnIndex(columnIndex))
+ return null;
+
+ return columnModel.get(columnIndex).columnObject;
+ }
+
+ /*!
+ Adds a \a column and returns the added column.
+
+ The \a column argument can be an instance of TumblerColumn,
+ or a Component. The component has to contain a TumblerColumn.
+ Otherwise \c null is returned.
+ */
+ function addColumn(column) {
+ return insertColumn(columnCount, column);
+ }
+
+ /*!
+ Inserts a \a column at the given \a index and returns the inserted column.
+
+ The \a column argument can be an instance of TumblerColumn,
+ or a Component. The component has to contain a TumblerColumn.
+ Otherwise, \c null is returned.
+ */
+ function insertColumn(index, column) {
+ var object = column;
+ if (typeof column["createObject"] === "function") {
+ object = column.createObject(root);
+ } else if (object.__tumbler) {
+ console.warn("Tumbler::insertColumn(): you cannot add a column to multiple Tumblers")
+ return null;
+ }
+ if (index >= 0 && index <= columnCount && object.Accessible.role === Accessible.ColumnHeader) {
+ object.__tumbler = tumbler;
+ object.__index = index;
+ columnModel.insert(index, { columnObject: object });
+ return object;
+ }
+
+ if (object !== column)
+ object.destroy();
+ console.warn("Tumbler::insertColumn(): invalid argument");
+ return null;
+ }
+
+ /*
+ Try making one selection bar by invisible highlight item hack, so that bars go across separators
+ */
+
+ Component.onCompleted: {
+ for (var i = 0; i < data.length; ++i) {
+ var column = data[i];
+ if (column.Accessible.role === Accessible.ColumnHeader)
+ addColumn(column);
+ }
+ }
+
+ /*! \internal */
+ readonly property alias __columnRow: columnRow
+ /*! \internal */
+ property int __highlightMoveDuration: 300
+
+ /*! \internal */
+ function __viewAt(index) {
+ if (!__isValidColumnIndex(index))
+ return null;
+
+ return columnRepeater.itemAt(index).view;
+ }
+
+ /*! \internal */
+ readonly property alias __movementDelayTimer: movementDelayTimer
+
+ // When the up/down arrow keys are held down on a PathView,
+ // the movement of the items is limited to the highlightMoveDuration,
+ // but there is no built-in guard against trying to move the items at
+ // the speed of the auto-repeat key presses. This results in sluggish
+ // movement, so we enforce a delay with a timer to avoid this.
+ Timer {
+ id: movementDelayTimer
+ interval: __highlightMoveDuration
+ }
+
+ Loader {
+ id: backgroundLoader
+ sourceComponent: __style.background
+ anchors.fill: columnRow
+ }
+
+ Loader {
+ id: frameLoader
+ sourceComponent: __style.frame
+ anchors.fill: columnRow
+ anchors.leftMargin: -__style.padding.left
+ anchors.rightMargin: -__style.padding.right
+ anchors.topMargin: -__style.padding.top
+ anchors.bottomMargin: -__style.padding.bottom
+ }
+
+ Row {
+ id: columnRow
+ x: __style.padding.left
+ y: __style.padding.top
+
+ Repeater {
+ id: columnRepeater
+ model: columnModel
+ delegate: Item {
+ id: columnItem
+ width: columnPathView.width + separatorDelegateLoader.width
+ height: columnPathView.height
+
+ readonly property int __columnIndex: index
+ // For index-related functions and tests.
+ readonly property alias view: columnPathView
+ readonly property alias separator: separatorDelegateLoader.item
+
+ PathView {
+ id: columnPathView
+ width: columnObject.width
+ height: tumbler.height - tumbler.__style.padding.top - tumbler.__style.padding.bottom
+ visible: columnObject.visible
+ clip: true
+
+ Binding {
+ target: columnObject
+ property: "__currentIndex"
+ value: columnPathView.currentIndex
+ }
+
+ // We add one here so that the delegate's don't just appear in the view instantly,
+ // but rather come from the top/bottom. To account for this adjustment elsewhere,
+ // we extend the path height by half an item's height at the top and bottom.
+ pathItemCount: tumbler.__style.visibleItemCount + 1
+ preferredHighlightBegin: 0.5
+ preferredHighlightEnd: 0.5
+ highlightMoveDuration: tumbler.__highlightMoveDuration
+ highlight: Loader {
+ id: highlightLoader
+ objectName: "highlightLoader"
+ sourceComponent: columnObject.highlight ? columnObject.highlight : __style.highlight
+ width: columnPathView.width
+
+ readonly property int __index: index
+
+ property QtObject styleData: QtObject {
+ readonly property alias index: highlightLoader.__index
+ readonly property int column: columnItem.__columnIndex
+ readonly property bool activeFocus: columnPathView.activeFocus
+ }
+ }
+ dragMargin: width / 2
+
+ activeFocusOnTab: true
+ Keys.onDownPressed: {
+ if (!movementDelayTimer.running) {
+ columnPathView.incrementCurrentIndex();
+ movementDelayTimer.start();
+ }
+ }
+ Keys.onUpPressed: {
+ if (!movementDelayTimer.running) {
+ columnPathView.decrementCurrentIndex();
+ movementDelayTimer.start();
+ }
+ }
+
+ path: Path {
+ startX: columnPathView.width / 2
+ startY: -tumbler.__style.__delegateHeight / 2
+ PathLine {
+ x: columnPathView.width / 2
+ y: columnPathView.pathItemCount * tumbler.__style.__delegateHeight - tumbler.__style.__delegateHeight / 2
+ }
+ }
+
+ model: columnObject.model
+
+ delegate: Item {
+ id: delegateRootItem
+ property var itemModel: model
+
+ implicitWidth: itemDelegateLoader.width
+ implicitHeight: itemDelegateLoader.height
+
+ Loader {
+ id: itemDelegateLoader
+ sourceComponent: columnObject.delegate ? columnObject.delegate : __style.delegate
+ width: columnObject.width
+
+ onHeightChanged: tumbler.__style.__delegateHeight = height;
+
+ property var model: itemModel
+
+ readonly property var __modelData: modelData
+ readonly property int __columnDelegateIndex: index
+ property QtObject styleData: QtObject {
+ readonly property var modelData: itemDelegateLoader.__modelData
+ readonly property alias index: itemDelegateLoader.__columnDelegateIndex
+ readonly property int column: columnItem.__columnIndex
+ readonly property bool activeFocus: columnPathView.activeFocus
+ readonly property real displacement: {
+ var count = delegateRootItem.PathView.view.count;
+ var offset = delegateRootItem.PathView.view.offset;
+
+ var d = count - index - offset;
+ var halfVisibleItems = Math.floor(tumbler.__style.visibleItemCount / 2) + 1;
+ if (d > halfVisibleItems)
+ d -= count;
+ else if (d < -halfVisibleItems)
+ d += count;
+ return d;
+ }
+ readonly property bool current: delegateRootItem.PathView.isCurrentItem
+ readonly property string role: columnObject.role
+ readonly property var value: (itemModel && itemModel.hasOwnProperty(role))
+ ? itemModel[role] // Qml ListModel and QAbstractItemModel
+ : modelData && modelData.hasOwnProperty(role)
+ ? modelData[role] // QObjectList/QObject
+ : modelData != undefined ? modelData : "" // Models without role
+ }
+ }
+ }
+ }
+
+ Loader {
+ anchors.fill: columnPathView
+ sourceComponent: columnObject.columnForeground ? columnObject.columnForeground : __style.columnForeground
+
+ property QtObject styleData: QtObject {
+ readonly property int column: columnItem.__columnIndex
+ readonly property bool activeFocus: columnPathView.activeFocus
+ }
+ }
+
+ Loader {
+ id: separatorDelegateLoader
+ objectName: "separatorDelegateLoader"
+ sourceComponent: __style.separator
+ // Don't need a separator after the last delegate.
+ active: __columnIndex < tumbler.columnCount - 1
+ anchors.left: columnPathView.right
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ visible: columnObject.visible
+
+ // Use the width of the first separator to help us
+ // determine the default separator width.
+ onWidthChanged: {
+ if (__columnIndex == 0) {
+ tumbler.__style.__separatorWidth = width;
+ }
+ }
+
+ property QtObject styleData: QtObject {
+ readonly property int index: __columnIndex
+ }
+ }
+ }
+ }
+ }
+
+ Loader {
+ id: foregroundLoader
+ sourceComponent: __style.foreground
+ anchors.fill: backgroundLoader
+ }
+}
diff --git a/src/extras/TumblerColumn.qml b/src/extras/TumblerColumn.qml
new file mode 100644
index 00000000..95bcae85
--- /dev/null
+++ b/src/extras/TumblerColumn.qml
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Private 1.0
+
+/*!
+ \qmltype TumblerColumn
+ \inqmlmodule QtQuick.Extras
+ \since QtQuick.Extras 1.2
+ \ingroup extras
+ \brief A column within a tumbler.
+
+ \note TumblerColumn requires Qt 5.3.2 or later.
+
+ TumblerColumn represents a column within a tumbler, providing the interface
+ to define the items and width of each column.
+
+ \code
+ Tumbler {
+ TumblerColumn {
+ model: [1, 2, 3]
+ }
+
+ TumblerColumn {
+ model: ["A", "B", "C"]
+ visible: false
+ }
+ }
+ \endcode
+
+ You can create a custom appearance for a Tumbler by assigning a
+ \l {QtQuick.Extras.Styles::}{TumblerStyle}.
+*/
+
+QtObject {
+ id: tumblerColumn
+
+ /*! \internal */
+ property Item __tumbler: null
+
+ /*!
+ \internal
+
+ The index of this column within the tumbler.
+ */
+ property int __index: -1
+
+ /*!
+ \internal
+
+ The index of the current item, if the PathView has items instantiated,
+ or the last current index if it doesn't.
+ */
+ property int __currentIndex: -1
+
+ Accessible.role: Accessible.ColumnHeader
+
+ /*!
+ \qmlproperty readonly int TumblerColumn::currentIndex
+
+ This read-only property holds the index of the current item for this
+ column. If the model count is reduced, the current index will be
+ reduced to the new count minus one.
+
+ \sa {Tumbler::currentIndexAt}, {Tumbler::setCurrentIndexAt}
+ */
+ readonly property alias currentIndex: tumblerColumn.__currentIndex
+
+ /*!
+ This property holds the model that provides data for this column.
+ */
+ property var model: null
+
+ /*!
+ This property holds the model role of this column.
+ */
+ property string role: ""
+
+ /*!
+ The item delegate for this column.
+
+ If set, this delegate will be used to display items in this column,
+ instead of the
+ \l {QtQuick.Extras.Styles::TumblerStyle::delegate}{delegate}
+ property in \l {QtQuick.Extras.Styles::}{TumblerStyle}.
+
+ The \l {Item::implicitHeight}{implicitHeight} property must be set,
+ and it must be the same for each delegate.
+ */
+ property Component delegate
+
+ /*!
+ The highlight delegate for this column.
+
+ If set, this highlight will be used to display the highlight in this
+ column, instead of the
+ \l {QtQuick.Extras.Styles::TumblerStyle::highlight}{highlight}
+ property in \l {QtQuick.Extras.Styles::}{TumblerStyle}.
+ */
+ property Component highlight
+
+ /*!
+ The foreground of this column.
+
+ If set, this component will be used to display the foreground in this
+ column, instead of the
+ \l {QtQuick.Extras.Styles::TumblerStyle::columnForeground}{columnForeground}
+ property in \l {QtQuick.Extras.Styles::}{TumblerStyle}.
+ */
+ property Component columnForeground
+
+ /*!
+ This property holds the visibility of this column.
+ */
+ property bool visible: true
+
+ /*!
+ This read-only property indicates whether the item has active focus.
+
+ See Item's \l {Item::activeFocus}{activeFocus} property for more
+ information.
+ */
+ readonly property bool activeFocus: {
+ if (__tumbler === null)
+ return null;
+
+ var view = __tumbler.__viewAt(__index);
+ return view && view.activeFocus ? true : false;
+ }
+
+ /*!
+ This property holds the width of this column.
+ */
+ property real width: TextSingleton.implicitHeight * 4
+}
diff --git a/src/extras/designer/CircularGaugeSpecifics.qml b/src/extras/designer/CircularGaugeSpecifics.qml
new file mode 100644
index 00000000..0be31366
--- /dev/null
+++ b/src/extras/designer/CircularGaugeSpecifics.qml
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import HelperWidgets 2.0
+import QtQuick.Layouts 1.0
+
+Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Section {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("CircularGauge")
+
+ SectionLayout {
+ Label {
+ text: qsTr("Value")
+ tooltip: qsTr("Value")
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.value
+ minimumValue: backendValues.minimumValue.value
+ maximumValue: backendValues.maximumValue.value
+ }
+ ExpandingSpacer {
+ }
+ }
+
+ Label {
+ text: qsTr("Minimum Value")
+ tooltip: qsTr("Minimum Value")
+ }
+ SecondColumnLayout {
+ SpinBox {
+ id: minimumValueSpinBox
+ backendValue: backendValues.minimumValue
+ minimumValue: 0
+ maximumValue: backendValues.maximumValue.value
+ }
+ ExpandingSpacer {
+ }
+ }
+
+ Label {
+ text: qsTr("Maximum Value")
+ tooltip: qsTr("Maximum Value")
+ }
+ SecondColumnLayout {
+ SpinBox {
+ id: maximumValueSpinBox
+ backendValue: backendValues.maximumValue
+ minimumValue: backendValues.minimumValue.value
+ maximumValue: 1000
+ }
+ ExpandingSpacer {
+ }
+ }
+
+ Label {
+ text: qsTr("Step Size")
+ tooltip: qsTr("Step Size")
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.stepSize
+ minimumValue: 0
+ maximumValue: backendValues.maximumValue.value
+ }
+ ExpandingSpacer {
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/extras/designer/DelayButtonSpecifics.qml b/src/extras/designer/DelayButtonSpecifics.qml
new file mode 100644
index 00000000..06dc9daa
--- /dev/null
+++ b/src/extras/designer/DelayButtonSpecifics.qml
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import HelperWidgets 2.0
+import QtQuick.Layouts 1.0
+
+Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Section {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("DelayButton")
+
+ SectionLayout {
+ Label {
+ text: qsTr("Text")
+ tooltip: qsTr("Text")
+ }
+ SecondColumnLayout {
+ LineEdit {
+ backendValue: backendValues.text
+ showTranslateCheckBox: true
+ implicitWidth: 180
+ }
+ ExpandingSpacer {
+ }
+ }
+
+// Label {
+// text: qsTr("Disable Button")
+// tooltip: qsTr("Disable Button")
+// }
+// SecondColumnLayout {
+// CheckBox {
+// backendValue: backendValues.disabled
+// implicitWidth: 180
+// }
+// ExpandingSpacer {
+// }
+// }
+
+ Label {
+ text: qsTr("Delay")
+ tooltip: qsTr("Delay")
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.delay
+ minimumValue: 0
+ maximumValue: 60000
+ }
+ ExpandingSpacer {
+ }
+ }
+ }
+ }
+}
diff --git a/src/extras/designer/DialSpecifics.qml b/src/extras/designer/DialSpecifics.qml
new file mode 100644
index 00000000..b68e6e04
--- /dev/null
+++ b/src/extras/designer/DialSpecifics.qml
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import HelperWidgets 2.0
+import QtQuick.Layouts 1.0
+
+Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Section {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("Dial")
+
+ SectionLayout {
+ Label {
+ text: qsTr("Value")
+ tooltip: qsTr("Value")
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.value
+ minimumValue: backendValues.minimumValue.value
+ maximumValue: backendValues.maximumValue.value
+ stepSize: 0.01
+ decimals: 2
+ }
+ ExpandingSpacer {
+ }
+ }
+
+ Label {
+ text: qsTr("Minimum Value")
+ tooltip: qsTr("Minimum Value")
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.minimumValue
+ minimumValue: -1000
+ maximumValue: backendValues.maximumValue.value
+ stepSize: 0.01
+ decimals: 2
+ }
+ ExpandingSpacer {
+ }
+ }
+
+ Label {
+ text: qsTr("Maximum Value")
+ tooltip: qsTr("Maximum Value")
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.maximumValue
+ minimumValue: backendValues.minimumValue.value
+ maximumValue: 1000
+ stepSize: 0.01
+ decimals: 2
+ }
+ ExpandingSpacer {
+ }
+ }
+
+ Label {
+ text: qsTr("Step Size")
+ tooltip: qsTr("Step Size")
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.stepSize
+ minimumValue: 0
+ maximumValue: backendValues.maximumValue.value
+ stepSize: 0.01
+ decimals: 2
+ }
+ ExpandingSpacer {
+ }
+ }
+
+ Label {
+ text: qsTr("Tickmarks Visible")
+ tooltip: qsTr("Tickmarks Visible")
+ }
+ SecondColumnLayout {
+ CheckBox {
+ backendValue: backendValues.tickmarksVisible
+ }
+ ExpandingSpacer {
+ }
+ }
+ }
+ }
+}
diff --git a/src/extras/designer/GaugeSpecifics.qml b/src/extras/designer/GaugeSpecifics.qml
new file mode 100644
index 00000000..13febbdd
--- /dev/null
+++ b/src/extras/designer/GaugeSpecifics.qml
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import HelperWidgets 2.0
+import QtQuick.Layouts 1.0
+
+Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Section {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("Gauge")
+
+ SectionLayout {
+
+ Label {
+ text: qsTr("Value")
+ tooltip: qsTr("Value")
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.value
+ minimumValue: backendValues.minimumValue.value
+ maximumValue: backendValues.maximumValue.value
+ stepSize: 0.01
+ decimals: 2
+ }
+ ExpandingSpacer {
+ }
+ }
+
+ Label {
+ text: qsTr("Minimum Value")
+ tooltip: qsTr("Minimum Value")
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.minimumValue
+ minimumValue: 0
+ maximumValue: backendValues.maximumValue.value
+ stepSize: 0.01
+ decimals: 2
+ }
+ ExpandingSpacer {
+ }
+ }
+
+ Label {
+ text: qsTr("Maximum Value")
+ tooltip: qsTr("Maximum Value")
+ }
+ SecondColumnLayout {
+ SpinBox {
+ backendValue: backendValues.maximumValue
+ minimumValue: backendValues.minimumValue.value
+ maximumValue: 1000
+ stepSize: 0.01
+ decimals: 2
+ }
+ ExpandingSpacer {
+ }
+ }
+
+// Label {
+// text: qsTr("Orientation")
+// tooltip: qsTr("Orientation")
+// }
+// SecondColumnLayout {
+// ComboBox {
+// id: orientationComboBox
+// backendValue: backendValues.orientation
+// implicitWidth: 180
+// model: ["Vertical", "Horizontal"]
+// }
+// ExpandingSpacer {
+// }
+// }
+
+// Label {
+// text: qsTr("Tickmark Alignment")
+// tooltip: qsTr("Tickmark Alignment")
+// }
+
+// SecondColumnLayout {
+// ComboBox {
+// backendValue: backendValues.orientation
+// implicitWidth: 180
+// model: orientationComboBox.currentText === "Vertical" ? ["AlignLeft", "AlignRight"] : ["AlignTop", "AlignBottom"]
+// }
+// ExpandingSpacer {
+// }
+// }
+ }
+ }
+}
diff --git a/src/extras/designer/PictureSpecifics.qml b/src/extras/designer/PictureSpecifics.qml
new file mode 100644
index 00000000..538614e4
--- /dev/null
+++ b/src/extras/designer/PictureSpecifics.qml
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import HelperWidgets 2.0
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.1 as Controls
+import QtQuick.Controls.Styles 1.1
+
+Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Section {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("Picture")
+
+ SectionLayout {
+ Label {
+ text: qsTr("Source")
+ toolTip: qsTr("Source")
+ }
+ SecondColumnLayout {
+ LineEdit {
+ backendValue: backendValues.source
+ showTranslateCheckBox: false
+ implicitWidth: 180
+ }
+ ExpandingSpacer {
+ }
+ }
+ }
+ }
+ Section {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("Color")
+
+ ColorEditor {
+ caption: qsTr("Color")
+ backendValue: backendValues.color
+ supportGradient: false
+ }
+ }
+}
+
diff --git a/src/extras/designer/PieMenuSpecifics.qml b/src/extras/designer/PieMenuSpecifics.qml
new file mode 100644
index 00000000..b6c9d325
--- /dev/null
+++ b/src/extras/designer/PieMenuSpecifics.qml
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import HelperWidgets 2.0
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.1 as Controls
+import QtQuick.Controls.Styles 1.1
+
+Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Section {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("PieMenu")
+
+ SectionLayout {
+ Label {
+ text: qsTr("Trigger Mode")
+ tooltip: qsTr("Trigger Mode")
+ }
+ SecondColumnLayout {
+ // Work around ComboBox string => int problem.
+ Controls.ComboBox {
+ id: comboBox
+
+ property variant backendValue: backendValues.triggerMode
+
+ property color textColor: "white"
+ implicitWidth: 180
+ model: ["TriggerOnPress", "TriggerOnRelease", "TriggerOnClick"]
+
+ QtObject {
+ property variant valueFromBackend: comboBox.backendValue
+ onValueFromBackendChanged: {
+ comboBox.currentIndex = comboBox.find(comboBox.backendValue.valueToString);
+ }
+ }
+
+ onCurrentTextChanged: {
+ if (backendValue === undefined)
+ return;
+
+ if (backendValue.value !== currentText)
+ backendValue.value = comboBox.currentIndex
+ }
+
+ style: CustomComboBoxStyle {
+ textColor: comboBox.textColor
+ }
+
+ ExtendedFunctionButton {
+ x: 2
+ y: 4
+ backendValue: comboBox.backendValue
+ visible: comboBox.enabled
+ }
+ }
+ ExpandingSpacer {
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/extras/designer/StatusIndicatorSpecifics.qml b/src/extras/designer/StatusIndicatorSpecifics.qml
new file mode 100644
index 00000000..b2a43362
--- /dev/null
+++ b/src/extras/designer/StatusIndicatorSpecifics.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import HelperWidgets 2.0
+import QtQuick.Layouts 1.0
+
+Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Section {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("StatusIndicator")
+
+ SectionLayout {
+ Label {
+ text: qsTr("Active")
+ tooltip: qsTr("Active")
+ }
+ SecondColumnLayout {
+ CheckBox {
+ backendValue: backendValues.active
+ implicitWidth: 100
+ }
+ ExpandingSpacer {
+ }
+ }
+ }
+ }
+ Section {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("Color")
+
+ ColorEditor {
+ caption: qsTr("Color")
+ backendValue: backendValues.color
+ supportGradient: false
+ }
+ }
+}
diff --git a/src/extras/designer/ToggleButtonSpecifics.qml b/src/extras/designer/ToggleButtonSpecifics.qml
new file mode 100644
index 00000000..abb0d06d
--- /dev/null
+++ b/src/extras/designer/ToggleButtonSpecifics.qml
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import HelperWidgets 2.0
+import QtQuick.Layouts 1.0
+
+Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Section {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("ToggleButton")
+
+ SectionLayout {
+ Label {
+ text: qsTr("Text")
+ tooltip: qsTr("Text")
+ }
+ SecondColumnLayout {
+ LineEdit {
+ backendValue: backendValues.text
+ showTranslateCheckBox: true
+ implicitWidth: 180
+ }
+ ExpandingSpacer {
+ }
+ }
+
+// Label {
+// text: qsTr("Disable Button")
+// tooltip: qsTr("Disable Button")
+// }
+// SecondColumnLayout {
+// CheckBox {
+// backendValue: backendValues.disabled
+// implicitWidth: 180
+// }
+// ExpandingSpacer {
+// }
+// }
+
+ Label {
+ text: qsTr("Checked")
+ tooltip: qsTr("Checked")
+ }
+ SecondColumnLayout {
+ CheckBox {
+ backendValue: backendValues.checked
+ implicitWidth: 180
+ }
+ ExpandingSpacer {
+ }
+ }
+ }
+ }
+}
diff --git a/src/extras/designer/TumblerSpecifics.qml b/src/extras/designer/TumblerSpecifics.qml
new file mode 100644
index 00000000..8d3986aa
--- /dev/null
+++ b/src/extras/designer/TumblerSpecifics.qml
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import HelperWidgets 2.0
+import QtQuick.Layouts 1.0
+
+Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Section {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ caption: qsTr("Tumbler")
+ }
+}
diff --git a/src/extras/designer/designer.pri b/src/extras/designer/designer.pri
new file mode 100644
index 00000000..790e0c0f
--- /dev/null
+++ b/src/extras/designer/designer.pri
@@ -0,0 +1,33 @@
+QML_FILES += \
+ $$PWD/CircularGaugeSpecifics.qml \
+ $$PWD/DelayButtonSpecifics.qml \
+ $$PWD/DialSpecifics.qml \
+ $$PWD/GaugeSpecifics.qml \
+ $$PWD/PictureSpecifics.qml \
+ $$PWD/PieMenuSpecifics.qml \
+ $$PWD/StatusIndicatorSpecifics.qml \
+ $$PWD/ToggleButtonSpecifics.qml
+
+QML_FILES += $$PWD/qtquickextras.metainfo
+
+# Images
+QML_FILES += \
+ $$PWD/images/circulargauge-icon.png \
+ $$PWD/images/circulargauge-icon16.png \
+ $$PWD/images/delaybutton-icon.png \
+ $$PWD/images/delaybutton-icon16.png \
+ $$PWD/images/dial-icon.png \
+ $$PWD/images/dial-icon16.png \
+ $$PWD/images/gauge-icon.png \
+ $$PWD/images/gauge-icon16.png \
+ $$PWD/images/picture-icon.png \
+ $$PWD/images/picture-icon16.png \
+ $$PWD/images/piemenu-icon.png \
+ $$PWD/images/piemenu-icon16.png \
+ $$PWD/images/statusindicator-icon.png \
+ $$PWD/images/statusindicator-icon16.png \
+ $$PWD/images/togglebutton-icon.png \
+ $$PWD/images/togglebutton-icon16.png \
+ $$PWD/images/tumbler-icon.png \
+ $$PWD/images/tumbler-icon16.png
+
diff --git a/src/extras/designer/images/circulargauge-icon.png b/src/extras/designer/images/circulargauge-icon.png
new file mode 100644
index 00000000..9f8eaab2
--- /dev/null
+++ b/src/extras/designer/images/circulargauge-icon.png
Binary files differ
diff --git a/src/extras/designer/images/circulargauge-icon16.png b/src/extras/designer/images/circulargauge-icon16.png
new file mode 100644
index 00000000..cde29aeb
--- /dev/null
+++ b/src/extras/designer/images/circulargauge-icon16.png
Binary files differ
diff --git a/src/extras/designer/images/delaybutton-icon.png b/src/extras/designer/images/delaybutton-icon.png
new file mode 100644
index 00000000..8b421f55
--- /dev/null
+++ b/src/extras/designer/images/delaybutton-icon.png
Binary files differ
diff --git a/src/extras/designer/images/delaybutton-icon16.png b/src/extras/designer/images/delaybutton-icon16.png
new file mode 100644
index 00000000..f14b3f89
--- /dev/null
+++ b/src/extras/designer/images/delaybutton-icon16.png
Binary files differ
diff --git a/src/extras/designer/images/dial-icon.png b/src/extras/designer/images/dial-icon.png
new file mode 100644
index 00000000..2c1031c2
--- /dev/null
+++ b/src/extras/designer/images/dial-icon.png
Binary files differ
diff --git a/src/extras/designer/images/dial-icon16.png b/src/extras/designer/images/dial-icon16.png
new file mode 100644
index 00000000..df938396
--- /dev/null
+++ b/src/extras/designer/images/dial-icon16.png
Binary files differ
diff --git a/src/extras/designer/images/gauge-icon.png b/src/extras/designer/images/gauge-icon.png
new file mode 100644
index 00000000..3bcdf27b
--- /dev/null
+++ b/src/extras/designer/images/gauge-icon.png
Binary files differ
diff --git a/src/extras/designer/images/gauge-icon16.png b/src/extras/designer/images/gauge-icon16.png
new file mode 100644
index 00000000..eae1bc37
--- /dev/null
+++ b/src/extras/designer/images/gauge-icon16.png
Binary files differ
diff --git a/src/extras/designer/images/picture-icon.png b/src/extras/designer/images/picture-icon.png
new file mode 100644
index 00000000..0fc54462
--- /dev/null
+++ b/src/extras/designer/images/picture-icon.png
Binary files differ
diff --git a/src/extras/designer/images/picture-icon16.png b/src/extras/designer/images/picture-icon16.png
new file mode 100644
index 00000000..58335819
--- /dev/null
+++ b/src/extras/designer/images/picture-icon16.png
Binary files differ
diff --git a/src/extras/designer/images/piemenu-icon.png b/src/extras/designer/images/piemenu-icon.png
new file mode 100644
index 00000000..0bde71fb
--- /dev/null
+++ b/src/extras/designer/images/piemenu-icon.png
Binary files differ
diff --git a/src/extras/designer/images/piemenu-icon16.png b/src/extras/designer/images/piemenu-icon16.png
new file mode 100644
index 00000000..d7b6e03d
--- /dev/null
+++ b/src/extras/designer/images/piemenu-icon16.png
Binary files differ
diff --git a/src/extras/designer/images/statusindicator-icon.png b/src/extras/designer/images/statusindicator-icon.png
new file mode 100644
index 00000000..4a148262
--- /dev/null
+++ b/src/extras/designer/images/statusindicator-icon.png
Binary files differ
diff --git a/src/extras/designer/images/statusindicator-icon16.png b/src/extras/designer/images/statusindicator-icon16.png
new file mode 100644
index 00000000..df41baf2
--- /dev/null
+++ b/src/extras/designer/images/statusindicator-icon16.png
Binary files differ
diff --git a/src/extras/designer/images/togglebutton-icon.png b/src/extras/designer/images/togglebutton-icon.png
new file mode 100644
index 00000000..b57ac871
--- /dev/null
+++ b/src/extras/designer/images/togglebutton-icon.png
Binary files differ
diff --git a/src/extras/designer/images/togglebutton-icon16.png b/src/extras/designer/images/togglebutton-icon16.png
new file mode 100644
index 00000000..eb42b855
--- /dev/null
+++ b/src/extras/designer/images/togglebutton-icon16.png
Binary files differ
diff --git a/src/extras/designer/images/tumbler-icon.png b/src/extras/designer/images/tumbler-icon.png
new file mode 100644
index 00000000..f5d7c0d4
--- /dev/null
+++ b/src/extras/designer/images/tumbler-icon.png
Binary files differ
diff --git a/src/extras/designer/images/tumbler-icon16.png b/src/extras/designer/images/tumbler-icon16.png
new file mode 100644
index 00000000..4ac31735
--- /dev/null
+++ b/src/extras/designer/images/tumbler-icon16.png
Binary files differ
diff --git a/src/extras/designer/qtquickextras.metainfo b/src/extras/designer/qtquickextras.metainfo
new file mode 100644
index 00000000..20e02ffb
--- /dev/null
+++ b/src/extras/designer/qtquickextras.metainfo
@@ -0,0 +1,122 @@
+MetaInfo {
+ Type {
+ name: "QtQuick.Extras.DelayButton"
+ icon: "images/delaybutton-icon16.png"
+
+ ItemLibraryEntry {
+ name: "DelayButton"
+ category: "Qt Quick - Extras"
+ libraryIcon: "images/delaybutton-icon.png"
+ version: "1.0"
+ requiredImport: "QtQuick.Extras"
+
+ Property {
+ name: "text"
+ type: "binding"
+ value: "qsTr(\"Button\")"
+ }
+ }
+ }
+ Type {
+ name: "QtQuick.Extras.ToggleButton"
+ icon: "images/togglebutton-icon16.png"
+
+ ItemLibraryEntry {
+ name: "ToggleButton"
+ category: "Qt Quick - Extras"
+ libraryIcon: "images/togglebutton-icon.png"
+ version: "1.0"
+ requiredImport: "QtQuick.Extras"
+
+ Property {
+ name: "text"
+ type: "binding"
+ value: "qsTr(\"Button\")"
+ }
+ }
+ }
+ Type {
+ name: "QtQuick.Extras.Gauge"
+ icon: "images/gauge-icon16.png"
+
+ ItemLibraryEntry {
+ name: "Gauge"
+ category: "Qt Quick - Extras"
+ libraryIcon: "images/gauge-icon.png"
+ version: "1.0"
+ requiredImport: "QtQuick.Extras"
+ }
+ }
+ Type {
+ name: "QtQuick.Extras.CircularGauge"
+ icon: "images/circulargauge-icon16.png"
+
+ ItemLibraryEntry {
+ name: "CircularGauge"
+ category: "Qt Quick - Extras"
+ libraryIcon: "images/circulargauge-icon.png"
+ version: "1.0"
+ requiredImport: "QtQuick.Extras"
+ }
+ }
+ Type {
+ name: "QtQuick.Extras.PieMenu"
+ icon: "images/piemenu-icon16.png"
+
+ ItemLibraryEntry {
+ name: "PieMenu"
+ category: "Qt Quick - Extras"
+ libraryIcon: "images/piemenu-icon.png"
+ version: "1.0"
+ requiredImport: "QtQuick.Extras"
+ }
+ }
+ Type {
+ name: "QtQuick.Extras.Dial"
+ icon: "images/dial-icon16.png"
+
+ ItemLibraryEntry {
+ name: "Dial"
+ category: "Qt Quick - Extras"
+ libraryIcon: "images/dial-icon.png"
+ version: "1.0"
+ requiredImport: "QtQuick.Extras"
+ }
+ }
+ Type {
+ name: "QtQuick.Extras.StatusIndicator"
+ icon: "images/statusindicator-icon16.png"
+
+ ItemLibraryEntry {
+ name: "StatusIndicator"
+ category: "Qt Quick - Extras"
+ libraryIcon: "images/statusindicator-icon.png"
+ version: "1.1"
+ requiredImport: "QtQuick.Extras"
+ }
+ }
+ Type {
+ name: "QtQuick.Extras.Tumbler"
+ icon: "images/tumbler-icon16.png"
+
+ ItemLibraryEntry {
+ name: "Tumbler"
+ category: "Qt Quick - Extras"
+ libraryIcon: "images/tumbler-icon.png"
+ version: "1.2"
+ requiredImport: "QtQuick.Extras"
+ }
+ }
+ Type {
+ name: "QtQuick.Extras.Picture"
+ icon: "images/picture-icon16.png"
+
+ ItemLibraryEntry {
+ name: "Picture"
+ category: "Qt Quick - Extras"
+ libraryIcon: "images/picture-icon.png"
+ version: "1.3"
+ requiredImport: "QtQuick.Extras"
+ }
+ }
+}
diff --git a/src/extras/doc/compat/qtquickextras.qdocconf b/src/extras/doc/compat/qtquickextras.qdocconf
new file mode 100644
index 00000000..d36fd909
--- /dev/null
+++ b/src/extras/doc/compat/qtquickextras.qdocconf
@@ -0,0 +1,5 @@
+include(../qtquickextras-compat.qdocconf)
+
+# Workaround for qdoc not parsing relative include paths correctly
+exampledirs += ../../../../examples
+imagedirs += ../images
diff --git a/src/extras/doc/images/circulargauge-angles.png b/src/extras/doc/images/circulargauge-angles.png
new file mode 100644
index 00000000..fb93bcaa
--- /dev/null
+++ b/src/extras/doc/images/circulargauge-angles.png
Binary files differ
diff --git a/src/extras/doc/images/circulargauge-needle-example-2.png b/src/extras/doc/images/circulargauge-needle-example-2.png
new file mode 100644
index 00000000..a2b5f322
--- /dev/null
+++ b/src/extras/doc/images/circulargauge-needle-example-2.png
Binary files differ
diff --git a/src/extras/doc/images/circulargauge-needle.png b/src/extras/doc/images/circulargauge-needle.png
new file mode 100644
index 00000000..b2780b41
--- /dev/null
+++ b/src/extras/doc/images/circulargauge-needle.png
Binary files differ
diff --git a/src/extras/doc/images/circulargauge-reversed.png b/src/extras/doc/images/circulargauge-reversed.png
new file mode 100644
index 00000000..aeadfbcc
--- /dev/null
+++ b/src/extras/doc/images/circulargauge-reversed.png
Binary files differ
diff --git a/src/extras/doc/images/circulargauge-tickmark-indices-values.png b/src/extras/doc/images/circulargauge-tickmark-indices-values.png
new file mode 100644
index 00000000..d117f483
--- /dev/null
+++ b/src/extras/doc/images/circulargauge-tickmark-indices-values.png
Binary files differ
diff --git a/src/extras/doc/images/circulargauge.png b/src/extras/doc/images/circulargauge.png
new file mode 100644
index 00000000..f88aa01f
--- /dev/null
+++ b/src/extras/doc/images/circulargauge.png
Binary files differ
diff --git a/src/extras/doc/images/delaybutton-activated.png b/src/extras/doc/images/delaybutton-activated.png
new file mode 100644
index 00000000..d78d7738
--- /dev/null
+++ b/src/extras/doc/images/delaybutton-activated.png
Binary files differ
diff --git a/src/extras/doc/images/delaybutton-progress.png b/src/extras/doc/images/delaybutton-progress.png
new file mode 100644
index 00000000..07a13256
--- /dev/null
+++ b/src/extras/doc/images/delaybutton-progress.png
Binary files differ
diff --git a/src/extras/doc/images/delaybutton.png b/src/extras/doc/images/delaybutton.png
new file mode 100644
index 00000000..510abc0b
--- /dev/null
+++ b/src/extras/doc/images/delaybutton.png
Binary files differ
diff --git a/src/extras/doc/images/dial.png b/src/extras/doc/images/dial.png
new file mode 100644
index 00000000..d0e4d5ac
--- /dev/null
+++ b/src/extras/doc/images/dial.png
Binary files differ
diff --git a/src/extras/doc/images/gauge-minorTickmark-example.png b/src/extras/doc/images/gauge-minorTickmark-example.png
new file mode 100644
index 00000000..591120d6
--- /dev/null
+++ b/src/extras/doc/images/gauge-minorTickmark-example.png
Binary files differ
diff --git a/src/extras/doc/images/gauge-temperature.png b/src/extras/doc/images/gauge-temperature.png
new file mode 100644
index 00000000..95fc1679
--- /dev/null
+++ b/src/extras/doc/images/gauge-temperature.png
Binary files differ
diff --git a/src/extras/doc/images/gauge-tickmark-example.png b/src/extras/doc/images/gauge-tickmark-example.png
new file mode 100644
index 00000000..c46fb8a5
--- /dev/null
+++ b/src/extras/doc/images/gauge-tickmark-example.png
Binary files differ
diff --git a/src/extras/doc/images/gauge.png b/src/extras/doc/images/gauge.png
new file mode 100644
index 00000000..7e03307b
--- /dev/null
+++ b/src/extras/doc/images/gauge.png
Binary files differ
diff --git a/src/extras/doc/images/piemenu-boundingItem-example.png b/src/extras/doc/images/piemenu-boundingItem-example.png
new file mode 100644
index 00000000..f5c312b6
--- /dev/null
+++ b/src/extras/doc/images/piemenu-boundingItem-example.png
Binary files differ
diff --git a/src/extras/doc/images/piemenu-boundingItem-null-example.png b/src/extras/doc/images/piemenu-boundingItem-null-example.png
new file mode 100644
index 00000000..9ddb4f67
--- /dev/null
+++ b/src/extras/doc/images/piemenu-boundingItem-null-example.png
Binary files differ
diff --git a/src/extras/doc/images/piemenu-menuitem-example.png b/src/extras/doc/images/piemenu-menuitem-example.png
new file mode 100644
index 00000000..57a2f956
--- /dev/null
+++ b/src/extras/doc/images/piemenu-menuitem-example.png
Binary files differ
diff --git a/src/extras/doc/images/piemenu.png b/src/extras/doc/images/piemenu.png
new file mode 100644
index 00000000..95078eae
--- /dev/null
+++ b/src/extras/doc/images/piemenu.png
Binary files differ
diff --git a/src/extras/doc/images/qtquickextras-example-dashboard.png b/src/extras/doc/images/qtquickextras-example-dashboard.png
new file mode 100644
index 00000000..979a2d03
--- /dev/null
+++ b/src/extras/doc/images/qtquickextras-example-dashboard.png
Binary files differ
diff --git a/src/extras/doc/images/qtquickextras-example-flat.png b/src/extras/doc/images/qtquickextras-example-flat.png
new file mode 100644
index 00000000..f10bdc18
--- /dev/null
+++ b/src/extras/doc/images/qtquickextras-example-flat.png
Binary files differ
diff --git a/src/extras/doc/images/qtquickextras-example-gallery.png b/src/extras/doc/images/qtquickextras-example-gallery.png
new file mode 100644
index 00000000..1895912c
--- /dev/null
+++ b/src/extras/doc/images/qtquickextras-example-gallery.png
Binary files differ
diff --git a/src/extras/doc/images/statusindicator-active.png b/src/extras/doc/images/statusindicator-active.png
new file mode 100644
index 00000000..c5ebc09d
--- /dev/null
+++ b/src/extras/doc/images/statusindicator-active.png
Binary files differ
diff --git a/src/extras/doc/images/statusindicator-green.png b/src/extras/doc/images/statusindicator-green.png
new file mode 100644
index 00000000..88dcb1ed
--- /dev/null
+++ b/src/extras/doc/images/statusindicator-green.png
Binary files differ
diff --git a/src/extras/doc/images/statusindicator-inactive.png b/src/extras/doc/images/statusindicator-inactive.png
new file mode 100644
index 00000000..27488d5e
--- /dev/null
+++ b/src/extras/doc/images/statusindicator-inactive.png
Binary files differ
diff --git a/src/extras/doc/images/styling-circulargauge-background-example.png b/src/extras/doc/images/styling-circulargauge-background-example.png
new file mode 100644
index 00000000..e816c6f6
--- /dev/null
+++ b/src/extras/doc/images/styling-circulargauge-background-example.png
Binary files differ
diff --git a/src/extras/doc/images/styling-circulargauge-knob-example.png b/src/extras/doc/images/styling-circulargauge-knob-example.png
new file mode 100644
index 00000000..793a36c2
--- /dev/null
+++ b/src/extras/doc/images/styling-circulargauge-knob-example.png
Binary files differ
diff --git a/src/extras/doc/images/styling-circulargauge-minorTickmark-example.png b/src/extras/doc/images/styling-circulargauge-minorTickmark-example.png
new file mode 100644
index 00000000..f3f2d8d7
--- /dev/null
+++ b/src/extras/doc/images/styling-circulargauge-minorTickmark-example.png
Binary files differ
diff --git a/src/extras/doc/images/styling-circulargauge-needle-example.png b/src/extras/doc/images/styling-circulargauge-needle-example.png
new file mode 100644
index 00000000..08049fc9
--- /dev/null
+++ b/src/extras/doc/images/styling-circulargauge-needle-example.png
Binary files differ
diff --git a/src/extras/doc/images/styling-circulargauge-tickmark-example.png b/src/extras/doc/images/styling-circulargauge-tickmark-example.png
new file mode 100644
index 00000000..01c71cd1
--- /dev/null
+++ b/src/extras/doc/images/styling-circulargauge-tickmark-example.png
Binary files differ
diff --git a/src/extras/doc/images/styling-circulargauge-tickmarkLabel-example.png b/src/extras/doc/images/styling-circulargauge-tickmarkLabel-example.png
new file mode 100644
index 00000000..7520827e
--- /dev/null
+++ b/src/extras/doc/images/styling-circulargauge-tickmarkLabel-example.png
Binary files differ
diff --git a/src/extras/doc/images/styling-gauge-font-size.png b/src/extras/doc/images/styling-gauge-font-size.png
new file mode 100644
index 00000000..97d7ebb2
--- /dev/null
+++ b/src/extras/doc/images/styling-gauge-font-size.png
Binary files differ
diff --git a/src/extras/doc/images/styling-gauge-foreground.png b/src/extras/doc/images/styling-gauge-foreground.png
new file mode 100644
index 00000000..5a4f65b9
--- /dev/null
+++ b/src/extras/doc/images/styling-gauge-foreground.png
Binary files differ
diff --git a/src/extras/doc/images/styling-gauge-minorTickmark.png b/src/extras/doc/images/styling-gauge-minorTickmark.png
new file mode 100644
index 00000000..34e36192
--- /dev/null
+++ b/src/extras/doc/images/styling-gauge-minorTickmark.png
Binary files differ
diff --git a/src/extras/doc/images/styling-gauge-tickmark.png b/src/extras/doc/images/styling-gauge-tickmark.png
new file mode 100644
index 00000000..1cd4fb8b
--- /dev/null
+++ b/src/extras/doc/images/styling-gauge-tickmark.png
Binary files differ
diff --git a/src/extras/doc/images/styling-gauge-valueBar.png b/src/extras/doc/images/styling-gauge-valueBar.png
new file mode 100644
index 00000000..581b8240
--- /dev/null
+++ b/src/extras/doc/images/styling-gauge-valueBar.png
Binary files differ
diff --git a/src/extras/doc/images/togglebutton-checked.png b/src/extras/doc/images/togglebutton-checked.png
new file mode 100644
index 00000000..d40b382b
--- /dev/null
+++ b/src/extras/doc/images/togglebutton-checked.png
Binary files differ
diff --git a/src/extras/doc/images/togglebutton-unchecked.png b/src/extras/doc/images/togglebutton-unchecked.png
new file mode 100644
index 00000000..7db5b84b
--- /dev/null
+++ b/src/extras/doc/images/togglebutton-unchecked.png
Binary files differ
diff --git a/src/extras/doc/images/tumbler-flat-style.png b/src/extras/doc/images/tumbler-flat-style.png
new file mode 100644
index 00000000..9ec5402a
--- /dev/null
+++ b/src/extras/doc/images/tumbler-flat-style.png
Binary files differ
diff --git a/src/extras/doc/images/tumbler.png b/src/extras/doc/images/tumbler.png
new file mode 100644
index 00000000..5b15c57f
--- /dev/null
+++ b/src/extras/doc/images/tumbler.png
Binary files differ
diff --git a/src/extras/doc/qtquickextras-compat.qdocconf b/src/extras/doc/qtquickextras-compat.qdocconf
new file mode 100644
index 00000000..ad171f47
--- /dev/null
+++ b/src/extras/doc/qtquickextras-compat.qdocconf
@@ -0,0 +1,17 @@
+include($QT_INSTALL_DOCS/global/qt-defines.qdocconf)
+include($QT_INSTALL_DOCS/global/qt-cpp-ignore.qdocconf)
+
+naturallanguage = en_US
+outputencoding = UTF-8
+sourceencoding = UTF-8
+
+examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml *.css"
+examples.imageextensions = "*.png *.jpg *.gif"
+
+headers.fileextensions = "*.ch *.h *.h++ *.hh *.hpp *.hxx"
+sources.fileextensions = "*.c++ *.cc *.cpp *.cxx *.mm *.qml *.qdoc"
+
+#include the external websites
+sourcedirs += externalsites
+
+include(qtquickextras-project.qdocconf)
diff --git a/src/extras/doc/qtquickextras-project.qdocconf b/src/extras/doc/qtquickextras-project.qdocconf
new file mode 100644
index 00000000..0e0104c1
--- /dev/null
+++ b/src/extras/doc/qtquickextras-project.qdocconf
@@ -0,0 +1,59 @@
+include($QT_INSTALL_DOCS/global/macros.qdocconf)
+include($QT_INSTALL_DOCS/global/compat.qdocconf)
+#include($QT_INSTALL_DOCS/global/manifest-meta.qdocconf)
+include($QT_INSTALL_DOCS/global/qt-html-templates-offline.qdocconf)
+
+project = QtQuickExtras
+description = Qt Quick Extras Reference Documentation
+url = http://doc.qt.digia.com/QtQuickExtras/
+version = 1.3
+
+qhp.projects = QtQuickExtras
+
+qhp.QtQuickExtras.file = qtquickextras.qhp
+qhp.QtQuickExtras.namespace = org.qt-project.qtquickextras.1.3
+qhp.QtQuickExtras.virtualFolder = qtquickextras
+qhp.QtQuickExtras.indexTitle = Qt Quick Extras
+qhp.QtQuickExtras.indexRoot =
+#qhp.QtQuickExtras.extraFiles = style/qtquickextras.css
+
+qhp.QtQuickExtras.filterAttributes = qtquickextras 1.3 qtrefdoc
+qhp.QtQuickExtras.customFilters.Qt.name = QtQuickExtras 1.3
+qhp.QtQuickExtras.customFilters.Qt.filterAttributes = qtquickextras 1.3
+
+qhp.QtQuickExtras.subprojects = qtquickextrasstyles
+
+qhp.QtQuickExtras.subprojects.qtquickextrasqmltypes.title = Controls QML Types
+qhp.QtQuickExtras.subprojects.qtquickextrasqmltypes.indexTitle = Qt Quick Controls QML Types
+qhp.QtQuickExtras.subprojects.qtquickextrasqmltypes.selectors = fake:qmlclass # cannot choose qmltypes from a specific group QTBUG-32985
+qhp.QtQuickExtras.subprojects.qtquickextrasqmltypes.sortPages = true
+
+qhp.QtQuickExtras.subprojects.qtquickextrasstyles.title = Qt Quick Extras Styles Structure
+qhp.QtQuickExtras.subprojects.qtquickextrasstyles.indexTitle = Qt Quick Extras Styles Structure
+qhp.QtQuickExtras.subprojects.qtquickextrasstyles.type = manual
+
+# QTBUG-35596: If you're using a shadow build of Qt >= 5.3.1, then uncomment the following line and comment out indexes += ...
+#depends = qtqml qtquick qtdoc qtquickcontrols
+indexes += $QT_INSTALL_DOCS/qtqml/qtqml.index \
+ $QT_INSTALL_DOCS/qtquick/qtquick.index \
+ $QT_INSTALL_DOCS/qtdoc/qtdoc.index \
+ $QT_INSTALL_DOCS/qtquickcontrols/qtquickcontrols.index
+
+# Specify the install path under QT_INSTALL_EXAMPLES
+# Examples will be installed under quick/extras -
+# 'extras' subdirectory is given as part of \example commands
+exampledirs += ../../../examples/quick \
+ snippets
+examplesinstallpath = quick
+
+headerdirs += ../
+
+sourcedirs += ../
+
+#sources += ../Private/<stuff> \
+
+imagedirs += images
+
+navigation.landingpage = "Qt Quick Extras"
+navigation.qmltypespage = "Qt Quick Extras QML Types"
+buildversion = "Qt Quick Extras 1.3"
diff --git a/src/extras/doc/qtquickextras.qdocconf b/src/extras/doc/qtquickextras.qdocconf
new file mode 100644
index 00000000..10117442
--- /dev/null
+++ b/src/extras/doc/qtquickextras.qdocconf
@@ -0,0 +1,4 @@
+include($QT_INSTALL_DOCS/global/qt-cpp-defines.qdocconf)
+include($QT_INSTALL_DOCS/global/fileextensions.qdocconf)
+
+include(qtquickextras-project.qdocconf)
diff --git a/src/extras/doc/snippets/circulargauge-background-range.qml b/src/extras/doc/snippets/circulargauge-background-range.qml
new file mode 100644
index 00000000..619fc465
--- /dev/null
+++ b/src/extras/doc/snippets/circulargauge-background-range.qml
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [range]
+import QtQuick 2.0
+import QtQuick.Controls 1.1
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private 1.0
+
+Rectangle {
+ width: 300
+ height: 300
+ color: "#494d53"
+
+ CircularGauge {
+ id: gauge
+ anchors.centerIn: parent
+ style: CircularGaugeStyle {
+ id: style
+
+ //! [background]
+ function degreesToRadians(degrees) {
+ return degrees * (Math.PI / 180);
+ }
+
+
+ background: Canvas {
+ onPaint: {
+ var ctx = getContext("2d");
+ ctx.reset();
+
+ ctx.beginPath();
+ ctx.strokeStyle = "#e34c22";
+ ctx.lineWidth = outerRadius * 0.02;
+
+ ctx.arc(outerRadius, outerRadius, outerRadius - ctx.lineWidth / 2,
+ degreesToRadians(valueToAngle(80) - 90), degreesToRadians(valueToAngle(100) - 90));
+ ctx.stroke();
+ }
+ }
+ //! [background]
+
+ //! [tickmark]
+ tickmark: Rectangle {
+ visible: styleData.value < 80 || styleData.value % 10 == 0
+ implicitWidth: outerRadius * 0.02
+ antialiasing: true
+ implicitHeight: outerRadius * 0.06
+ color: styleData.value >= 80 ? "#e34c22" : "#e5e5e5"
+ }
+ //! [tickmark]
+
+ //! [minorTickmark]
+ minorTickmark: Rectangle {
+ visible: styleData.value < 80
+ implicitWidth: outerRadius * 0.01
+ antialiasing: true
+ implicitHeight: outerRadius * 0.03
+ color: "#e5e5e5"
+ }
+ //! [minorTickmark]
+
+ //! [tickmarkLabel]
+ tickmarkLabel: Text {
+ font.pixelSize: Math.max(6, outerRadius * 0.1)
+ text: styleData.value
+ color: styleData.value >= 80 ? "#e34c22" : "#e5e5e5"
+ antialiasing: true
+ }
+ //! [tickmarkLabel]
+
+ //! [needle]
+ needle: Rectangle {
+ y: outerRadius * 0.15
+ implicitWidth: outerRadius * 0.03
+ implicitHeight: outerRadius * 0.9
+ antialiasing: true
+ color: "#e5e5e5"
+ }
+ //! [needle]
+
+ //! [foreground]
+ foreground: Item {
+ Rectangle {
+ width: outerRadius * 0.2
+ height: width
+ radius: width / 2
+ color: "#e5e5e5"
+ anchors.centerIn: parent
+ }
+ }
+ //! [foreground]
+ }
+ }
+}
+//! [range]
diff --git a/src/extras/doc/snippets/circulargauge-tickmark-indices-values.qml b/src/extras/doc/snippets/circulargauge-tickmark-indices-values.qml
new file mode 100644
index 00000000..33781baa
--- /dev/null
+++ b/src/extras/doc/snippets/circulargauge-tickmark-indices-values.qml
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [tickmarks]
+import QtQuick 2.0
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+
+Rectangle {
+ width: 400
+ height: 400
+
+ CircularGauge {
+ id: gauge
+ anchors.fill: parent
+ style: CircularGaugeStyle {
+ labelInset: outerRadius * 0.2
+
+ tickmarkLabel: null
+
+ tickmark: Text {
+ text: styleData.value
+
+ Text {
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.bottom
+ text: styleData.index
+ color: "blue"
+ }
+ }
+
+ minorTickmark: Text {
+ text: styleData.value
+ font.pixelSize: 8
+
+ Text {
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.bottom
+ text: styleData.index
+ font.pixelSize: 8
+ color: "blue"
+ }
+ }
+ }
+
+ Text {
+ id: indexText
+ text: "Major and minor indices"
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: valueText.top
+ color: "blue"
+ }
+ Text {
+ id: valueText
+ text: "Major and minor values"
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ }
+ }
+}
+//! [tickmarks]
diff --git a/src/extras/doc/snippets/styling-gauge.qml b/src/extras/doc/snippets/styling-gauge.qml
new file mode 100644
index 00000000..48cb95ed
--- /dev/null
+++ b/src/extras/doc/snippets/styling-gauge.qml
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [all]
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+
+Rectangle {
+ width: 100
+ height: 220
+ color: "#494d53"
+
+ Gauge {
+ value: 50
+ tickmarkStepSize: 20
+ minorTickmarkCount: 1
+ //! [font-size]
+ font.pixelSize: 15
+ //! [font-size]
+ anchors.centerIn: parent
+ anchors.horizontalCenterOffset: -4
+
+ style: GaugeStyle {
+ //! [valueBar]
+ valueBar: Rectangle {
+ color: "#e34c22"
+ implicitWidth: 28
+ }
+ //! [valueBar]
+
+ //! [foreground]
+ foreground: null
+ //! [foreground]
+
+ //! [tickmark]
+ tickmark: Item {
+ implicitWidth: 8
+ implicitHeight: 4
+
+ Rectangle {
+ x: control.tickmarkAlignment === Qt.AlignLeft
+ || control.tickmarkAlignment === Qt.AlignTop ? parent.implicitWidth : -28
+ width: 28
+ height: parent.height
+ color: "#ffffff"
+ }
+ }
+ //! [tickmark]
+
+ //! [minorTickmark]
+ minorTickmark: Item {
+ implicitWidth: 8
+ implicitHeight: 2
+
+ Rectangle {
+ x: control.tickmarkAlignment === Qt.AlignLeft
+ || control.tickmarkAlignment === Qt.AlignTop ? parent.implicitWidth : -28
+ width: 28
+ height: parent.height
+ color: "#ffffff"
+ }
+ }
+ //! [minorTickmark]
+ }
+ }
+}
+//! [all]
diff --git a/src/extras/doc/src/qtquickextras-examples.qdoc b/src/extras/doc/src/qtquickextras-examples.qdoc
new file mode 100644
index 00000000..c966e48d
--- /dev/null
+++ b/src/extras/doc/src/qtquickextras-examples.qdoc
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \group qtquickextras-examples
+ \ingroup all-examples
+ \title Qt Quick Extras Examples
+ \brief A collection of examples for \l{Qt Quick Extras}.
+
+ Below is a listing of the examples for \l{Qt Quick Extras}.
+*/
+
+/*!
+ \example extras/gallery
+ \title Qt Quick Extras - Gallery
+ \ingroup qtquickextras-examples
+ \brief An interactive showcase of the various controls.
+ \image qtquickextras-example-gallery.png
+
+ This example project demonstrates the various UI controls provided by
+ \l{Qt Quick Extras}.
+*/
+
+/*!
+ \example extras/dashboard
+ \title Qt Quick Extras - Dashboard
+ \ingroup qtquickextras-examples
+ \brief A car dashboard created using several CircularGauge controls.
+ \image qtquickextras-example-dashboard.png
+
+ This example project demonstrates the use of \l CircularGauge to create a car dashboard.
+*/
+
+/*!
+ \example extras/flat
+ \title Qt Quick Extras - Flat
+ \ingroup qtquickextras-examples
+ \brief An interactive showcase of the flat style.
+ \image qtquickextras-example-flat.png
+
+ This example project demonstrates the Flat style, a modern look for
+ both the Qt Quick Controls and Qt Quick Extras.
+*/
diff --git a/src/extras/doc/src/qtquickextras-index.qdoc b/src/extras/doc/src/qtquickextras-index.qdoc
new file mode 100644
index 00000000..18e40711
--- /dev/null
+++ b/src/extras/doc/src/qtquickextras-index.qdoc
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page index.html
+ \title Qt Quick Extras
+
+ \brief The Qt Quick Extras module provides a set of UI controls for Qt
+ Quick.
+
+ The Qt Quick Extras module provides a specialized set of
+ controls that can be used to build interfaces in Qt Quick.
+
+ The module requires \l{Qt Quick} 2.2, and \l{Qt Quick Controls} 1.1.
+
+ Visit the \l{Qt Quick Extras Overview} page to get started.
+
+ \section1 Controls
+ Controls are typically items that are used to present or receive input from
+ the user.
+ \annotatedlist extras
+
+ \section1 Related information
+
+ \list
+ \li \l{Qt Quick}
+ \li \l{Qt Quick Extras Overview}
+ \li \l{Qt Quick Extras QML Types}{Qt Quick Extras QML Types}
+ \li \l{Qt Quick Extras Examples}
+ \li \l{Qt Quick Extras Styles}
+ \endlist
+*/
diff --git a/src/extras/doc/src/qtquickextras-overview.qdoc b/src/extras/doc/src/qtquickextras-overview.qdoc
new file mode 100644
index 00000000..63732c50
--- /dev/null
+++ b/src/extras/doc/src/qtquickextras-overview.qdoc
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page qtquickextras-overview.html
+ \title Qt Quick Extras Overview
+ \brief A set of UI controls to create user interfaces in Qt Quick
+
+ Qt Quick Extras provide a set of UI controls to create user
+ interfaces in Qt Quick.
+
+ \section1 Getting Started
+
+ \section2 Building
+
+ If you are building Qt Quick Extras from source, you can follow
+ the steps used for most Qt modules:
+
+ \code
+ qmake
+ make
+ make install
+ \endcode
+
+ \section2 Documentation
+
+ To build this documentation, you should use an in-source build of Qt or
+ install Qt from a binary package.
+
+ The steps to build the documentation are:
+
+ \code
+ qmake
+ make docs
+ \endcode
+
+ \section2 Using the Controls
+
+ The QML types can be imported into your application using the following
+ import statement in your \c {.qml} file.
+
+ \code
+ import QtQuick.Extras 1.3
+ \endcode
+
+ \section1 Interactive controls
+
+ \annotatedlist extras-interactive
+
+ \section1 Non-interactive controls
+
+ \annotatedlist extras-non-interactive
+
+ \section1 Creating a basic example
+
+ A basic example of a QML file that makes use of controls is shown here:
+
+ \code
+ import QtQuick 2.2
+ import QtQuick.Extras 1.3
+
+ Rectangle {
+ DelayButton {
+ anchors.centerIn: parent
+ }
+ }
+ \endcode
+
+ For an interactive showcase of the controls provided by
+ \l{Qt Quick Extras}, you can look at
+ the \l{Qt Quick Extras - Gallery}{Gallery} example.
+
+ \image qtquickextras-example-gallery.png
+
+ \section1 Related information
+
+ \list
+ \li \l{Qt Quick}
+ \li \l{Qt Quick Extras}
+ \li \l{Qt Quick Extras Examples}
+ \endlist
+*/
diff --git a/src/extras/doc/src/qtquickextras.qdoc b/src/extras/doc/src/qtquickextras.qdoc
new file mode 100644
index 00000000..835b14fd
--- /dev/null
+++ b/src/extras/doc/src/qtquickextras.qdoc
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \qmlmodule QtQuick.Extras 1.3
+ \title Qt Quick Extras QML Types
+ \ingroup qmlmodules
+ \brief Provides QML types for user interfaces.
+
+ The \l{Qt Quick Extras} module provides specialized controls
+ for creating user interfaces. These QML types work in conjunction with
+ \l{Qt Quick} and \l{Qt Quick Controls}.
+
+ Controls can be styled using the
+ \l{Qt Quick Extras Styles QML Types}{Styles QML Types}.
+
+ The QML types can be imported into your application using the
+ following import statement in your .qml file.
+
+ \code
+ import QtQuick.Extras 1.3
+ \endcode
+
+*/
diff --git a/src/extras/doc/src/qtquickextrasstyles-index.qdoc b/src/extras/doc/src/qtquickextrasstyles-index.qdoc
new file mode 100644
index 00000000..6af24bb7
--- /dev/null
+++ b/src/extras/doc/src/qtquickextrasstyles-index.qdoc
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \group extrasstyling
+ \title Styling Extras Controls
+*/
+
+/*!
+ \page qtquickextrasstyles-index.html
+ \title Qt Quick Extras Styles
+ \brief The Qt Quick Extras Styles submodule provides custom
+ styles for Qt Quick Extras.
+
+ The Qt Quick Extras Styles module allows custom styling for
+ \l {Qt Quick Extras}.
+
+ The submodule requires \l{Qt Quick} 2.2.
+
+ \section1 Getting started
+
+ The QML types can be imported into your application using the following
+ import statement in your \c {.qml} file.
+
+ \code
+ import QtQuick.Extras.Styles 1.3
+ \endcode
+
+ \section1 Styles
+
+ \section2 Base Style
+
+ The Base Style is the default style used when none is specified. It is also
+ used as a fallback when the specified style cannot be found.
+
+ \image tumbler.png
+ \caption The Base Style Tumbler.
+
+ \section2 Flat Style
+
+ The Flat Style is designed for touch devices. It was introduced in Qt Quick
+ Extras Controls 1.3 and requires Qt 5.4.
+
+ \image tumbler-flat-style.png
+ \caption The Flat Style Tumbler.
+
+ \section2 Selecting Styles
+
+ Qt Quick Extras follow Qt Quick Controls' styling system. You
+ can apply a different style to the controls by setting the
+ \e QT_QUICK_CONTROLS_STYLE environment variable to the name of the style.
+ For example, to use the Flat style, you can do the following:
+
+ \code
+ QT_QUICK_CONTROLS_STYLE=Flat ./app
+ \endcode
+
+ This can also be done in C++, using qputenv():
+
+ \code
+ qputenv("QT_QUICK_CONTROLS_STYLE", "Flat");
+ \endcode
+
+ \section1 Control Styles
+ \annotatedlist extrasstyles
+
+ \section1 Styling Tutorials
+ \annotatedlist extrasstyling
+
+ \section1 Related information
+
+ \list
+ \li \l{Qt Quick}
+ \li \l{Qt Quick Extras}
+ \li \l{Qt Quick Extras Styles QML Types}
+ \endlist
+*/
+
+/*!
+ \page qtquickextrasstyles-structure.html
+ \title Qt Quick Extras Styles Structure
+ \list
+ \li \l{Qt Quick Extras Styles}
+ \list
+ \li \l{Qt Quick Extras Styles QML Types}{Styles QMl Types}
+ \endlist
+ \endlist
+*/
+
+/*!
+ \qmlmodule QtQuick.Extras.Styles 1.0
+ \title Qt Quick Extras Styles QML Types
+ \ingroup qmlmodules
+ \brief Provides QML types for Qt Quick Extras styles.
+
+ The \l{Qt Quick Extras} module provides a set of QML types for
+ handling styles.
+
+ Some of the controls allow custom styling similar to widget style sheets.
+ A styling object is usually a collection of properties that control behavior
+ and simple delegates that can be replaced with custom QML snippets.
+
+ \code
+ import QtQuick.Extras.Styles 1.3
+ \endcode
+*/
diff --git a/src/extras/doc/src/styling-circulargauge.qdoc b/src/extras/doc/src/styling-circulargauge.qdoc
new file mode 100644
index 00000000..9cf94087
--- /dev/null
+++ b/src/extras/doc/src/styling-circulargauge.qdoc
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page styling-circulargauge.html
+ \title Styling CircularGauge
+ \brief Tutorial for styling CircularGauge.
+ \ingroup extrasstyling
+
+ \target styling-circulargauge-needle
+ \section2 The Needle Component
+
+ The \l {QtQuick.Extras.Styles::CircularGaugeStyle::}{needle}
+ component is rotated around the gauge to represent the current value.
+
+ Starting from the default style, we'll add a very basic white needle:
+
+ \snippet circulargauge-background-range.qml needle
+
+ \image styling-circulargauge-needle-example.png
+
+ As mentioned in the documentation for \l {QtQuick.Extras.Styles::}
+ {CircularGaugeStyle}, \c implicitWidth
+ and \c implicitHeight properties need to be set. This is so that the needle
+ can be positioned properly. We always scale items by the
+ \l {QtQuick.Extras.Styles::CircularGaugeStyle::}{outerRadius}
+ property of the style, ensuring the control resizes gracefully.
+
+ We offset the needle vertically so that its back sits beyond the knob.
+
+ \target styling-circulargauge-foreground
+ \section2 The Foreground Component
+
+ We've now changed the needle, but the default knob is still there; let's
+ replace it. The \l {QtQuick.Extras.Styles::CircularGaugeStyle::}
+ {foreground} component defines the default knob, so we can specify our own by
+ overriding it (note that we could also set it to \c null if we didn't want a
+ foreground):
+
+ \snippet circulargauge-background-range.qml foreground
+
+ \image styling-circulargauge-knob-example.png
+
+ Firstly, we create a circle from the Rectangle item by setting the radius to
+ be half the width (either width or height will work here; they are always
+ equal in this case). We make it a child of the Item, because the foreground
+ fills the gauge. We then center it within the Item.
+
+ We set the color of the knob to the same white that we used before.
+
+ \target styling-circulargauge-tickmarkLabel
+ \section2 The Tickmark Label Component
+
+ Suppose we want to caution the user if the value displayed by the gauge goes
+ above or below a certain range. We could present this range to the user in
+ several ways:
+
+ \list A
+ \li Change the color of the tickmarks depending on \c styleData.value
+ \li Add an image to the background
+ \li Draw it with \l {QtQuick::}{Canvas}
+ \endlist
+
+ We'll choose options 1 and 3, as they are more flexible than using an
+ image.
+
+ Firstly, let's change the color of the three highest tickmark labels:
+
+ \snippet circulargauge-background-range.qml tickmarkLabel
+
+ \image styling-circulargauge-tickmarkLabel-example.png tickmarkLabel
+
+ We also change the color of the rest of the labels to the same white that
+ we used for the needle and knob.
+
+ \target styling-circulargauge-tickmark
+ \section2 The Tickmark Component
+
+ Now let's do the same for the three highest tickmarks:
+
+ \snippet circulargauge-background-range.qml tickmark
+
+ \image styling-circulargauge-tickmark-example.png tickmark
+
+ \target styling-circulargauge-minorTickmark
+ \section2 The Minor Tickmark Component
+
+ For the minor tickmarks, we'll only show those which are not higher than
+ \c 80:
+
+ \snippet circulargauge-background-range.qml minorTickmark
+
+ \image styling-circulargauge-minorTickmark-example.png minorTickmark
+
+ This is because we'll draw something between that range in the next section.
+
+ \target styling-circulargauge-background
+ \section2 The Background Component
+
+ We'll display the range that indicates caution with an orange arc:
+
+ \snippet circulargauge-background-range.qml background
+
+ We define a function to convert degrees to radians, which are the
+ units used by \l {QtQuick::}{Canvas}.
+
+ Next, we do the drawing of the range using Canvas. We draw an arc between
+ \c 80 and \c 100, using the
+ \l {QtQuick.Extras.Styles::CircularGaugeStyle::}{valueToAngle()}
+ function provided by CircularGaugeStyle. Note that we subtract \c 90 degrees
+ before converting to radians, as our origin is north and Canvas' is east.
+
+ The finished product:
+
+ \image styling-circulargauge-background-example.png background
+
+ The complete code for this example is as follows:
+
+ \snippet circulargauge-background-range.qml range
+*/
+
diff --git a/src/extras/doc/src/styling-gauge.qdoc b/src/extras/doc/src/styling-gauge.qdoc
new file mode 100644
index 00000000..accdd425
--- /dev/null
+++ b/src/extras/doc/src/styling-gauge.qdoc
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page styling-gauge.html
+ \title Styling Gauge
+ \brief Tutorial for styling the Gauge control.
+ \ingroup extrasstyling
+
+ As GaugeStyle's documentation adequately covers common use cases, this
+ tutorial will cover a different scenario: one where the gauge's tickmarks
+ cover the value bar, instead of being aligned to the left or right of it.
+
+ \target styling-gauge-valueBar
+ \section2 The Value Bar Component
+
+ The \l {QtQuick.Extras.Styles::GaugeStyle::}{valueBar}
+ component is resized according to the gauge's value; if the value is low,
+ the bar will be small, and vice versa.
+
+ Starting from the default style, we'll change the color of the value bar to
+ orange, and increase its width slightly:
+
+ \snippet styling-gauge.qml valueBar
+
+ \image styling-gauge-valueBar.png
+
+ As mentioned in the documentation for GaugeStyle, \c implicitWidth needs to
+ be set when defining your own value bar.
+
+ \target styling-gauge-foreground
+ \section2 The Foreground Component
+
+ The \l {QtQuick.Extras.Styles::GaugeStyle::}{foreground}
+ component covers the full width and height of the value bar, even when the
+ value bar is not at its highest. By default, the foreground component
+ provides a "sheen". We'll choose to discard this, and leave it empty
+ instead:
+
+ \snippet styling-gauge.qml foreground
+
+ \image styling-gauge-foreground.png
+
+ \target styling-gauge-tickmark
+ \section2 The Tickmark Component
+
+ The \l {QtQuick.Extras.Styles::GaugeStyle::}{tickmark}
+ component sits to the left or right of the value bar, depending on the
+ control's \l {Gauge::tickmarkAlignment}{tickmarkAlignment}. In order to
+ have the tickmarks cover the width of the value bar instead, we need to do
+ two things:
+ \list 1
+ \li Remove the space the tickmarks previously assumed so that there is
+ just enough space for margins between the tickmarks and value bar.
+ \li Position the tickmarks according to the control's orientation and
+ tickmark alignment.
+ \endlist
+
+ \snippet styling-gauge.qml tickmark
+
+ In this case we chose \c 8 pixel margins, so we set the \c implicitWidth of
+ the tickmarks to that.
+
+ We account for every possible orientation and tickmark alignment, something
+ that is not necessary if the gauge will only ever have one orientation and
+ alignment. For example, if the gauge will always be of a vertical
+ orientation and the tickmarks left-aligned, then it is enough to set the
+ \c x property of the \c Rectangle to the following:
+
+ \code
+ x: parent.implicitWidth
+ \endcode
+
+ The value bar is \c 28 pixels wide, so we give the same width to our
+ tickmarks so that they cover the width of it.
+
+ \image styling-gauge-tickmark.png
+
+ \target styling-gauge-minorTickmark
+ \section2 The Minor Tickmark Component
+
+ The \l {QtQuick.Extras.Styles::GaugeStyle::}{minorTickmark}
+ component is almost identical to its larger counterpart, except that its
+ width does not affect the layout of the gauge's components. We'll do
+ similar adjustments to the ones in the previous section - the only
+ difference being the height:
+
+ \snippet styling-gauge.qml minorTickmark
+
+ \image styling-gauge-minorTickmark.png
+
+ \target styling-gauge-font-size
+ \section2 Adjusting Font Size
+
+ Finally, we increase the \l {Gauge::font}{font} size to \c 15 pixels:
+
+ \snippet styling-gauge.qml font-size
+ \image styling-gauge-font-size.png
+
+ \target styling-gauge-complete
+ \section2 Complete Source Code
+
+ \snippet styling-gauge.qml all
+*/
+
diff --git a/src/extras/extras.pro b/src/extras/extras.pro
new file mode 100644
index 00000000..dacadf1f
--- /dev/null
+++ b/src/extras/extras.pro
@@ -0,0 +1,39 @@
+TARGET = qtquickextrasplugin
+TARGETPATH = QtQuick/Extras
+IMPORT_VERSION = 1.3
+
+QT += qml
+
+# Qt 5.1 requires a different set of includes for .qdocconf
+equals(QT_MAJOR_VERSION, 5):!greaterThan(QT_MINOR_VERSION, 1) {
+ QMAKE_DOCS = $$PWD/doc/compat/qtquickextras.qdocconf
+} else {
+ QMAKE_DOCS = $$PWD/doc/qtquickextras.qdocconf
+}
+
+CONTROLS_QML_FILES = \
+ CircularGauge.qml \
+ DelayButton.qml \
+ Dial.qml \
+ Gauge.qml \
+ StatusIndicator.qml \
+ PieMenu.qml \
+ ToggleButton.qml \
+ Tumbler.qml \
+ TumblerColumn.qml
+
+HEADERS += plugin.h \
+ qquicktriggermode_p.h \
+ qquickpicture_p.h
+SOURCES += plugin.cpp \
+ qquickpicture.cpp
+
+include(Private/private.pri)
+include(designer/designer.pri)
+
+OTHER_FILES += doc/src/*
+
+RESOURCES += extras.qrc
+
+CONFIG += no_cxx_module
+load(qml_plugin)
diff --git a/src/extras/extras.qrc b/src/extras/extras.qrc
new file mode 100644
index 00000000..fcb8da57
--- /dev/null
+++ b/src/extras/extras.qrc
@@ -0,0 +1,19 @@
+<RCC>
+ <qresource prefix="/ExtrasImports/QtQuick/Extras">
+ <file>StatusIndicator.qml</file>
+ <file>ToggleButton.qml</file>
+ <file>Tumbler.qml</file>
+ <file>PieMenu.qml</file>
+ <file>Gauge.qml</file>
+ <file>Dial.qml</file>
+ <file>CircularGauge.qml</file>
+ <file>TumblerColumn.qml</file>
+ <file>DelayButton.qml</file>
+ <file>Private/CircularButton.qml</file>
+ <file>Private/Handle.qml</file>
+ <file>Private/PieMenuIcon.qml</file>
+ <file>Private/CircularButtonStyleHelper.qml</file>
+ <file>Private/CircularTickmarkLabel.qml</file>
+ <file>Private/TextSingleton.qml</file>
+ </qresource>
+</RCC>
diff --git a/src/extras/generateresource.prf b/src/extras/generateresource.prf
new file mode 100644
index 00000000..f84f1d87
--- /dev/null
+++ b/src/extras/generateresource.prf
@@ -0,0 +1,27 @@
+defineReplace(generate_resource) {
+ GENERATED_FILE = $$OUT_PWD/$$1
+ INCLUDED_FILES = $$2
+ GENERATED_CONTENT = \
+ "<RCC>"
+
+ RESOURCE_PREFIX = ""
+ for (FILE, INCLUDED_FILES) {
+ RELATIVE_PATH = $$relative_path($$absolute_path($$FILE), $$_PRO_FILE_PWD_)
+ SUB_FOLDER = /$$dirname(RELATIVE_PATH)
+ !equals(SUB_FOLDER, $$RESOURCE_PREFIX) {
+ !isEmpty(RESOURCE_PREFIX): GENERATED_CONTENT += "</qresource>"
+ RESOURCE_PREFIX = "ExtrasImports"/$$TARGETPATH$$SUB_FOLDER
+ GENERATED_CONTENT += "<qresource prefix=\"$$RESOURCE_PREFIX\">"
+ }
+ ABSOLUTE_PATH = $$absolute_path($$FILE)
+ ALIAS_NAME = $$basename(FILE)
+ GENERATED_CONTENT += "<file alias=\"$$ALIAS_NAME\">$$ABSOLUTE_PATH</file>"
+ }
+ !isEmpty(RESOURCE_PREFIX): GENERATED_CONTENT += "</qresource>"
+
+ GENERATED_CONTENT += \
+ "</RCC>"
+ write_file($$GENERATED_FILE, GENERATED_CONTENT)|error("Failed to write resource file!")
+
+ return($$GENERATED_FILE)
+}
diff --git a/src/extras/plugin.cpp b/src/extras/plugin.cpp
new file mode 100644
index 00000000..7ac942bd
--- /dev/null
+++ b/src/extras/plugin.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "plugin.h"
+
+#include <QtCore/qfile.h>
+
+#include "qquickpicture_p.h"
+#include "qquicktriggermode_p.h"
+#include "Private/qquickcircularprogressbar_p.h"
+#include "Private/qquickflatprogressbar_p.h"
+#include "Private/qquickmousethief_p.h"
+#include "Private/qquickstylesettings_p.h"
+#include "Private/qquickmathutils_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static QObject *registerMathUtilsSingleton(QQmlEngine *engine, QJSEngine *jsEngine)
+{
+ Q_UNUSED(engine);
+ Q_UNUSED(jsEngine);
+ return new QQuickMathUtils();
+}
+
+QtQuickExtrasPlugin::QtQuickExtrasPlugin(QObject *parent) :
+ QQmlExtensionPlugin(parent)
+{
+}
+
+void QtQuickExtrasPlugin::registerTypes(const char *uri)
+{
+ Q_INIT_RESOURCE(extras);
+ const QString prefix = "qrc:///ExtrasImports/QtQuick/Extras";
+ // Register public API.
+ qmlRegisterUncreatableType<QQuickActivationMode>(uri, 1, 0, "ActivationMode", QLatin1String("Do not create objects of type ActivationMode"));
+ // register 1.0
+ qmlRegisterType(QUrl(prefix + "/CircularGauge.qml"), uri, 1, 0, "CircularGauge");
+ qmlRegisterType(QUrl(prefix + "/DelayButton.qml"), uri, 1, 0, "DelayButton");
+ qmlRegisterType(QUrl(prefix + "/Dial.qml"), uri, 1, 0, "Dial");
+ qmlRegisterType(QUrl(prefix + "/Gauge.qml"), uri, 1, 0, "Gauge");
+ qmlRegisterType(QUrl(prefix + "/PieMenu.qml"), uri, 1, 0, "PieMenu");
+ qmlRegisterType(QUrl(prefix + "/StatusIndicator.qml"), uri, 1, 0, "StatusIndicator");
+ qmlRegisterType(QUrl(prefix + "/ToggleButton.qml"), uri, 1, 0, "ToggleButton");
+ // register 1.1
+ qmlRegisterType(QUrl(prefix + "/Dial.qml"), uri, 1, 1, "Dial");
+ qmlRegisterType(QUrl(prefix + "/StatusIndicator.qml"), uri, 1, 1, "StatusIndicator");
+ // register 1.2
+ qmlRegisterType(QUrl(prefix + "/Tumbler.qml"), uri, 1, 2, "Tumbler");
+ qmlRegisterType(QUrl(prefix + "/TumblerColumn.qml"), uri, 1, 2, "TumblerColumn");
+ // register 1.3
+ qmlRegisterUncreatableType<QQuickTriggerMode>(uri, 1, 3, "TriggerMode", QLatin1String("Do not create objects of type TriggerMode"));
+ // register 1.4
+ qmlRegisterType<QQuickPicture>(uri, 1, /*TODO: 4*/3, "Picture");
+}
+
+void QtQuickExtrasPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
+{
+ Q_UNUSED(uri);
+ Q_UNUSED(engine);
+ qmlRegisterType<QQuickMouseThief>("QtQuick.Extras.Private.CppUtils", 1, 0, "MouseThief");
+ qmlRegisterType<QQuickCircularProgressBar>("QtQuick.Extras.Private.CppUtils", 1, 1, "CircularProgressBar");
+ qmlRegisterType<QQuickFlatProgressBar>("QtQuick.Extras.Private.CppUtils", 1, 1, "FlatProgressBar");
+ qmlRegisterSingletonType<QQuickStyleSettings>("QtQuick.Extras.Private", 1, 0, "StyleSettings", registerSettingsModule);
+ qmlRegisterSingletonType<QQuickMathUtils>("QtQuick.Extras.Private.CppUtils", 1, 0, "MathUtils", registerMathUtilsSingleton);
+
+ const QString prefix = "qrc:///ExtrasImports/QtQuick/Extras";
+ const char *private_uri = "QtQuick.Extras.Private";
+ qmlRegisterType(QUrl(prefix + "/Private/CircularButton.qml"), private_uri, 1, 0, "CircularButton");
+ qmlRegisterType(QUrl(prefix + "/Private/CircularButtonStyleHelper.qml"), private_uri, 1, 0, "CircularButtonStyleHelper");
+ qmlRegisterType(QUrl(prefix + "/Private/CircularTickmarkLabel.qml"), private_uri, 1, 0, "CircularTickmarkLabel");
+ qmlRegisterType(QUrl(prefix + "/Private/Handle.qml"), private_uri, 1, 0, "Handle");
+ qmlRegisterType(QUrl(prefix + "/Private/PieMenuIcon.qml"), private_uri, 1, 0, "PieMenuIcon");
+ qmlRegisterSingletonType(QUrl(prefix + "/Private/TextSingleton.qml"), private_uri, 1, 0, "TextSingleton");
+}
+
+QObject *QtQuickExtrasPlugin::registerSettingsModule(QQmlEngine *engine, QJSEngine *jsEngine)
+{
+ Q_UNUSED(engine);
+ Q_UNUSED(jsEngine);
+ return new QQuickStyleSettings(engine);
+}
+
+QT_END_NAMESPACE
diff --git a/src/extras/plugin.h b/src/extras/plugin.h
new file mode 100644
index 00000000..c613739f
--- /dev/null
+++ b/src/extras/plugin.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PLUGIN_H
+#define PLUGIN_H
+
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+#include <QtQml/qqmlengine.h>
+
+QT_BEGIN_NAMESPACE
+
+class QtQuickExtrasPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
+public:
+ explicit QtQuickExtrasPlugin(QObject *parent = 0);
+
+ void registerTypes(const char *uri);
+ void initializeEngine(QQmlEngine *engine, const char *uri);
+private:
+ static QObject *registerSettingsModule(QQmlEngine *engine, QJSEngine *jsEngine);
+};
+
+QT_END_NAMESPACE
+
+#endif // PLUGIN_H
diff --git a/src/extras/plugins.qmltypes b/src/extras/plugins.qmltypes
new file mode 100644
index 00000000..3421236e
--- /dev/null
+++ b/src/extras/plugins.qmltypes
@@ -0,0 +1,619 @@
+import QtQuick.tooling 1.1
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated by:
+// 'qmlplugindump -nonrelocatable QtQuick.Extras 1.3'
+
+Module {
+ Component {
+ name: "QQuickActivationMode"
+ exports: ["QtQuick.Extras/ActivationMode 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "ActivationMode"
+ values: {
+ "ActivateOnPress": 0,
+ "ActivateOnRelease": 1,
+ "ActivateOnClick": 2
+ }
+ }
+ }
+ Component {
+ name: "QQuickCircularProgressBar"
+ defaultProperty: "data"
+ prototype: "QQuickPaintedItem"
+ exports: ["QtQuick.Extras.Private.CppUtils/CircularProgressBar 1.1"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "progress"; type: "double" }
+ Property { name: "barWidth"; type: "double" }
+ Property { name: "inset"; type: "double" }
+ Property { name: "minimumValueAngle"; type: "double" }
+ Property { name: "maximumValueAngle"; type: "double" }
+ Property { name: "backgroundColor"; type: "QColor" }
+ Signal {
+ name: "progressChanged"
+ Parameter { name: "progress"; type: "double" }
+ }
+ Signal {
+ name: "barWidthChanged"
+ Parameter { name: "barWidth"; type: "double" }
+ }
+ Signal {
+ name: "insetChanged"
+ Parameter { name: "inset"; type: "double" }
+ }
+ Signal {
+ name: "minimumValueAngleChanged"
+ Parameter { name: "minimumValueAngle"; type: "double" }
+ }
+ Signal {
+ name: "maximumValueAngleChanged"
+ Parameter { name: "maximumValueAngle"; type: "double" }
+ }
+ Signal {
+ name: "backgroundColorChanged"
+ Parameter { name: "backgroundColor"; type: "QColor" }
+ }
+ Method { name: "clearStops" }
+ Method {
+ name: "addStop"
+ Parameter { name: "position"; type: "double" }
+ Parameter { name: "color"; type: "QColor" }
+ }
+ Method { name: "redraw" }
+ }
+ Component {
+ name: "QQuickFlatProgressBar"
+ defaultProperty: "data"
+ prototype: "QQuickPaintedItem"
+ exports: ["QtQuick.Extras.Private.CppUtils/FlatProgressBar 1.1"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "stripeOffset"; type: "double" }
+ Property { name: "progress"; type: "double" }
+ Property { name: "indeterminate"; type: "bool" }
+ Signal {
+ name: "stripeOffsetChanged"
+ Parameter { name: "stripeOffset"; type: "double" }
+ }
+ Signal {
+ name: "progressChanged"
+ Parameter { name: "progress"; type: "double" }
+ }
+ Signal {
+ name: "indeterminateChanged"
+ Parameter { name: "indeterminate"; type: "bool" }
+ }
+ Method { name: "repaint" }
+ Method { name: "restartAnimation" }
+ Method { name: "onVisibleChanged" }
+ Method { name: "onWidthChanged" }
+ Method { name: "onHeightChanged" }
+ }
+ Component {
+ name: "QQuickMathUtils"
+ prototype: "QObject"
+ exports: ["QtQuick.Extras.Private.CppUtils/MathUtils 1.0"]
+ isCreatable: false
+ isSingleton: true
+ exportMetaObjectRevisions: [0]
+ Property { name: "pi2"; type: "double"; isReadonly: true }
+ Method {
+ name: "degToRad"
+ type: "double"
+ Parameter { name: "degrees"; type: "double" }
+ }
+ Method {
+ name: "degToRadOffset"
+ type: "double"
+ Parameter { name: "degrees"; type: "double" }
+ }
+ Method {
+ name: "radToDeg"
+ type: "double"
+ Parameter { name: "radians"; type: "double" }
+ }
+ Method {
+ name: "radToDegOffset"
+ type: "double"
+ Parameter { name: "radians"; type: "double" }
+ }
+ Method {
+ name: "centerAlongCircle"
+ type: "QPointF"
+ Parameter { name: "xCenter"; type: "double" }
+ Parameter { name: "yCenter"; type: "double" }
+ Parameter { name: "width"; type: "double" }
+ Parameter { name: "height"; type: "double" }
+ Parameter { name: "angleOnCircle"; type: "double" }
+ Parameter { name: "distanceAlongRadius"; type: "double" }
+ }
+ Method {
+ name: "roundEven"
+ type: "double"
+ Parameter { name: "number"; type: "double" }
+ }
+ }
+ Component {
+ name: "QQuickMouseThief"
+ prototype: "QObject"
+ exports: ["QtQuick.Extras.Private.CppUtils/MouseThief 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "receivedPressEvent"; type: "bool" }
+ Signal {
+ name: "pressed"
+ Parameter { name: "mouseX"; type: "int" }
+ Parameter { name: "mouseY"; type: "int" }
+ }
+ Signal {
+ name: "released"
+ Parameter { name: "mouseX"; type: "int" }
+ Parameter { name: "mouseY"; type: "int" }
+ }
+ Signal {
+ name: "clicked"
+ Parameter { name: "mouseX"; type: "int" }
+ Parameter { name: "mouseY"; type: "int" }
+ }
+ Signal {
+ name: "touchUpdate"
+ Parameter { name: "mouseX"; type: "int" }
+ Parameter { name: "mouseY"; type: "int" }
+ }
+ Signal { name: "handledEventChanged" }
+ Method {
+ name: "grabMouse"
+ Parameter { name: "item"; type: "QQuickItem"; isPointer: true }
+ }
+ Method { name: "ungrabMouse" }
+ Method { name: "acceptCurrentEvent" }
+ }
+ Component {
+ name: "QQuickPicture"
+ defaultProperty: "data"
+ prototype: "QQuickPaintedItem"
+ exports: ["QtQuick.Extras/Picture 1.3"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "source"; type: "QUrl" }
+ Property { name: "color"; type: "QColor" }
+ }
+ Component {
+ name: "QQuickStyleSettings"
+ prototype: "QObject"
+ exports: ["QtQuick.Extras.Private/StyleSettings 1.0"]
+ isCreatable: false
+ isSingleton: true
+ exportMetaObjectRevisions: [0]
+ Property { name: "style"; type: "QUrl"; isReadonly: true }
+ Property { name: "styleName"; type: "string" }
+ Property { name: "stylePath"; type: "string" }
+ }
+ Component {
+ name: "QQuickTriggerMode"
+ exports: ["QtQuick.Extras/TriggerMode 1.3"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "TriggerMode"
+ values: {
+ "TriggerOnPress": 0,
+ "TriggerOnRelease": 1,
+ "TriggerOnClick": 2
+ }
+ }
+ }
+ Component {
+ prototype: "QQuickFocusScope"
+ name: "QtQuick.Extras.Private/CircularButton"
+ exports: ["QtQuick.Extras.Private/CircularButton 1.0"]
+ exportMetaObjectRevisions: [0]
+ isComposite: true
+ defaultProperty: "data"
+ Property { name: "isDefault"; type: "bool" }
+ Property { name: "menu"; type: "Menu_QMLTYPE_29"; isPointer: true }
+ Property { name: "checkable"; type: "bool" }
+ Property { name: "checked"; type: "bool" }
+ Property { name: "exclusiveGroup"; type: "QQuickExclusiveGroup"; isPointer: true }
+ Property { name: "action"; type: "QQuickAction"; isPointer: true }
+ Property { name: "activeFocusOnPress"; type: "bool" }
+ Property { name: "text"; type: "string" }
+ Property { name: "tooltip"; type: "string" }
+ Property { name: "iconSource"; type: "QUrl" }
+ Property { name: "iconName"; type: "string" }
+ Property { name: "__position"; type: "string" }
+ Property { name: "__iconOverriden"; type: "bool"; isReadonly: true }
+ Property { name: "__action"; type: "QQuickAction"; isPointer: true }
+ Property { name: "__iconAction"; type: "QQuickAction"; isReadonly: true; isPointer: true }
+ Property { name: "__effectivePressed"; type: "bool" }
+ Property { name: "__behavior"; type: "QVariant" }
+ Property { name: "pressed"; type: "bool"; isReadonly: true }
+ Property { name: "hovered"; type: "bool"; isReadonly: true }
+ Signal { name: "clicked" }
+ Method { name: "accessiblePressAction"; type: "QVariant" }
+ Property { name: "style"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "__style"; type: "QObject"; isPointer: true }
+ Property { name: "__panel"; type: "QQuickItem"; isPointer: true }
+ Property { name: "styleHints"; type: "QVariant" }
+ Property { name: "__styleData"; type: "QObject"; isPointer: true }
+ }
+ Component {
+ prototype: "QObject"
+ name: "QtQuick.Extras.Private/CircularButtonStyleHelper"
+ exports: ["QtQuick.Extras.Private/CircularButtonStyleHelper 1.0"]
+ exportMetaObjectRevisions: [0]
+ isComposite: true
+ Property { name: "control"; type: "QQuickItem"; isPointer: true }
+ Property { name: "buttonColorUpTop"; type: "QColor" }
+ Property { name: "buttonColorUpBottom"; type: "QColor" }
+ Property { name: "buttonColorDownTop"; type: "QColor" }
+ Property { name: "buttonColorDownBottom"; type: "QColor" }
+ Property { name: "outerArcColorTop"; type: "QColor" }
+ Property { name: "outerArcColorBottom"; type: "QColor" }
+ Property { name: "innerArcColorTop"; type: "QColor" }
+ Property { name: "innerArcColorBottom"; type: "QColor" }
+ Property { name: "innerArcColorBottomStop"; type: "double" }
+ Property { name: "shineColor"; type: "QColor" }
+ Property { name: "smallestAxis"; type: "double" }
+ Property { name: "outerArcLineWidth"; type: "double" }
+ Property { name: "innerArcLineWidth"; type: "double" }
+ Property { name: "shineArcLineWidth"; type: "double" }
+ Property { name: "implicitWidth"; type: "double" }
+ Property { name: "implicitHeight"; type: "double" }
+ Property { name: "textColorUp"; type: "QColor" }
+ Property { name: "textColorDown"; type: "QColor" }
+ Property { name: "textRaisedColorUp"; type: "QColor" }
+ Property { name: "textRaisedColorDown"; type: "QColor" }
+ Property { name: "radius"; type: "double" }
+ Property { name: "halfRadius"; type: "double" }
+ Property { name: "outerArcRadius"; type: "double" }
+ Property { name: "innerArcRadius"; type: "double" }
+ Property { name: "shineArcRadius"; type: "double" }
+ Property { name: "zeroAngle"; type: "double" }
+ Property { name: "buttonColorTop"; type: "QColor" }
+ Property { name: "buttonColorBottom"; type: "QColor" }
+ Method {
+ name: "toPixels"
+ type: "QVariant"
+ Parameter { name: "percentageOfSmallestAxis"; type: "QVariant" }
+ }
+ Method {
+ name: "paintBackground"
+ type: "QVariant"
+ Parameter { name: "ctx"; type: "QVariant" }
+ }
+ }
+ Component {
+ prototype: "QQuickFocusScope"
+ name: "QtQuick.Extras/CircularGauge"
+ exports: ["QtQuick.Extras/CircularGauge 1.0"]
+ exportMetaObjectRevisions: [0]
+ isComposite: true
+ defaultProperty: "data"
+ Property { name: "tickmarksVisible"; type: "bool" }
+ Property { name: "minimumValue"; type: "double" }
+ Property { name: "maximumValue"; type: "double" }
+ Property { name: "value"; type: "double" }
+ Property { name: "stepSize"; type: "double" }
+ Property { name: "style"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "__style"; type: "QObject"; isPointer: true }
+ Property { name: "__panel"; type: "QQuickItem"; isPointer: true }
+ Property { name: "styleHints"; type: "QVariant" }
+ Property { name: "__styleData"; type: "QObject"; isPointer: true }
+ }
+ Component {
+ prototype: "QQuickFocusScope"
+ name: "QtQuick.Extras.Private/CircularTickmarkLabel"
+ exports: ["QtQuick.Extras.Private/CircularTickmarkLabel 1.0"]
+ exportMetaObjectRevisions: [0]
+ isComposite: true
+ defaultProperty: "data"
+ Property { name: "minimumValueAngle"; type: "double" }
+ Property { name: "maximumValueAngle"; type: "double" }
+ Property { name: "angleRange"; type: "double"; isReadonly: true }
+ Property { name: "tickmarkStepSize"; type: "double" }
+ Property { name: "tickmarkInset"; type: "double" }
+ Property { name: "tickmarkCount"; type: "int"; isReadonly: true }
+ Property { name: "minorTickmarkCount"; type: "int" }
+ Property { name: "minorTickmarkInset"; type: "double" }
+ Property { name: "labelInset"; type: "double" }
+ Property { name: "labelStepSize"; type: "double" }
+ Property { name: "labelCount"; type: "int"; isReadonly: true }
+ Property { name: "__tickmarkCount"; type: "double"; isReadonly: true }
+ Property { name: "tickmarksVisible"; type: "bool" }
+ Property { name: "minimumValue"; type: "double" }
+ Property { name: "maximumValue"; type: "double" }
+ Property { name: "stepSize"; type: "double" }
+ Method {
+ name: "valueToAngle"
+ type: "QVariant"
+ Parameter { name: "value"; type: "QVariant" }
+ }
+ Property { name: "style"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "__style"; type: "QObject"; isPointer: true }
+ Property { name: "__panel"; type: "QQuickItem"; isPointer: true }
+ Property { name: "styleHints"; type: "QVariant" }
+ Property { name: "__styleData"; type: "QObject"; isPointer: true }
+ }
+ Component {
+ prototype: "QQuickFocusScope"
+ name: "QtQuick.Extras/DelayButton"
+ exports: ["QtQuick.Extras/DelayButton 1.0"]
+ exportMetaObjectRevisions: [0]
+ isComposite: true
+ defaultProperty: "data"
+ Property { name: "delay"; type: "int" }
+ Property { name: "__progress"; type: "double" }
+ Property { name: "progress"; type: "double"; isReadonly: true }
+ Signal { name: "activated" }
+ Property { name: "isDefault"; type: "bool" }
+ Property { name: "menu"; type: "Menu_QMLTYPE_29"; isPointer: true }
+ Property { name: "checkable"; type: "bool" }
+ Property { name: "checked"; type: "bool" }
+ Property { name: "exclusiveGroup"; type: "QQuickExclusiveGroup"; isPointer: true }
+ Property { name: "action"; type: "QQuickAction"; isPointer: true }
+ Property { name: "activeFocusOnPress"; type: "bool" }
+ Property { name: "text"; type: "string" }
+ Property { name: "tooltip"; type: "string" }
+ Property { name: "iconSource"; type: "QUrl" }
+ Property { name: "iconName"; type: "string" }
+ Property { name: "__position"; type: "string" }
+ Property { name: "__iconOverriden"; type: "bool"; isReadonly: true }
+ Property { name: "__action"; type: "QQuickAction"; isPointer: true }
+ Property { name: "__iconAction"; type: "QQuickAction"; isReadonly: true; isPointer: true }
+ Property { name: "__effectivePressed"; type: "bool" }
+ Property { name: "__behavior"; type: "QVariant" }
+ Property { name: "pressed"; type: "bool"; isReadonly: true }
+ Property { name: "hovered"; type: "bool"; isReadonly: true }
+ Signal { name: "clicked" }
+ Method { name: "accessiblePressAction"; type: "QVariant" }
+ Property { name: "style"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "__style"; type: "QObject"; isPointer: true }
+ Property { name: "__panel"; type: "QQuickItem"; isPointer: true }
+ Property { name: "styleHints"; type: "QVariant" }
+ Property { name: "__styleData"; type: "QObject"; isPointer: true }
+ }
+ Component {
+ prototype: "QQuickFocusScope"
+ name: "QtQuick.Extras/Dial"
+ exports: ["QtQuick.Extras/Dial 1.1"]
+ exportMetaObjectRevisions: [1]
+ isComposite: true
+ defaultProperty: "data"
+ Property { name: "__wrap"; type: "bool" }
+ Property { name: "activeFocusOnPress"; type: "bool" }
+ Property { name: "tickmarksVisible"; type: "bool" }
+ Property { name: "value"; type: "double" }
+ Property { name: "minimumValue"; type: "double" }
+ Property { name: "maximumValue"; type: "double" }
+ Property { name: "hovered"; type: "bool"; isReadonly: true }
+ Property { name: "stepSize"; type: "double" }
+ Property { name: "pressed"; type: "bool"; isReadonly: true }
+ Property { name: "style"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "__style"; type: "QObject"; isPointer: true }
+ Property { name: "__panel"; type: "QQuickItem"; isPointer: true }
+ Property { name: "styleHints"; type: "QVariant" }
+ Property { name: "__styleData"; type: "QObject"; isPointer: true }
+ }
+ Component {
+ prototype: "QQuickFocusScope"
+ name: "QtQuick.Extras/Gauge"
+ exports: ["QtQuick.Extras/Gauge 1.0"]
+ exportMetaObjectRevisions: [0]
+ isComposite: true
+ defaultProperty: "data"
+ Property { name: "orientation"; type: "int" }
+ Property { name: "tickmarkAlignment"; type: "int" }
+ Property { name: "__tickmarkAlignment"; type: "int" }
+ Property { name: "__tickmarksInside"; type: "bool" }
+ Property { name: "tickmarkStepSize"; type: "double" }
+ Property { name: "minorTickmarkCount"; type: "int" }
+ Property { name: "formatValue"; type: "QVariant" }
+ Property { name: "minimumValue"; type: "double" }
+ Property { name: "value"; type: "double" }
+ Property { name: "maximumValue"; type: "double" }
+ Property { name: "font"; type: "QFont" }
+ Property { name: "__hiddenText"; type: "QQuickText"; isReadonly: true; isPointer: true }
+ Property { name: "style"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "__style"; type: "QObject"; isPointer: true }
+ Property { name: "__panel"; type: "QQuickItem"; isPointer: true }
+ Property { name: "styleHints"; type: "QVariant" }
+ Property { name: "__styleData"; type: "QObject"; isPointer: true }
+ }
+ Component {
+ prototype: "QQuickFocusScope"
+ name: "QtQuick.Extras/PieMenu"
+ exports: ["QtQuick.Extras/PieMenu 1.0"]
+ exportMetaObjectRevisions: [0]
+ isComposite: true
+ defaultProperty: "menuItems"
+ Property { name: "selectionAngle"; type: "double"; isReadonly: true }
+ Property { name: "triggerMode"; type: "int" }
+ Property { name: "title"; type: "string" }
+ Property { name: "boundingItem"; type: "QQuickItem"; isPointer: true }
+ Property { name: "__protectedScope"; type: "QObject"; isPointer: true }
+ Property { name: "activationMode"; type: "int" }
+ Property { name: "menuItems"; type: "QQuickMenuItem"; isList: true; isReadonly: true }
+ Property { name: "currentIndex"; type: "int"; isReadonly: true }
+ Property { name: "currentItem"; type: "QQuickMenuItem"; isReadonly: true; isPointer: true }
+ Property { name: "__mouseThief"; type: "QQuickMouseThief"; isReadonly: true; isPointer: true }
+ Method {
+ name: "popup"
+ type: "QVariant"
+ Parameter { name: "x"; type: "QVariant" }
+ Parameter { name: "y"; type: "QVariant" }
+ }
+ Method {
+ name: "addItem"
+ type: "QVariant"
+ Parameter { name: "text"; type: "QVariant" }
+ }
+ Method {
+ name: "insertItem"
+ type: "QVariant"
+ Parameter { name: "before"; type: "QVariant" }
+ Parameter { name: "text"; type: "QVariant" }
+ }
+ Method {
+ name: "removeItem"
+ type: "QVariant"
+ Parameter { name: "item"; type: "QVariant" }
+ }
+ Property { name: "style"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "__style"; type: "QObject"; isPointer: true }
+ Property { name: "__panel"; type: "QQuickItem"; isPointer: true }
+ Property { name: "styleHints"; type: "QVariant" }
+ Property { name: "__styleData"; type: "QObject"; isPointer: true }
+ }
+ Component {
+ prototype: "QQuickLoader"
+ name: "QtQuick.Extras.Private/PieMenuIcon"
+ exports: ["QtQuick.Extras.Private/PieMenuIcon 1.0"]
+ exportMetaObjectRevisions: [0]
+ isComposite: true
+ defaultProperty: "data"
+ Property { name: "control"; type: "PieMenu_QMLTYPE_93"; isPointer: true }
+ Property { name: "styleData"; type: "QObject"; isPointer: true }
+ Property { name: "iconSource"; type: "string"; isReadonly: true }
+ }
+ Component {
+ prototype: "QQuickFocusScope"
+ name: "QtQuick.Extras/StatusIndicator"
+ exports: ["QtQuick.Extras/StatusIndicator 1.1"]
+ exportMetaObjectRevisions: [1]
+ isComposite: true
+ defaultProperty: "data"
+ Property { name: "active"; type: "bool" }
+ Property { name: "color"; type: "QColor" }
+ Property { name: "on"; type: "bool" }
+ Property { name: "style"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "__style"; type: "QObject"; isPointer: true }
+ Property { name: "__panel"; type: "QQuickItem"; isPointer: true }
+ Property { name: "styleHints"; type: "QVariant" }
+ Property { name: "__styleData"; type: "QObject"; isPointer: true }
+ }
+ Component {
+ prototype: "QQuickText"
+ name: "QtQuick.Extras.Private/TextSingleton"
+ exports: ["QtQuick.Extras.Private/TextSingleton 1.0"]
+ exportMetaObjectRevisions: [0]
+ isComposite: true
+ isCreatable: false
+ isSingleton: true
+ defaultProperty: "data"
+ }
+ Component {
+ prototype: "QQuickFocusScope"
+ name: "QtQuick.Extras/ToggleButton"
+ exports: ["QtQuick.Extras/ToggleButton 1.0"]
+ exportMetaObjectRevisions: [0]
+ isComposite: true
+ defaultProperty: "data"
+ Property { name: "isDefault"; type: "bool" }
+ Property { name: "menu"; type: "Menu_QMLTYPE_29"; isPointer: true }
+ Property { name: "checkable"; type: "bool" }
+ Property { name: "checked"; type: "bool" }
+ Property { name: "exclusiveGroup"; type: "QQuickExclusiveGroup"; isPointer: true }
+ Property { name: "action"; type: "QQuickAction"; isPointer: true }
+ Property { name: "activeFocusOnPress"; type: "bool" }
+ Property { name: "text"; type: "string" }
+ Property { name: "tooltip"; type: "string" }
+ Property { name: "iconSource"; type: "QUrl" }
+ Property { name: "iconName"; type: "string" }
+ Property { name: "__position"; type: "string" }
+ Property { name: "__iconOverriden"; type: "bool"; isReadonly: true }
+ Property { name: "__action"; type: "QQuickAction"; isPointer: true }
+ Property { name: "__iconAction"; type: "QQuickAction"; isReadonly: true; isPointer: true }
+ Property { name: "__effectivePressed"; type: "bool" }
+ Property { name: "__behavior"; type: "QVariant" }
+ Property { name: "pressed"; type: "bool"; isReadonly: true }
+ Property { name: "hovered"; type: "bool"; isReadonly: true }
+ Signal { name: "clicked" }
+ Method { name: "accessiblePressAction"; type: "QVariant" }
+ Property { name: "style"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "__style"; type: "QObject"; isPointer: true }
+ Property { name: "__panel"; type: "QQuickItem"; isPointer: true }
+ Property { name: "styleHints"; type: "QVariant" }
+ Property { name: "__styleData"; type: "QObject"; isPointer: true }
+ }
+ Component {
+ prototype: "QQuickFocusScope"
+ name: "QtQuick.Extras/Tumbler"
+ exports: ["QtQuick.Extras/Tumbler 1.2"]
+ exportMetaObjectRevisions: [2]
+ isComposite: true
+ defaultProperty: "data"
+ Property { name: "__highlightMoveDuration"; type: "int" }
+ Property { name: "columnCount"; type: "int"; isReadonly: true }
+ Property { name: "__columnRow"; type: "QQuickRow"; isReadonly: true; isPointer: true }
+ Property { name: "__movementDelayTimer"; type: "QQmlTimer"; isReadonly: true; isPointer: true }
+ Method {
+ name: "__isValidColumnIndex"
+ type: "QVariant"
+ Parameter { name: "index"; type: "QVariant" }
+ }
+ Method {
+ name: "__isValidColumnAndItemIndex"
+ type: "QVariant"
+ Parameter { name: "columnIndex"; type: "QVariant" }
+ Parameter { name: "itemIndex"; type: "QVariant" }
+ }
+ Method {
+ name: "currentIndexAt"
+ type: "QVariant"
+ Parameter { name: "columnIndex"; type: "QVariant" }
+ }
+ Method {
+ name: "setCurrentIndexAt"
+ type: "QVariant"
+ Parameter { name: "columnIndex"; type: "QVariant" }
+ Parameter { name: "itemIndex"; type: "QVariant" }
+ }
+ Method {
+ name: "getColumn"
+ type: "QVariant"
+ Parameter { name: "columnIndex"; type: "QVariant" }
+ }
+ Method {
+ name: "addColumn"
+ type: "QVariant"
+ Parameter { name: "column"; type: "QVariant" }
+ }
+ Method {
+ name: "insertColumn"
+ type: "QVariant"
+ Parameter { name: "index"; type: "QVariant" }
+ Parameter { name: "column"; type: "QVariant" }
+ }
+ Method {
+ name: "__viewAt"
+ type: "QVariant"
+ Parameter { name: "index"; type: "QVariant" }
+ }
+ Property { name: "style"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "__style"; type: "QObject"; isPointer: true }
+ Property { name: "__panel"; type: "QQuickItem"; isPointer: true }
+ Property { name: "styleHints"; type: "QVariant" }
+ Property { name: "__styleData"; type: "QObject"; isPointer: true }
+ }
+ Component {
+ prototype: "QObject"
+ name: "QtQuick.Extras/TumblerColumn"
+ exports: ["QtQuick.Extras/TumblerColumn 1.2"]
+ exportMetaObjectRevisions: [2]
+ isComposite: true
+ Property { name: "__tumbler"; type: "QQuickItem"; isPointer: true }
+ Property { name: "__index"; type: "int" }
+ Property { name: "__currentIndex"; type: "int" }
+ Property { name: "role"; type: "string" }
+ Property { name: "delegate"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "highlight"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "columnForeground"; type: "QQmlComponent"; isPointer: true }
+ Property { name: "visible"; type: "bool" }
+ Property { name: "activeFocus"; type: "bool"; isReadonly: true }
+ Property { name: "width"; type: "double" }
+ Property { name: "model"; type: "QVariant" }
+ Property { name: "currentIndex"; type: "int"; isReadonly: true }
+ }
+}
diff --git a/src/extras/qmldir b/src/extras/qmldir
new file mode 100644
index 00000000..8cf21310
--- /dev/null
+++ b/src/extras/qmldir
@@ -0,0 +1,4 @@
+module QtQuick.Extras
+plugin qtquickextrasplugin
+classname QtQuickExtrasPlugin
+#typeinfo plugins.qmltypes
diff --git a/src/extras/qquickpicture.cpp b/src/extras/qquickpicture.cpp
new file mode 100644
index 00000000..fd8846a2
--- /dev/null
+++ b/src/extras/qquickpicture.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickpicture_p.h"
+
+#include <QQmlFile>
+
+/*!
+ \qmltype Picture
+ \inherits QQuickPaintedItem
+ \inqmlmodule QtQuick.Extras
+ \since QtQuick.Extras 1.4
+ \ingroup extras
+ \ingroup extras-non-interactive
+ \brief An indicator that displays a colorized ISO 7000 icon
+
+ Picture displays icons in a scalable vector format. It can also colorize
+ the icons via the \l color property.
+
+ The icon to display is set with the \l source property.
+*/
+
+QQuickPicture::QQuickPicture(QQuickItem *parent)
+ : QQuickPaintedItem(parent)
+{
+ const qreal defaultFontHeight = QFontMetricsF(QFont()).height();
+ setImplicitWidth(defaultFontHeight * 4);
+ setImplicitHeight(defaultFontHeight * 4);
+}
+
+QQuickPicture::~QQuickPicture()
+{
+}
+
+void QQuickPicture::paint(QPainter *painter)
+{
+ const QSize size = boundingRect().size().toSize();
+ // Don't want the scale to apply to the fill.
+ painter->save();
+ painter->scale(qreal(size.width()) / mPicture.boundingRect().width(),
+ qreal(size.height()) / mPicture.boundingRect().height());
+ painter->drawPicture(0, 0, mPicture);
+ painter->restore();
+
+ if (mColor.isValid()) {
+ painter->setCompositionMode(QPainter::CompositionMode_SourceIn);
+ painter->fillRect(0, 0, size.width(), size.height(), mColor);
+ }
+}
+
+/*!
+ \qmlproperty url Picture::source
+
+ This property specifies the URL of the icon to use. The URL must point to a
+ local file that contains \l QPicture data.
+
+ For example, if you have the \l <NewControlName> from \l
+ <NewEnterpriseControlsName>, you can specify the following URL:
+
+ \code
+ "qrc:/iso-icons/iso_grs_7000_4_0001.dat"
+ \endcode
+
+ Due to the
+ \l {http://www.iso.org/iso/home/store/catalogue_tc/catalogue_detail.htm?csnumber=65977}
+ {large selection of icons} available in this package, it is advisable to
+ use Qt Creator's Qt Quick Designer tool to browse and select icons, as this
+ property will then be set automatically.
+
+ If you have your own picture that you'd like to display, you can set the
+ following URL:
+
+ \code
+ "mypicture.dat"
+ \endcode
+*/
+QUrl QQuickPicture::source() const
+{
+ return mSource;
+}
+
+void QQuickPicture::setSource(const QUrl &source)
+{
+ if (mSource != source) {
+ mSource = source;
+ const QString fileName = QQmlFile::urlToLocalFileOrQrc(source);
+ if (!mPicture.load(fileName)) {
+ qWarning().nospace() << "Failed to load " << fileName << "; does it exist?";
+ mPicture = QPicture();
+ }
+
+ setImplicitWidth(mPicture.boundingRect().width());
+ setImplicitHeight(mPicture.boundingRect().height());
+
+ update();
+ emit sourceChanged();
+ }
+}
+
+/*!
+ \qmlproperty color Picture::color
+
+ This property specifies the color of the indicator.
+
+ The default value is \c "black".
+*/
+QColor QQuickPicture::color() const
+{
+ return mColor;
+}
+
+void QQuickPicture::setColor(const QColor &color)
+{
+ if (mColor != color) {
+ mColor = color;
+ update();
+ emit colorChanged();
+ }
+}
+
+void QQuickPicture::resetColor()
+{
+ setColor(QColor());
+}
+
diff --git a/src/extras/qquickpicture_p.h b/src/extras/qquickpicture_p.h
new file mode 100644
index 00000000..ee299cd2
--- /dev/null
+++ b/src/extras/qquickpicture_p.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPICTURE_H
+#define QQUICKPICTURE_H
+
+#include <QQuickPaintedItem>
+#include <QPainter>
+#include <QPicture>
+
+class QQuickPicture : public QQuickPaintedItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged RESET resetColor)
+public:
+ explicit QQuickPicture(QQuickItem *parent = 0);
+ ~QQuickPicture();
+
+ void paint(QPainter *painter) Q_DECL_OVERRIDE;
+
+ QUrl source() const;
+ void setSource(const QUrl &source);
+
+ QColor color() const;
+ void setColor(const QColor &color);
+ void resetColor();
+
+Q_SIGNALS:
+ void sourceChanged();
+ void colorChanged();
+
+private:
+ QUrl mSource;
+ QColor mColor;
+ QPicture mPicture;
+};
+
+#endif // QQUICKPICTURE_H
diff --git a/src/extras/qquicktriggermode_p.h b/src/extras/qquicktriggermode_p.h
new file mode 100644
index 00000000..a6f2f404
--- /dev/null
+++ b/src/extras/qquicktriggermode_p.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TRIGGERMODE_P_H
+#define TRIGGERMODE_P_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qobjectdefs.h>
+
+QT_BEGIN_NAMESPACE
+
+// TODO: Remove with v2.0
+class QQuickActivationMode
+{
+ Q_GADGET
+ Q_ENUMS(ActivationMode)
+public:
+ enum ActivationMode {
+ ActivateOnPress = 0,
+ ActivateOnRelease = 1,
+ ActivateOnClick = 2
+ };
+};
+
+class QQuickTriggerMode
+{
+ Q_GADGET
+ Q_ENUMS(TriggerMode)
+public:
+ enum TriggerMode {
+ TriggerOnPress = 0,
+ TriggerOnRelease = 1,
+ TriggerOnClick = 2
+ };
+};
+
+QT_END_NAMESPACE
+
+#endif // TRIGGERMODE_P_H
diff --git a/src/src.pro b/src/src.pro
index 17e0445f..ecbf28b9 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -7,6 +7,9 @@ winrt: SUBDIRS += controls/Styles/WinRT
SUBDIRS += layouts
+SUBDIRS += extras
+SUBDIRS += extras/Styles/styles.pro
+
SUBDIRS += dialogs
SUBDIRS += dialogs/Private
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 810b4678..de1b45b6 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -1,3 +1,3 @@
TEMPLATE = subdirs
-SUBDIRS += testplugin controls activeFocusOnTab applicationwindow dialogs
+SUBDIRS += testplugin controls activeFocusOnTab applicationwindow dialogs extras paint
controls.depends = testplugin
diff --git a/tests/auto/extras/data/PieMenu3Items.qml b/tests/auto/extras/data/PieMenu3Items.qml
new file mode 100644
index 00000000..f9349e63
--- /dev/null
+++ b/tests/auto/extras/data/PieMenu3Items.qml
@@ -0,0 +1,53 @@
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Extras 1.3
+
+Rectangle {
+ id: rect
+ anchors.fill: parent
+
+ signal actionTriggered(int index)
+
+ property alias mouseArea: area
+
+ MouseArea {
+ id: area
+ anchors.fill: parent
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+ onPressed: {
+ if (menu.triggerMode === TriggerMode.TriggerOnRelease)
+ pieMenu.popup(mouseX, mouseY);
+ }
+
+ onClicked: {
+ if (menu.triggerMode !== TriggerMode.TriggerOnRelease)
+ pieMenu.popup(mouseX, mouseY);
+ }
+ }
+
+ property alias pieMenu: menu
+
+ PieMenu {
+ id: menu
+ width: 200
+ height: 200
+
+ MenuItem {
+ text: "Action 1"
+ onTriggered: actionTriggered(0)
+ }
+ MenuItem {
+ text: "Action 2"
+ onTriggered: actionTriggered(1)
+ }
+ MenuItem {
+ text: "Action 3"
+ onTriggered: actionTriggered(2)
+ }
+ }
+ Rectangle {
+ anchors.fill: menu
+ color: "transparent"
+ border.color: "black"
+ }
+}
diff --git a/tests/auto/extras/data/PieMenu3ItemsKeepOpen.qml b/tests/auto/extras/data/PieMenu3ItemsKeepOpen.qml
new file mode 100644
index 00000000..ffbfa20a
--- /dev/null
+++ b/tests/auto/extras/data/PieMenu3ItemsKeepOpen.qml
@@ -0,0 +1,54 @@
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Extras 1.3
+
+Rectangle {
+ id: rect
+ anchors.fill: parent
+
+ signal actionTriggered(int index)
+
+ property alias mouseArea: area
+
+ MouseArea {
+ id: area
+ anchors.fill: parent
+ acceptedButtons: Qt.LeftButton
+ onClicked: pieMenu.popup(mouseX, mouseY);
+ }
+
+ property alias pieMenu: menu
+
+ PieMenu {
+ id: menu
+ width: 200
+ height: 200
+
+ MenuItem {
+ text: "Action 1"
+ onTriggered: {
+ menu.visible = true;
+ actionTriggered(0);
+ }
+ }
+ MenuItem {
+ text: "Action 2"
+ onTriggered: {
+ menu.visible = true;
+ actionTriggered(1);
+ }
+ }
+ MenuItem {
+ text: "Action 3"
+ onTriggered: {
+ menu.visible = true;
+ actionTriggered(2);
+ }
+ }
+ }
+ Rectangle {
+ anchors.fill: menu
+ color: "transparent"
+ border.color: "black"
+ }
+}
diff --git a/tests/auto/extras/data/PieMenu3ItemsLongPress.qml b/tests/auto/extras/data/PieMenu3ItemsLongPress.qml
new file mode 100644
index 00000000..fddc5460
--- /dev/null
+++ b/tests/auto/extras/data/PieMenu3ItemsLongPress.qml
@@ -0,0 +1,44 @@
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Extras 1.3
+
+Rectangle {
+ id: rect
+ anchors.fill: parent
+
+ signal actionTriggered(int index)
+
+ property alias mouseArea: area
+
+ MouseArea {
+ id: area
+ anchors.fill: parent
+ onPressAndHold: pieMenu.popup(mouseX, mouseY)
+ }
+
+ property alias pieMenu: menu
+
+ PieMenu {
+ id: menu
+ width: 200
+ height: 200
+
+ MenuItem {
+ text: "Action 1"
+ onTriggered: actionTriggered(0)
+ }
+ MenuItem {
+ text: "Action 2"
+ onTriggered: actionTriggered(1)
+ }
+ MenuItem {
+ text: "Action 3"
+ onTriggered: actionTriggered(2)
+ }
+ }
+ Rectangle {
+ anchors.fill: menu
+ color: "transparent"
+ border.color: "black"
+ }
+}
diff --git a/tests/auto/extras/data/PieMenuBoundingItem.qml b/tests/auto/extras/data/PieMenuBoundingItem.qml
new file mode 100644
index 00000000..3daf0f19
--- /dev/null
+++ b/tests/auto/extras/data/PieMenuBoundingItem.qml
@@ -0,0 +1,51 @@
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Extras 1.3
+
+Rectangle {
+ id: root
+ anchors.fill: parent
+ color: "black"
+
+ property alias mouseArea: area
+
+ property alias pieMenu: menu
+
+ readonly property int margins: 50
+ readonly property int boundingItemTopMargin: 100
+
+ Rectangle {
+ id: canvasContainer
+ anchors.fill: parent
+ anchors.topMargin: boundingItemTopMargin
+
+ Rectangle {
+ id: rect
+ anchors.fill: parent
+ anchors.margins: margins
+ border.color: "black"
+
+ MouseArea {
+ id: area
+ anchors.fill: parent
+ acceptedButtons: Qt.RightButton
+ onClicked: menu.popup(mouseX, mouseY)
+ }
+
+ PieMenu {
+ id: menu
+ boundingItem: canvasContainer
+
+ MenuItem {
+ text: "Action 1"
+ }
+ MenuItem {
+ text: "Action 2"
+ }
+ MenuItem {
+ text: "Action 3"
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/extras/data/PieMenuRotatedBoundingItem.qml b/tests/auto/extras/data/PieMenuRotatedBoundingItem.qml
new file mode 100644
index 00000000..2df592ab
--- /dev/null
+++ b/tests/auto/extras/data/PieMenuRotatedBoundingItem.qml
@@ -0,0 +1,49 @@
+import QtQuick 2.2
+import QtQuick.Controls 1.1
+import QtQuick.Extras 1.3
+
+Rectangle {
+ id: root
+ anchors.fill: parent
+
+ signal actionTriggered(int index)
+
+ property alias mouseArea: area
+
+ property alias pieMenu: menu
+
+ readonly property int margins: 50
+
+ Rectangle {
+ id: rect
+ rotation: 90
+ anchors.fill: parent
+ anchors.margins: root.margins
+ border.color: "black"
+
+ MouseArea {
+ id: area
+ anchors.fill: parent
+ acceptedButtons: Qt.RightButton
+ onClicked: menu.popup(mouseX, mouseY)
+ }
+
+ PieMenu {
+ id: menu
+ boundingItem: root
+
+ MenuItem {
+ text: "Action 1"
+ onTriggered: actionTriggered(0)
+ }
+ MenuItem {
+ text: "Action 2"
+ onTriggered: actionTriggered(1)
+ }
+ MenuItem {
+ text: "Action 3"
+ onTriggered: actionTriggered(2)
+ }
+ }
+ }
+}
diff --git a/tests/auto/extras/data/PieMenuVisibleButNoParent.qml b/tests/auto/extras/data/PieMenuVisibleButNoParent.qml
new file mode 100644
index 00000000..582e168a
--- /dev/null
+++ b/tests/auto/extras/data/PieMenuVisibleButNoParent.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.2
+import QtQuick.Extras 1.3
+
+Rectangle {
+ width: 400
+ height: 400
+
+ property PieMenu pieMenu: PieMenu {
+ id: pieMenu
+ visible: true
+ }
+}
diff --git a/tests/auto/extras/data/PieMenuVisibleOnCompleted.qml b/tests/auto/extras/data/PieMenuVisibleOnCompleted.qml
new file mode 100644
index 00000000..aa9cc18c
--- /dev/null
+++ b/tests/auto/extras/data/PieMenuVisibleOnCompleted.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.2
+import QtQuick.Extras 1.3
+
+Rectangle {
+ width: 400
+ height: 400
+
+ PieMenu {
+ Component.onCompleted: {
+ visible = true;
+ visible = false;
+ }
+ }
+}
diff --git a/tests/auto/extras/data/TestUtils.js b/tests/auto/extras/data/TestUtils.js
new file mode 100644
index 00000000..3cf2ff1b
--- /dev/null
+++ b/tests/auto/extras/data/TestUtils.js
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+.pragma library
+
+function findChild(parent, childObjectName) {
+ if (!parent)
+ return null;
+
+ for (var i = 0; i < parent.children.length; ++i) {
+ // Is this direct child of ours the child we're after?
+ var child = parent.children[i];
+ if (child.objectName === childObjectName)
+ return child;
+
+ // Try the direct child's children.
+ child = findChild(parent.children[i], childObjectName);
+ if (child)
+ return child;
+ }
+ return null;
+}
diff --git a/tests/auto/extras/data/TumblerDatePicker.qml b/tests/auto/extras/data/TumblerDatePicker.qml
new file mode 100644
index 00000000..9872fc00
--- /dev/null
+++ b/tests/auto/extras/data/TumblerDatePicker.qml
@@ -0,0 +1,38 @@
+import QtQuick 2.3
+import QtQuick.Controls 1.2
+import QtQuick.Extras 1.3
+
+Tumbler {
+ id: tumbler
+
+ readonly property var days: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
+
+ TumblerColumn {
+ id: tumblerDayColumn
+
+ function updateModel() {
+ var previousIndex = tumblerDayColumn.currentIndex;
+ var array = [];
+ var newDays = tumbler.days[monthColumn.currentIndex];
+ for (var i = 0; i < newDays; ++i) {
+ array.push(i + 1);
+ }
+ model = array;
+ tumbler.setCurrentIndexAt(0, Math.min(newDays - 1, previousIndex));
+ }
+ }
+ TumblerColumn {
+ id: monthColumn
+ model: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+ onCurrentIndexChanged: tumblerDayColumn.updateModel()
+ }
+ TumblerColumn {
+ model: ListModel {
+ Component.onCompleted: {
+ for (var i = 2000; i < 2100; ++i) {
+ append({value: i.toString()});
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/extras/data/picture.dat b/tests/auto/extras/data/picture.dat
new file mode 100644
index 00000000..e408aca2
--- /dev/null
+++ b/tests/auto/extras/data/picture.dat
Binary files differ
diff --git a/tests/auto/extras/data/tst_circulargauge.qml b/tests/auto/extras/data/tst_circulargauge.qml
new file mode 100644
index 00000000..16c0815f
--- /dev/null
+++ b/tests/auto/extras/data/tst_circulargauge.qml
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtTest 1.0
+import QtQuick 2.1
+import "TestUtils.js" as TestUtils
+
+TestCase {
+ id: testcase
+ name: "Tests_CircularGauge"
+ when: windowShown
+ width: 400
+ height: 400
+
+ function test_instance() {
+ var gauge = Qt.createQmlObject('import QtQuick.Extras 1.3; CircularGauge { }', testcase, '');
+ verify (gauge, "CircularGauge: failed to create an instance")
+ verify(gauge.__style)
+ gauge.destroy()
+ }
+
+ property Component tickmark: Rectangle {
+ objectName: "tickmark" + styleData.index
+ implicitWidth: 2
+ implicitHeight: 6
+ color: "#c8c8c8"
+ }
+
+ property Component minorTickmark: Rectangle {
+ objectName: "minorTickmark" + styleData.index
+ implicitWidth: 1
+ implicitHeight: 3
+ color: "#c8c8c8"
+ }
+
+ property Component tickmarkLabel: Text {
+ objectName: "tickmarkLabel" + styleData.index
+ text: styleData.value
+ color: "#c8c8c8"
+ }
+
+ function test_tickmarksVisible() {
+ var gauge = Qt.createQmlObject("import QtQuick.Extras 1.3; CircularGauge { }", testcase, "");
+ verify(gauge, "CircularGauge: failed to create an instance");
+
+ gauge.__style.tickmark = tickmark;
+ gauge.__style.minorTickmark = minorTickmark;
+ gauge.__style.tickmarkLabel = tickmarkLabel;
+ verify(TestUtils.findChild(gauge, "tickmark0"));
+ verify(TestUtils.findChild(gauge, "minorTickmark0"));
+ verify(TestUtils.findChild(gauge, "tickmarkLabel0"));
+
+ gauge.tickmarksVisible = false;
+ verify(!TestUtils.findChild(gauge, "tickmark0"));
+ verify(!TestUtils.findChild(gauge, "minorTickmark0"));
+ verify(!TestUtils.findChild(gauge, "tickmarkLabel0"));
+
+ gauge.destroy();
+ }
+}
diff --git a/tests/auto/extras/data/tst_circulartickmarklabel.qml b/tests/auto/extras/data/tst_circulartickmarklabel.qml
new file mode 100644
index 00000000..2521cbe9
--- /dev/null
+++ b/tests/auto/extras/data/tst_circulartickmarklabel.qml
@@ -0,0 +1,318 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtTest 1.0
+import QtQuick 2.1
+import "TestUtils.js" as TestUtils
+
+TestCase {
+ id: testcase
+ name: "Tests_CircularTickmarkLabel"
+ visible: windowShown
+ when: windowShown
+ width: 400
+ height: 400
+
+ property var label: null
+
+ function init() {
+ label = Qt.createQmlObject("import QtQuick.Extras 1.3; import QtQuick.Extras.Private 1.0; CircularTickmarkLabel {}", testcase, "");
+ verify(label, "CircularTickmarkLabel: failed to create an instance");
+ verify(label.__style);
+ }
+
+ function cleanup() {
+ label.destroy();
+ }
+
+ function test_angleRange() {
+ label.minimumValueAngle = -180;
+ label.maximumValueAngle = 180;
+ compare(label.angleRange, 360);
+
+ label.minimumValueAngle = -140;
+ label.maximumValueAngle = 160;
+ compare(label.angleRange, 300);
+
+ label.minimumValueAngle = -40;
+ label.maximumValueAngle = -10;
+ compare(label.angleRange, 30);
+
+ label.minimumValueAngle = -40;
+ label.maximumValueAngle = 10;
+ compare(label.angleRange, 50);
+ }
+
+ function test_tickmarksAndLabels() {
+ label.minimumValueAngle = 0;
+ label.maximumValueAngle = 180;
+
+ // When the label step size is 40 and the maximumValue 220, the following labels should be displayed:
+ // 0, 40, 80, 120, 160, 200
+ // In addition, the labels should be positioned according to how much of the angle range they actually use;
+ // since 240 is unable to be displayed, 200 should not be displayed on the last tickmark, but two tickmarks
+ // before it (the tickmarkStepSize is 10).
+ label.maximumValue = 220;
+ label.tickmarkStepSize = 10;
+ label.labelStepSize = 40;
+ compare(label.angleRange, 180);
+ compare(label.valueToAngle(0), 0);
+ compare(label.valueToAngle(220), 180);
+ compare(label.__panel.labelAngleFromIndex(1), 32.7272727);
+ compare(label.__panel.labelAngleFromIndex(0), 0);
+ compare(label.__panel.totalMinorTickmarkCount, 88);
+ compare(label.__panel.tickmarkValueFromIndex(0), 0);
+ compare(label.__panel.tickmarkValueFromIndex(label.tickmarkCount - 1), 220);
+ compare(label.__panel.tickmarkValueFromMinorIndex(0), 2);
+ compare(label.__panel.tickmarkValueFromMinorIndex(label.minorTickmarkCount - 1), 8);
+ compare(label.__panel.tickmarkValueFromMinorIndex(((label.tickmarkCount - 1) * label.minorTickmarkCount) - 1), 218);
+
+ var rotations = [
+ -0.5729577951308232,
+ 7.6088603866873585,
+ 15.79067856850554,
+ 23.972496750323725,
+ 32.1543149321419,
+ 40.33613311396008,
+ 48.51795129577827,
+ 56.69976947759645,
+ 64.88158765941463,
+ 73.06340584123282,
+ 81.245224023051,
+ 89.42704220486918,
+ 97.60886038668737,
+ 105.79067856850554,
+ 113.97249675032373,
+ 122.1543149321419,
+ 130.33613311396007,
+ 138.51795129577826,
+ 146.69976947759645,
+ 154.8815876594146,
+ 163.0634058412328,
+ 171.24522402305098,
+ 179.42704220486917
+ ];
+
+ // Check that the tickmarks have the correct transforms and hence are actually in the correct position.
+ for (var tickmarkIndex = 0; tickmarkIndex < label.__tickmarkCount; ++tickmarkIndex) {
+ var tickmark = TestUtils.findChild(label.__panel, "tickmark" + tickmarkIndex);
+ verify(tickmark);
+ compare(tickmark.transform[1].angle, rotations[tickmarkIndex]);
+ }
+
+ var minorRotations = [
+ 1.3498847387982247, 2.986248375161861,
+ 4.622612011525496, 6.258975647889133, 9.531702920616407,
+ 11.168066556980042, 12.804430193343679, 14.440793829707316,
+ 17.713521102434587, 19.349884738798224, 20.98624837516186,
+ 22.622612011525494, 25.89533928425277, 27.531702920616407,
+ 29.16806655698004, 30.80443019334368, 34.07715746607095,
+ 35.71352110243459, 37.349884738798224, 38.986248375161864,
+ 42.25897564788913, 43.89533928425277, 45.531702920616404,
+ 47.168066556980044, 50.44079382970732, 52.07715746607096,
+ 53.71352110243459, 55.34988473879823, 58.6226120115255,
+ 60.25897564788914, 61.89533928425277, 63.53170292061641,
+ 66.80443019334368, 68.4407938297073, 70.07715746607094,
+ 71.71352110243458, 74.98624837516186, 76.62261201152549,
+ 78.25897564788913, 79.89533928425277, 83.16806655698004,
+ 84.80443019334366, 86.4407938297073, 88.07715746607094,
+ 91.34988473879822, 92.98624837516185, 94.62261201152549,
+ 96.25897564788913, 99.53170292061641, 101.16806655698004,
+ 102.80443019334368, 104.44079382970732, 107.71352110243458,
+ 109.34988473879821, 110.98624837516185, 112.62261201152549,
+ 115.89533928425277, 117.5317029206164, 119.16806655698004,
+ 120.80443019334368, 124.07715746607094, 125.71352110243457,
+ 127.34988473879821, 128.98624837516184, 132.25897564788912,
+ 133.89533928425277, 135.5317029206164, 137.16806655698002,
+ 140.4407938297073, 142.07715746607096, 143.71352110243458,
+ 145.3498847387982, 148.6226120115255, 150.25897564788914,
+ 151.89533928425277, 153.5317029206164, 156.80443019334365,
+ 158.4407938297073, 160.07715746607093, 161.71352110243456,
+ 164.98624837516184, 166.6226120115255, 168.25897564788912,
+ 169.89533928425274, 173.16806655698002, 174.80443019334368,
+ 176.4407938297073, 178.07715746607093,
+ ];
+
+ for (var minorTickmarkIndex = 0; minorTickmarkIndex < label.__panel.totalMinorTickmarkCount; ++minorTickmarkIndex) {
+ var minorTickmark = TestUtils.findChild(label.__panel, "minorTickmark" + minorTickmarkIndex);
+ verify(minorTickmark);
+ compare(minorTickmark.transform[1].angle, minorRotations[minorTickmarkIndex]);
+ }
+
+ // 0, 10, 20... 100
+ label.labelStepSize = 10;
+ label.minimumValue = 0;
+ label.maximumValue = 100;
+ compare(label.tickmarkCount, 11);
+ compare(label.minorTickmarkCount, 4);
+ compare(label.labelCount, 11);
+ compare(label.angleRange, 180);
+ compare(label.valueToAngle(0), 0);
+ compare(label.valueToAngle(100), 180);
+ compare(label.__panel.labelAngleFromIndex(0), 0);
+ compare(label.__panel.labelAngleFromIndex(label.labelCount - 1), 180);
+ compare(label.__panel.totalMinorTickmarkCount, 40);
+ compare(label.__panel.tickmarkValueFromIndex(0), 0);
+ compare(label.__panel.tickmarkValueFromIndex(label.tickmarkCount - 1), 100);
+ compare(label.__panel.tickmarkValueFromMinorIndex(0), 2);
+ compare(label.__panel.tickmarkValueFromMinorIndex(label.minorTickmarkCount - 1), 8);
+ compare(label.__panel.tickmarkValueFromMinorIndex(((label.tickmarkCount - 1) * label.minorTickmarkCount) - 1), 98);
+
+ // 10, 20... 100
+ label.labelStepSize = 10;
+ label.minimumValue = 10;
+ label.maximumValue = 100;
+
+ compare(label.tickmarkCount, 10);
+ compare(label.minorTickmarkCount, 4);
+ compare(label.labelCount, 10);
+ compare(label.angleRange, 180);
+ compare(label.valueToAngle(10), 0);
+ compare(label.valueToAngle(100), 180);
+ compare(label.__panel.labelAngleFromIndex(0), 0);
+ compare(label.__panel.labelAngleFromIndex(label.labelCount - 1), 180);
+ compare(label.__panel.totalMinorTickmarkCount, 36);
+ compare(label.__panel.tickmarkValueFromIndex(0), 10);
+ compare(label.__panel.tickmarkValueFromIndex(label.tickmarkCount - 1), 100);
+ compare(label.__panel.tickmarkValueFromMinorIndex(0), 12);
+ compare(label.__panel.tickmarkValueFromMinorIndex(label.minorTickmarkCount - 1), 18);
+ compare(label.__panel.tickmarkValueFromMinorIndex(((label.tickmarkCount - 1) * label.minorTickmarkCount) - 1), 98);
+
+ // -10, 0, 10, 20... 100
+ label.labelStepSize = 10;
+ label.minimumValue = -10;
+ label.maximumValue = 100;
+ compare(label.tickmarkCount, 12);
+ compare(label.minorTickmarkCount, 4);
+ compare(label.labelCount, 12);
+ compare(label.angleRange, 180);
+ compare(label.valueToAngle(-10), 0);
+ compare(label.valueToAngle(100), 180);
+ compare(label.__panel.labelAngleFromIndex(0), 0);
+ compare(label.__panel.labelAngleFromIndex(label.labelCount - 1), 180);
+ compare(label.__panel.totalMinorTickmarkCount, 44);
+ compare(label.__panel.tickmarkValueFromIndex(0), -10);
+ compare(label.__panel.tickmarkValueFromIndex(label.tickmarkCount - 1), 100);
+ compare(label.__panel.tickmarkValueFromMinorIndex(0), -8);
+ compare(label.__panel.tickmarkValueFromMinorIndex(label.minorTickmarkCount - 1), -2);
+ compare(label.__panel.tickmarkValueFromMinorIndex(((label.tickmarkCount - 1) * label.minorTickmarkCount) - 1), 98);
+
+ // 0, 10, 20... 105
+ label.labelStepSize = 10;
+ label.minimumValue = 0;
+ label.maximumValue = 105;
+ label.minorTickmarkCount = 1;
+ compare(label.tickmarkCount, 11);
+ compare(label.labelCount, 11);
+ compare(label.angleRange, 180);
+ compare(label.valueToAngle(0), 0);
+ compare(label.valueToAngle(105), 180);
+ compare(label.__panel.labelAngleFromIndex(0), 0);
+ compare(label.__panel.labelAngleFromIndex(label.labelCount - 1), 171.42857142857142);
+ compare(label.__panel.tickmarkAngleFromIndex(label.tickmarkCount - 1), 171.42857142857142);
+ compare(label.__panel.minorTickmarkAngleFromIndex(label.minorTickmarkCount * (label.tickmarkCount - 1)), 180);
+ compare(label.__panel.totalMinorTickmarkCount, 11);
+ compare(label.__panel.tickmarkValueFromIndex(0), 0);
+ compare(label.__panel.tickmarkValueFromIndex(label.tickmarkCount - 1), 105);
+ compare(label.__panel.tickmarkValueFromMinorIndex(0), 5.25);
+ compare(label.__panel.tickmarkValueFromMinorIndex(((label.tickmarkCount - 1) * label.minorTickmarkCount) - 1), 99.75);
+
+ // 0, 10, 20... 101. Shouldn't show an extra minor tickmark, because each minor tickmark
+ // is 2 "units", and 1 (taken from 101) < 2.
+ label.labelStepSize = 10;
+ label.minimumValue = 0;
+ label.maximumValue = 101;
+ label.minorTickmarkCount = 4;
+ compare(label.valueToAngle(0), 0);
+ compare(label.valueToAngle(101), 180);
+ compare(label.tickmarkCount, 11);
+ compare(label.labelCount, 11);
+ compare(label.angleRange, 180);
+ compare(label.__panel.labelAngleFromIndex(0), 0);
+ compare(label.__panel.labelAngleFromIndex(label.labelCount - 1), 178.21782178217825);
+ compare(label.__panel.tickmarkAngleFromIndex(label.tickmarkCount - 1), 178.21782178217825);
+ compare(label.__panel.totalMinorTickmarkCount, 40);
+ compare(label.__panel.tickmarkValueFromIndex(0), 0);
+ compare(label.__panel.tickmarkValueFromIndex(label.tickmarkCount - 1), 101);
+ compare(label.__panel.tickmarkValueFromMinorIndex(0), 2.02);
+ compare(label.__panel.tickmarkValueFromMinorIndex(label.minorTickmarkCount - 1), 8.08);
+ compare(label.__panel.tickmarkValueFromMinorIndex(((label.tickmarkCount - 1) * label.minorTickmarkCount) - 1), 98.97999999999999);
+
+ // Test reversed labels.
+ label.minimumValueAngle = 270;
+ label.maximumValueAngle = 90;
+ label.minimumValue = 0;
+ label.maximumValue = 100;
+ compare(label.valueToAngle(0), 270);
+ compare(label.valueToAngle(50), 180);
+ compare(label.valueToAngle(100), 90);
+
+ label.minimumValueAngle = 270;
+ label.maximumValueAngle = 0;
+ compare(label.valueToAngle(0), 270);
+ compare(label.valueToAngle(100), 0);
+
+ label.minimumValueAngle = -90;
+ label.maximumValueAngle = 0;
+ compare(label.valueToAngle(0), -90);
+ compare(label.valueToAngle(100), 0);
+
+ label.minimumValueAngle = -180;
+ label.maximumValueAngle = 90;
+ compare(label.valueToAngle(0), -180);
+ compare(label.valueToAngle(100), 90);
+
+ label.minimumValueAngle = 215;
+ label.maximumValueAngle = 145;
+ label.minimumValue = 0;
+ label.maximumValue = 100;
+ compare(label.tickmarkCount, 11);
+ compare(label.labelCount, 11);
+ compare(label.angleRange, -70);
+ compare(label.__panel.totalMinorTickmarkCount, 40);
+ compare(label.__panel.tickmarkValueFromIndex(0), 0);
+ compare(label.__panel.tickmarkValueFromIndex(label.tickmarkCount - 1), 100);
+ compare(label.__panel.tickmarkValueFromMinorIndex(0), 2);
+ compare(label.__panel.tickmarkValueFromMinorIndex(label.minorTickmarkCount - 1), 8);
+ compare(label.__panel.tickmarkValueFromMinorIndex(((label.tickmarkCount - 1) * label.minorTickmarkCount) - 1), 98);
+ }
+
+ function test_invalidValues() {
+ // Shouldn't produce warnings.
+ label.labelStepSize = 0;
+ label.tickmarkStepSize = 0;
+ }
+}
diff --git a/tests/auto/extras/data/tst_common.qml b/tests/auto/extras/data/tst_common.qml
new file mode 100644
index 00000000..1a7fe990
--- /dev/null
+++ b/tests/auto/extras/data/tst_common.qml
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtTest 1.0
+import QtQuick 2.1
+
+TestCase {
+ id: testCase
+ name: "Tests_Common"
+ visible: windowShown
+ when: windowShown
+ width: 400
+ height: 400
+
+ property var control
+
+ function init_data() {
+ return [
+ { tag: "CircularGauge" },
+ { tag: "DelayButton" },
+ { tag: "Dial" },
+ { tag: "Gauge" },
+ { tag: "PieMenu", qml: "import QtQuick.Controls 1.1; import QtQuick.Extras 1.3;"
+ + "PieMenu { visible: true; MenuItem { text: 'foo' } }"},
+ { tag: "StatusIndicator" },
+ { tag: "ToggleButton" },
+ { tag: "Tumbler", qml: "import QtQuick.Extras 1.3; Tumbler { TumblerColumn { model: 10 } }" }
+ ];
+ }
+
+ function cleanup() {
+ control.destroy();
+ }
+
+ function test_resize(data) {
+ var qml = data.qml ? data.qml : "import QtQuick.Extras 1.3; " + data.tag + " { }";
+ control = Qt.createQmlObject(qml, testCase, "");
+
+ var resizeAnimation = Qt.createQmlObject("import QtQuick 2.2; NumberAnimation {}", testCase, "");
+ resizeAnimation.target = control;
+ resizeAnimation.properties = "width,height";
+ resizeAnimation.duration = 100;
+ resizeAnimation.to = 0;
+ resizeAnimation.start();
+ // Shouldn't get any warnings.
+ tryCompare(resizeAnimation, "running", false);
+ resizeAnimation.destroy();
+ }
+}
diff --git a/tests/auto/extras/data/tst_delaybutton.qml b/tests/auto/extras/data/tst_delaybutton.qml
new file mode 100644
index 00000000..59e602a1
--- /dev/null
+++ b/tests/auto/extras/data/tst_delaybutton.qml
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtTest 1.0
+import QtQuick 2.1
+
+TestCase {
+ id: testcase
+ name: "Tests_DelayButton"
+ visible: windowShown
+ when: windowShown
+ width: 400
+ height: 400
+
+ function test_instance() {
+ var button = Qt.createQmlObject('import QtQuick.Extras 1.3; DelayButton { }', testcase, '')
+ verify (button, "DelayButton: failed to create an instance")
+ verify(button.__style)
+ verify(!button.checked)
+ verify(!button.pressed)
+ button.destroy()
+ }
+
+ SignalSpy {
+ id: activationSpy
+ signalName: "activated"
+ }
+
+ function test_activation_data() {
+ return [
+ { tag: "delayed", delay: 1 },
+ { tag: "immediate", delay: 0 },
+ { tag: "negative", delay: -1 }
+ ]
+ }
+
+ function test_activation(data) {
+ var button = Qt.createQmlObject('import QtQuick.Extras 1.3; DelayButton { }', testcase, '')
+ verify (button, "DelayButton: failed to create an instance")
+ button.delay = data.delay
+
+ activationSpy.clear()
+ activationSpy.target = button
+ verify(activationSpy.valid)
+
+ // press and hold to activate
+ mousePress(button, button.width / 2, button.height / 2)
+ verify(button.pressed)
+ var immediate = data.delay <= 0
+ if (!immediate)
+ activationSpy.wait()
+ compare(activationSpy.count, 1)
+
+ // release
+ mouseRelease(button, button.width / 2, button.height / 2)
+ verify(!button.pressed)
+ compare(activationSpy.count, 1)
+
+ button.destroy()
+ }
+
+ SignalSpy {
+ id: progressSpy
+ signalName: "progressChanged"
+ }
+
+ function test_progress() {
+ var button = Qt.createQmlObject('import QtQuick.Extras 1.3; DelayButton { delay: 1 }', testcase, '')
+ verify (button, "DelayButton: failed to create an instance")
+
+ progressSpy.target = button
+ verify(progressSpy.valid)
+
+ compare(button.progress, 0.0)
+ mousePress(button, button.width / 2, button.height / 2)
+ tryCompare(button, "progress", 1.0)
+ verify(progressSpy.count > 0)
+
+ button.destroy()
+ }
+
+ SignalSpy {
+ id: checkSpy
+ signalName: "checkedChanged"
+ }
+
+ function test_checked_data() {
+ return [
+ { tag: "delayed", delay: 1 },
+ { tag: "immediate", delay: 0 },
+ { tag: "negative", delay: -1 }
+ ]
+ }
+
+ function test_checked(data) {
+ var button = Qt.createQmlObject('import QtQuick.Extras 1.3; DelayButton { }', testcase, '')
+ verify (button, "DelayButton: failed to create an instance")
+ button.delay = data.delay
+
+ var checkCount = 0
+
+ checkSpy.clear()
+ checkSpy.target = button
+ verify(checkSpy.valid)
+ verify(!button.checked)
+
+ // press and hold to check
+ mousePress(button, button.width / 2, button.height / 2)
+ verify(button.pressed)
+ var immediate = data.delay <= 0
+ compare(button.checked, immediate)
+ if (!immediate)
+ tryCompare(button, "checked", true)
+ compare(checkSpy.count, ++checkCount)
+
+ // release
+ mouseRelease(button, button.width / 2, button.height / 2)
+ verify(!button.pressed)
+ verify(button.checked)
+ compare(checkSpy.count, checkCount)
+
+ // press to uncheck immediately
+ mousePress(button, button.width / 2, button.height / 2)
+ verify(button.pressed)
+ verify(!button.checked)
+ compare(checkSpy.count, ++checkCount)
+
+ // release
+ mouseRelease(button, button.width / 2, button.height / 2)
+ verify(!button.pressed)
+ verify(!button.checked)
+ compare(checkSpy.count, checkCount)
+
+ button.destroy()
+ }
+
+ function test_programmaticCheck() {
+ var button = Qt.createQmlObject("import QtQuick.Extras 1.3; DelayButton {}", testcase, "");
+ verify(button, "DelayButton: failed to create an instance");
+
+ checkSpy.clear();
+ checkSpy.target = button;
+ verify(!button.checked);
+
+ button.checked = true;
+ compare(button.progress, 1);
+
+ button.checked = false;
+ compare(button.progress, 0);
+
+ button.destroy();
+ }
+
+ function test_largeText() {
+ // Should be no binding loop warnings.
+ var button = Qt.createQmlObject("import QtQuick.Extras 1.3; DelayButton { "
+ + "anchors.centerIn: parent; text: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' }", testcase, "");
+ verify(button, "DelayButton: failed to create an instance");
+ button.destroy();
+ }
+}
diff --git a/tests/auto/extras/data/tst_dial.qml b/tests/auto/extras/data/tst_dial.qml
new file mode 100644
index 00000000..02e6eaa3
--- /dev/null
+++ b/tests/auto/extras/data/tst_dial.qml
@@ -0,0 +1,367 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtTest 1.0
+import QtQuick 2.1
+import "TestUtils.js" as TestUtils
+
+TestCase {
+ id: testcase
+ name: "Tests_Dial"
+ visible: windowShown
+ when: windowShown
+ width: 400
+ height: 400
+
+ function test_instance() {
+ var dial = Qt.createQmlObject('import QtQuick.Extras 1.3; Dial { }', testcase, '');
+ verify (dial, "Dial: failed to create an instance")
+ verify(dial.__style)
+ compare(dial.value, 0.0)
+ compare(dial.minimumValue, 0.0)
+ compare(dial.maximumValue, 1.0)
+ compare(dial.stepSize, 0.0)
+ verify(!dial.wrap)
+ verify(!dial.activeFocusOnPress)
+ verify(!dial.containsMouse)
+ verify(!dial.pressed)
+ dial.destroy()
+ }
+
+ function test_minimumValue() {
+ var dial = Qt.createQmlObject('import QtQuick.Extras 1.3; Dial { }', testcase, '');
+ verify (dial, "Dial: failed to create an instance")
+ dial.minimumValue = 5
+ dial.maximumValue = 10
+ dial.value = 2
+ compare(dial.minimumValue, 5)
+ compare(dial.value, 5)
+ dial.destroy()
+ }
+
+ function test_maximumValue() {
+ var dial = Qt.createQmlObject('import QtQuick.Extras 1.3; Dial { }', testcase, '');
+ verify (dial, "Dial: failed to create an instance")
+ dial.minimumValue = 5
+ dial.maximumValue = 10
+ dial.value = 15
+ compare(dial.maximumValue, 10)
+ compare(dial.value, 10)
+ dial.destroy()
+ }
+
+ function test_activeFocusOnPress(){
+ var scope = Qt.createQmlObject('import QtQuick 2.2; FocusScope { focus: false }', testcase, '')
+ verify(!scope.activeFocus)
+
+ var dial = Qt.createQmlObject('import QtQuick.Extras 1.3; Dial { }', scope, '')
+ verify (dial, "Dial: failed to create an instance")
+ verify(!dial.activeFocusOnPress)
+ verify(!dial.activeFocus)
+ verify(!scope.activeFocus)
+ mousePress(dial, dial.width / 2, dial.height / 2)
+ verify(!dial.activeFocus)
+ verify(!scope.activeFocus)
+ mouseRelease(dial, dial.width / 2, dial.height / 2)
+ verify(!dial.activeFocus)
+ verify(!scope.activeFocus)
+
+ dial.activeFocusOnPress = true
+ verify(dial.activeFocusOnPress)
+ verify(!dial.activeFocus)
+ verify(!scope.activeFocus)
+ mousePress(dial, dial.width / 2, dial.height / 2)
+ verify(dial.activeFocus)
+ verify(scope.activeFocus)
+ mouseRelease(dial, dial.width / 2, dial.height / 2)
+ verify(dial.activeFocus)
+ verify(scope.activeFocus)
+
+ dial.destroy()
+ }
+
+ SignalSpy {
+ id: pressSpy
+ signalName: "pressedChanged"
+ }
+
+ function test_pressed() {
+ var dial = Qt.createQmlObject('import QtQuick.Extras 1.3; Dial { }', testcase, '')
+ verify (dial, "Dial: failed to create an instance")
+
+ pressSpy.target = dial
+ verify(pressSpy.valid)
+ verify(!dial.pressed)
+
+ mousePress(dial, dial.width / 2, dial.height / 2)
+ verify(dial.pressed)
+ compare(pressSpy.count, 1)
+
+ mouseRelease(dial, dial.width / 2, dial.height / 2)
+ verify(!dial.pressed)
+ compare(pressSpy.count, 2)
+
+ dial.destroy()
+ }
+
+ SignalSpy {
+ id: hoverSpy
+ signalName: "hoveredChanged"
+ }
+
+ function test_hovered() {
+ var dial = Qt.createQmlObject('import QtQuick.Extras 1.3; Dial { }', testcase, '')
+ verify (dial, "Dial: failed to create an instance")
+
+ hoverSpy.target = dial
+ verify(hoverSpy.valid)
+ verify(!dial.hovered)
+
+ mouseMove(dial, dial.width / 2, dial.height / 2)
+ verify(dial.hovered)
+ compare(hoverSpy.count, 1)
+
+ mouseMove(dial, dial.width * 2, dial.height * 2)
+ verify(!dial.hovered)
+ compare(hoverSpy.count, 2)
+
+ dial.destroy()
+ }
+
+ SignalSpy {
+ id: valueSpy
+ signalName: "valueChanged"
+ }
+
+ function test_dragging_data() {
+ return [
+ { tag: "default", min: 0, max: 1, leftValue: 0.20, topValue: 0.5, rightValue: 0.8, bottomValue: 1.0 },
+ { tag: "scaled2", min: 0, max: 2, leftValue: 0.4, topValue: 1.0, rightValue: 1.6, bottomValue: 2.0 },
+ { tag: "scaled1", min: -1, max: 0, leftValue: -0.8, topValue: -0.5, rightValue: -0.2, bottomValue: 0.0 }
+ ]
+ }
+
+ function test_dragging(data) {
+ var dial = Qt.createQmlObject('import QtQuick.Extras 1.3; Dial { }', testcase, '')
+ verify(dial, "Dial: failed to create an instance")
+ dial.minimumValue = data.min
+ dial.maximumValue = data.max
+
+ valueSpy.target = dial
+ verify(valueSpy.valid)
+
+ // drag to the left
+ mouseDrag(dial, dial.width / 2, dial.height / 2, -dial.width / 2, 0, Qt.LeftButton)
+ fuzzyCompare(dial.value, data.leftValue, 0.1)
+ verify(valueSpy.count > 0)
+ valueSpy.clear()
+
+ // drag to the top
+ mouseDrag(dial, dial.width / 2, dial.height / 2, 0, -dial.height / 2, Qt.LeftButton)
+ fuzzyCompare(dial.value, data.topValue, 0.1)
+ verify(valueSpy.count > 0)
+ valueSpy.clear()
+
+ // drag to the right
+ mouseDrag(dial, dial.width / 2, dial.height / 2, dial.width / 2, 0, Qt.LeftButton)
+ fuzzyCompare(dial.value, data.rightValue, 0.1)
+ verify(valueSpy.count > 0)
+ valueSpy.clear()
+
+ // drag to the bottom
+ mouseDrag(dial, dial.width / 2, dial.height / 2, 0, dial.height / 2, Qt.LeftButton)
+ fuzzyCompare(dial.value, data.bottomValue, 0.1)
+ verify(valueSpy.count > 0)
+ valueSpy.clear()
+
+ dial.destroy()
+ }
+
+ function test_outerRadius() {
+ var dial = Qt.createQmlObject("import QtQuick.Extras 1.3; Dial { }", testcase, "");
+ verify(dial, "Dial: failed to create an instance");
+ // Implicit width and height are identical.
+ compare(dial.__style.outerRadius, dial.width / 2);
+
+ dial.width = 100;
+ dial.height = 250;
+ compare(dial.__style.outerRadius, dial.width / 2);
+
+ dial.width = 250;
+ dial.height = 100;
+ compare(dial.__style.outerRadius, dial.height / 2);
+
+ dial.destroy();
+ }
+
+ property Component tickmark: Rectangle {
+ objectName: "tickmark" + styleData.index
+ implicitWidth: 3
+ implicitHeight: 8
+ color: "#c8c8c8"
+ }
+
+ property Component minorTickmark: Rectangle {
+ objectName: "minorTickmark" + styleData.index
+ implicitWidth: 2
+ implicitHeight: 6
+ color: "#c8c8c8"
+ }
+
+ property Component tickmarkLabel: Text {
+ objectName: "tickmarkLabel" + styleData.index
+ text: styleData.value
+ color: "#c8c8c8"
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+
+ function test_tickmarksVisible() {
+ var dial = Qt.createQmlObject("import QtQuick.Extras 1.3; Dial { }", testcase, "");
+ verify(dial, "Dial: failed to create an instance");
+
+ dial.__style.minorTickmarkCount = 4;
+ dial.__style.tickmark = tickmark;
+ dial.__style.minorTickmark = minorTickmark;
+ dial.__style.tickmarkLabel = tickmarkLabel;
+ verify(TestUtils.findChild(dial, "tickmark0"));
+ verify(TestUtils.findChild(dial, "minorTickmark0"));
+ verify(TestUtils.findChild(dial, "tickmarkLabel0"));
+
+ dial.tickmarksVisible = false;
+ verify(!TestUtils.findChild(dial, "tickmark0"));
+ verify(!TestUtils.findChild(dial, "minorTickmark0"));
+ verify(!TestUtils.findChild(dial, "tickmarkLabel0"));
+
+ dial.destroy();
+ }
+
+ property Component focusTest: Component {
+ FocusScope {
+ signal receivedKeyPress
+
+ Component.onCompleted: forceActiveFocus()
+ anchors.fill: parent
+ Keys.onPressed: receivedKeyPress()
+ }
+ }
+
+ SignalSpy {
+ id: parentEventSpy
+ }
+
+ function test_keyboardNavigation() {
+ var focusScope = focusTest.createObject(testcase);
+ verify(focusScope);
+
+ // Tests that we've accepted events that we're interested in.
+ parentEventSpy.target = focusScope;
+ parentEventSpy.signalName = "receivedKeyPress";
+
+ var dial = Qt.createQmlObject("import QtQuick.Extras 1.3; Dial { }", focusScope, "");
+ verify(dial, "Dial: failed to create an instance");
+ compare(dial.activeFocusOnTab, true);
+ compare(dial.value, 0);
+
+ dial.focus = true;
+ compare(dial.activeFocus, true);
+ dial.stepSize = 0.1;
+
+ keyClick(Qt.Key_Left);
+ compare(parentEventSpy.count, 0);
+ compare(dial.value, 0);
+
+ var keyPairs = [[Qt.Key_Left, Qt.Key_Right], [Qt.Key_Down, Qt.Key_Up]];
+ for (var keyPairIndex = 0; keyPairIndex < 2; ++keyPairIndex) {
+ for (var i = 1; i <= 10; ++i) {
+ keyClick(keyPairs[keyPairIndex][1]);
+ compare(parentEventSpy.count, 0);
+ compare(dial.value, dial.stepSize * i);
+ }
+
+ compare(dial.value, dial.maximumValue);
+
+ for (i = 10; i > 0; --i) {
+ keyClick(keyPairs[keyPairIndex][0]);
+ compare(parentEventSpy.count, 0);
+ compare(dial.value, dial.stepSize * (i - 1));
+ }
+ }
+
+ compare(dial.value, dial.minimumValue);
+
+ keyClick(Qt.Key_Home);
+ compare(parentEventSpy.count, 0);
+ compare(dial.value, dial.minimumValue);
+
+ keyClick(Qt.Key_End);
+ compare(parentEventSpy.count, 0);
+ compare(dial.value, dial.maximumValue);
+
+ keyClick(Qt.Key_End);
+ compare(parentEventSpy.count, 0);
+ compare(dial.value, dial.maximumValue);
+
+ keyClick(Qt.Key_Home);
+ compare(parentEventSpy.count, 0);
+ compare(dial.value, dial.minimumValue);
+
+ focusScope.destroy();
+ }
+
+ function test_dragToSet() {
+ var dial = Qt.createQmlObject("import QtQuick.Extras 1.3; Dial { }", testcase, "");
+ verify(dial, "Dial: failed to create an instance");
+
+ dial.__style.__dragToSet = false;
+
+ compare(dial.value, 0);
+ var lastValue = dial.value;
+
+ mousePress(dial, dial.width, dial.height / 2, Qt.LeftButton);
+ verify(dial.value !== lastValue);
+ lastValue = dial.value;
+ mouseRelease(dial, dial.width, dial.height / 2, Qt.LeftButton);
+
+ dial.__style.__dragToSet = true;
+
+ mousePress(dial, dial.width / 4, dial.height / 2, Qt.LeftButton);
+ verify(dial.value === lastValue);
+ mouseRelease(dial, dial.width / 4, dial.height / 2, Qt.LeftButton);
+
+ dial.destroy();
+ }
+}
diff --git a/tests/auto/extras/data/tst_gauge.qml b/tests/auto/extras/data/tst_gauge.qml
new file mode 100644
index 00000000..08fdf53f
--- /dev/null
+++ b/tests/auto/extras/data/tst_gauge.qml
@@ -0,0 +1,287 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtTest 1.0
+import QtQuick 2.2
+import QtQuick.Extras.Styles 1.3
+import "TestUtils.js" as TestUtils
+
+TestCase {
+ id: testcase
+ name: "Tests_Gauge"
+ visible: windowShown
+ when: windowShown
+ width: 60
+ height: 200
+
+ property var gauge
+
+ Rectangle {
+ anchors.fill: parent
+ color: "black"
+ }
+
+ property Component zeroTickmarkWidthGaugeStyle: GaugeStyle {
+ tickmark: Item {
+ implicitWidth: 0
+ implicitHeight: 1
+ }
+ }
+
+ property Component largeGaugeStyle: GaugeStyle {
+ tickmark: Item {
+ implicitWidth: 8
+ implicitHeight: 4
+ }
+ }
+
+ function init() {
+ gauge = Qt.createQmlObject("import QtQuick.Extras 1.3; Gauge { }", testcase, "");
+ verify(gauge, "Gauge: failed to create an instance");
+ verify(gauge.__style);
+ }
+
+ function cleanup() {
+ if (gauge)
+ gauge.destroy();
+ }
+
+ function test_assignStyle() {
+ gauge.style = zeroTickmarkWidthGaugeStyle;
+ compare(gauge.__panel.tickmarkLabelBoundsWidth, gauge.__hiddenText.width);
+ compare(gauge.__panel.tickmarkLength, 0);
+ compare(gauge.__panel.tickmarkWidth, 1);
+
+ // Ensure that our internals are correct after changing to smaller tickmarks.
+ gauge.style = largeGaugeStyle;
+ compare(gauge.__panel.tickmarkLabelBoundsWidth, gauge.__hiddenText.width + 8);
+ compare(gauge.__panel.tickmarkLength, 8);
+ compare(gauge.__panel.tickmarkWidth, 4);
+
+ gauge.style = zeroTickmarkWidthGaugeStyle;
+ compare(gauge.__panel.tickmarkLabelBoundsWidth, gauge.__hiddenText.width);
+ compare(gauge.__panel.tickmarkLength, 0);
+ compare(gauge.__panel.tickmarkWidth, 1);
+ }
+
+ property Component centeredTickmarkStyle: GaugeStyle {
+ tickmark: Item {
+ implicitWidth: 10
+ implicitHeight: 4
+
+ Rectangle {
+ // We must use this as the actual tickmark, because the parent is just spacing.
+ objectName: "tickmark" + styleData.index
+ x: control.tickmarkAlignment === Qt.AlignLeft
+ || control.tickmarkAlignment === Qt.AlignTop ? parent.implicitWidth : -28
+ width: 28
+ height: parent.height
+ }
+ }
+
+ valueBar: Rectangle {
+ objectName: "valueBar"
+ implicitWidth: 28
+
+ Text {
+ text: parent.width
+ }
+ }
+ }
+
+ function test_valueBarPosition_data() {
+ return [
+ { tag: "AlignLeft", orientation: Qt.Vertical, tickmarkAlignment: Qt.AlignLeft },
+ { tag: "AlignRight", orientation: Qt.Vertical, tickmarkAlignment: Qt.AlignRight },
+ // TODO: these combinations work, but the tests need to account for them (perhaps due to rotation)
+// { tag: "AlignTop", orientation: Qt.Horizontal, tickmarkAlignment: Qt.AlignTop },
+// { tag: "AlignBottom", orientation: Qt.Horizontal, tickmarkAlignment: Qt.AlignBottom },
+ ];
+ }
+
+ function test_valueBarPosition(data) {
+ gauge.orientation = data.orientation;
+ gauge.tickmarkAlignment = data.tickmarkAlignment;
+ gauge.value = 1.8;
+ gauge.maximumValue = 4;
+ gauge.tickmarkStepSize = 1;
+ gauge.minorTickmarkCount = 1;
+ gauge.width = 50;
+
+ gauge.style = centeredTickmarkStyle;
+
+ var valueBar = TestUtils.findChild(gauge, "valueBar");
+ var firstTickmark = TestUtils.findChild(gauge, "tickmark0");
+ compare(testcase.mapFromItem(valueBar, 0, 0).x, testcase.mapFromItem(firstTickmark, 0, 0).x);
+ }
+
+ property Component tickmarkValueStyle: GaugeStyle {
+ tickmark: Rectangle {
+ implicitWidth: 10
+ implicitHeight: 4
+ objectName: "tickmark" + styleData.index
+
+ readonly property real value: styleData.value
+ readonly property real valuePosition: styleData.valuePosition
+ }
+
+ minorTickmark: Rectangle {
+ implicitWidth: 5
+ implicitHeight: 2
+ objectName: "minorTickmark" + styleData.index
+
+ readonly property real value: styleData.value
+ readonly property real valuePosition: styleData.valuePosition
+ }
+ }
+
+ function test_gaugeTickmarkValues_data() {
+ var data = [
+ {
+ tickmarkStepSize: 1, minorTickmarkCount: 4, minimumValue: 0, maximumValue: 5,
+ expectedTickmarkValues: [0, 1, 2, 3, 4, 5],
+ expectedMinorTickmarkValues: [0.2, 0.4, 0.6, 0.8, 1.2, 1.4, 1.6, 1.8, 2.2, 2.4,
+ 2.6, 2.8, 3.2, 3.4, 3.6, 3.8, 4.2, 4.4, 4.6, 4.8],
+ expectedTickmarkValuePositions: [0, 19, 38, 58, 77, 96],
+ expectedMinorTickmarkValuePositions: [6, 9, 12, 15, 25, 28, 31, 34, 44, 47, 51, 54, 64, 67, 70, 73, 83, 86, 89, 92]
+ },
+ {
+ tickmarkStepSize: 1, minorTickmarkCount: 1, minimumValue: 0, maximumValue: 5,
+ expectedTickmarkValues: [0, 1, 2, 3, 4, 5],
+ expectedMinorTickmarkValues: [0.5, 1.5, 2.5, 3.5, 4.5],
+ expectedTickmarkValuePositions: [0, 19, 38, 58, 77, 96],
+ expectedMinorTickmarkValuePositions: [11, 30, 49, 68, 87]
+ },
+ {
+ tickmarkStepSize: 1, minorTickmarkCount: 1, minimumValue: -1, maximumValue: 1,
+ expectedTickmarkValues: [-1, 0, 1],
+ expectedMinorTickmarkValues: [-0.5, 0.5],
+ expectedTickmarkValuePositions: [0, 48, 96],
+ expectedMinorTickmarkValuePositions: [25, 73]
+ },
+ {
+ tickmarkStepSize: 1, minorTickmarkCount: 1, minimumValue: -2, maximumValue: -1,
+ expectedTickmarkValues: [-2, -1],
+ expectedMinorTickmarkValues: [-1.5],
+ expectedTickmarkValuePositions: [0, 96],
+ expectedMinorTickmarkValuePositions: [49]
+ },
+ {
+ tickmarkStepSize: 0.5, minorTickmarkCount: 1, minimumValue: 1, maximumValue: 2,
+ expectedTickmarkValues: [1, 1.5, 2],
+ expectedMinorTickmarkValues: [1.25, 1.75],
+ expectedTickmarkValuePositions: [0, 48, 96],
+ expectedMinorTickmarkValuePositions: [25, 73]
+ },
+ {
+ tickmarkStepSize: 0.5, minorTickmarkCount: 1, minimumValue: -0.5, maximumValue: 0.5,
+ expectedTickmarkValues: [-0.5, 0, 0.5],
+ expectedMinorTickmarkValues: [-0.25, 0.25],
+ expectedTickmarkValuePositions: [0, 48, 96],
+ expectedMinorTickmarkValuePositions: [25, 73]
+ }
+ ];
+
+ for (var i = 0; i < data.length; ++i) {
+ data[i].tag = "tickmarkStepSize=" + data[i].tickmarkStepSize
+ + " minorTickmarkCount=" + data[i].minorTickmarkCount
+ + " minimumValue=" + data[i].minimumValue
+ + " maximumValue=" + data[i].maximumValue;
+ }
+
+ return data;
+ }
+
+ function gaugeHeightFor100PixelHighValueBar(gauge) {
+ return 100 + gauge.__panel.tickmarkOffset * 2 - 2;
+ }
+
+ function test_gaugeTickmarkValues(data) {
+ gauge.minimumValue = data.minimumValue;
+ gauge.maximumValue = data.maximumValue;
+ gauge.minorTickmarkCount = data.minorTickmarkCount;
+ gauge.tickmarkStepSize = data.tickmarkStepSize;
+ gauge.style = tickmarkValueStyle;
+
+ // To make it easier on us, we expect the max length of the value bar to be 100.
+ gauge.height = gaugeHeightFor100PixelHighValueBar(gauge);
+ compare(gauge.__panel.barLength, 100);
+
+ // Give stuff time to re-layout after the new control height, etc.,
+ // otherwise we'll be comparing against incorrect pixel positions.
+ wait(0);
+
+ for (var tickmarkIndex = 0; tickmarkIndex < data.expectedTickmarkValues.length; ++tickmarkIndex) {
+ var tickmark = TestUtils.findChild(gauge, "tickmark" + tickmarkIndex);
+ compare(tickmark.value, data.expectedTickmarkValues[tickmarkIndex],
+ "Value of tickmark at index " + tickmarkIndex + " is " + data.expectedTickmarkValues[tickmarkIndex]);
+
+ var expectedValuePos = data.expectedTickmarkValuePositions[tickmarkIndex];
+ compare(tickmark.valuePosition, expectedValuePos,
+ "Value position of tickmark at index " + tickmarkIndex + " is " + expectedValuePos);
+ }
+
+ for (var minorTickmarkIndex = 0; minorTickmarkIndex < data.expectedMinorTickmarkValues.length; ++minorTickmarkIndex) {
+ var minorTickmark = TestUtils.findChild(gauge, "minorTickmark" + minorTickmarkIndex);
+ compare(minorTickmark.value, data.expectedMinorTickmarkValues[minorTickmarkIndex],
+ "Value of minor tickmark at index " + minorTickmarkIndex + " is " + data.expectedMinorTickmarkValues[minorTickmarkIndex]);
+
+ expectedValuePos = data.expectedMinorTickmarkValuePositions[minorTickmarkIndex];
+ compare(minorTickmark.valuePosition, expectedValuePos,
+ "Value position of minor tickmark at index " + minorTickmarkIndex + " is " + expectedValuePos);
+ }
+ }
+
+ function test_formatValue() {
+ var formatValueCalled = false;
+ gauge.formatValue = function(value) { formatValueCalled = true; return value; }
+ verify(formatValueCalled);
+ }
+
+ function test_valuePosition() {
+ gauge.minimumValue = 0;
+ gauge.maximumValue = 100;
+ gauge.tickmarkStepSize = 10;
+
+ // To make it easier on us, we expect the max length of the value bar to be 100.
+ gauge.height = gaugeHeightFor100PixelHighValueBar(gauge);
+ compare(gauge.__panel.barLength, 100);
+
+ for (var i = gauge.minimumValue; i < gauge.maximumValue; ++i) {
+ compare(gauge.__style.valuePosition, 0);
+ }
+ }
+}
diff --git a/tests/auto/extras/data/tst_picture.qml b/tests/auto/extras/data/tst_picture.qml
new file mode 100644
index 00000000..3c3c4391
--- /dev/null
+++ b/tests/auto/extras/data/tst_picture.qml
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtTest 1.0
+import QtQuick 2.4
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private 1.0
+
+TestCase {
+ id: testCase
+ name: "Tests_Picture"
+ visible: windowShown
+ when: windowShown
+ width: 400
+ height: 400
+
+ property var picture
+
+ /*
+ picture.dat was generated with a 10 width pen, and:
+
+ painter.drawEllipse(painter.pen().width() / 2, painter.pen().width() / 2,
+ 100 - painter.pen().width(), 100 - painter.pen().width());
+ */
+ property color pictureDotDatDefaultColor: Qt.rgba(0, 0, 0, 1)
+ property size pictureDotDatImplicitSize: Qt.size(100, 100)
+
+ function cleanup() {
+ if (picture)
+ picture.destroy();
+ }
+
+ function test_instance() {
+ picture = Qt.createQmlObject("import QtQuick.Extras 1.3; Picture { }", testCase, "");
+ verify(picture, "Picture: failed to create an instance");
+ }
+
+ function test_source_data() {
+ return [
+ {
+ tag: "picture.dat",
+ implicitSize: pictureDotDatImplicitSize,
+ pixels: [
+ { x: 0, y: 0, color: Qt.rgba(1, 1, 1, 1) },
+ { x: 18, y: 18, color: pictureDotDatDefaultColor },
+ { x: 50, y: 50, color: Qt.rgba(1, 1, 1, 1) }
+ ]
+ }
+ ];
+ }
+
+ function test_source(data) {
+ picture = Qt.createQmlObject("import QtQuick.Extras 1.3; Picture {}", testCase, "");
+ verify(picture, "Picture: failed to create an instance");
+ picture.source = data.tag;
+ picture.width = data.implicitSize.width;
+ picture.height = data.implicitSize.height;
+ waitForRendering(picture);
+
+ var pictureImage = grabImage(picture);
+
+ for (var i = 0; i < data.pixels.length; ++i) {
+ var pixel = data.pixels[i];
+ // TODO: use compare when QTBUG-34878 is fixed
+ verify(Qt.colorEqual(pictureImage.pixel(pixel.x, pixel.y), pixel.color),
+ "pixel " + pictureImage.pixel(pixel.x, pixel.y) + " at "
+ + pixel.x + "," + pixel.y + " isn't equal to " + pixel.color);
+ }
+ }
+
+ function test_color_data() {
+ return [
+ { tag: "undefined", color: undefined, expectedColor: pictureDotDatDefaultColor },
+ { tag: "not a valid color", color: "not a valid color", expectedColor: pictureDotDatDefaultColor },
+ { tag: "red", color: "red", expectedColor: Qt.rgba(1, 0, 0, 1) },
+ { tag: "black", color: "black", expectedColor: Qt.rgba(0, 0, 0, 1) }
+ ]
+ }
+
+ function test_color(data) {
+ picture = Qt.createQmlObject("import QtQuick.Extras 1.3; Picture {}", testCase, "");
+ verify(picture, "Picture: failed to create an instance");
+
+ picture.width = pictureDotDatImplicitSize.width;
+ picture.height = pictureDotDatImplicitSize.height;
+ picture.source = "picture.dat";
+ picture.color = data.color;
+ waitForRendering(picture);
+
+ var pictureImage = grabImage(picture);
+
+ verify(Qt.colorEqual(pictureImage.pixel(0, 0), Qt.rgba(1, 1, 1, 1)));
+ verify(Qt.colorEqual(pictureImage.pixel(17, 17), data.expectedColor));
+ verify(Qt.colorEqual(pictureImage.pixel(picture.width / 2, picture.height / 2), Qt.rgba(1, 1, 1, 1)));
+ }
+
+ FontMetrics {
+ id: fontMetrics
+ }
+
+ function test_size() {
+ picture = Qt.createQmlObject("import QtQuick.Extras 1.3; Picture {}", testCase, "");
+ verify(picture, "Picture: failed to create an instance");
+
+ compare(picture.implicitWidth, fontMetrics.height * 4);
+ compare(picture.implicitHeight, fontMetrics.height * 4);
+ compare(picture.width, picture.implicitWidth);
+ compare(picture.height, picture.implicitHeight);
+
+ picture.source = "picture.dat";
+ compare(picture.implicitWidth, pictureDotDatImplicitSize.width);
+ compare(picture.implicitHeight, pictureDotDatImplicitSize.height);
+ compare(picture.width, picture.implicitWidth);
+ compare(picture.height, picture.implicitHeight);
+ }
+}
diff --git a/tests/auto/extras/data/tst_piemenu.qml b/tests/auto/extras/data/tst_piemenu.qml
new file mode 100644
index 00000000..fa109a1a
--- /dev/null
+++ b/tests/auto/extras/data/tst_piemenu.qml
@@ -0,0 +1,836 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtTest 1.0
+import QtQuick 2.1
+import QtQuick.Controls 1.1
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private 1.0
+import QtQuick.Extras.Private.CppUtils 1.0
+
+// Have to have Item here otherwise mouse clicks don't work.
+Item {
+ id: container
+ width: 400
+ height: 400
+
+ TestCase {
+ id: testcase
+ name: "Tests_PieMenu"
+ when: windowShown
+ anchors.fill: parent
+
+ readonly property real menuWidth: 200
+ readonly property real menuHeight: 200
+
+ // The root item for each test, if one exists.
+ property Item root
+ // The pie menu for each test, if no root is created.
+ property Item pieMenu
+
+ SignalSpy {
+ id: currentIndexSignalSpy
+ }
+
+ SignalSpy {
+ id: actionSignalSpy
+ }
+
+ SignalSpy {
+ id: selectedAngleChangedSpy
+ }
+
+ function cleanup() {
+ currentIndexSignalSpy.clear();
+ actionSignalSpy.clear();
+ selectedAngleChangedSpy.clear();
+
+ if (root)
+ root.destroy();
+ if (pieMenu)
+ pieMenu.destroy();
+ }
+
+ function mouseButtonToString(button) {
+ return button === Qt.LeftButton ? "Qt.LeftButton" : "Qt.RightButton";
+ }
+
+ function triggerModeToString(triggerMode) {
+ return triggerMode === TriggerMode.TriggerOnPress ? "TriggerOnPress"
+ : (triggerMode === TriggerMode.TriggerOnRelease ? "TriggerOnRelease" : "TriggerOnClick");
+ }
+
+ function test_instance() {
+ var pieMenu = Qt.createQmlObject("import QtQuick.Extras 1.3; PieMenu { }", container, "");
+ verify(pieMenu, "PieMenu: failed to create an instance");
+ verify(pieMenu.__style);
+ compare(pieMenu.triggerMode, TriggerMode.TriggerOnClick);
+ pieMenu.destroy();
+
+ // Ensure setting visible = true; visible = false; in onCompleted doesn't cause any problems.
+ var pieMenuComponent = Qt.createComponent("PieMenuVisibleOnCompleted.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ pieMenu = pieMenuComponent.createObject(container);
+ verify(pieMenu, "PieMenu: failed to create an instance");
+ pieMenu.destroy();
+
+ // Ensure constructing a menu as a property (and hence no parent)
+ // with visible = true doesn't cause any problems.
+ pieMenuComponent = Qt.createComponent("PieMenuVisibleButNoParent.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ pieMenu = pieMenuComponent.createObject(container);
+ verify(pieMenu, "PieMenu: failed to create an instance");
+ pieMenu.destroy();
+ }
+
+ function test_triggerMode() {
+ var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ root = pieMenuComponent.createObject(container);
+ var mouseArea = root.mouseArea;
+ var pieMenu = root.pieMenu;
+ currentIndexSignalSpy.signalName = "onCurrentIndexChanged"
+ currentIndexSignalSpy.target = pieMenu;
+ actionSignalSpy.signalName = "onActionTriggered";
+ actionSignalSpy.target = root;
+
+ compare(pieMenu.triggerMode, TriggerMode.TriggerOnClick);
+
+ var triggerModes = [
+ TriggerMode.TriggerOnClick,
+ TriggerMode.TriggerOnPress,
+ TriggerMode.TriggerOnRelease
+ ];
+ // Our root mouse area will accept either left click or right click,
+ // and the menu should accept either to select items or close it.
+ var buttonVariations = [
+ [Qt.LeftButton, Qt.LeftButton],
+ [Qt.RightButton, Qt.RightButton],
+ [Qt.LeftButton, Qt.RightButton],
+ [Qt.RightButton, Qt.LeftButton]
+ ];
+ for (var modeIndex = 0; modeIndex < triggerModes.length; ++modeIndex) {
+ for (var i = 0; i < buttonVariations.length; ++i) {
+ var openButton = buttonVariations[i][0];
+ var closeButton = buttonVariations[i][1];
+
+ pieMenu.triggerMode = triggerModes[modeIndex];
+ compare(pieMenu.triggerMode, triggerModes[modeIndex]);
+
+ // Make the menu visible.
+ if (pieMenu.triggerMode !== TriggerMode.TriggerOnRelease) {
+ mouseClick(root, 0, 0, openButton);
+ } else {
+ mousePress(root, 0, 0, openButton);
+ }
+ tryCompare(pieMenu, "visible", true);
+
+ // Click/press outside the menu to close it.
+ switch (pieMenu.triggerMode) {
+ case TriggerMode.TriggerOnClick:
+ mouseClick(root, 0, 0, closeButton);
+ tryCompare(currentIndexSignalSpy, "count", 0);
+ compare(pieMenu.visible, false, "Menu isn't closed when clicking "
+ + mouseButtonToString(closeButton) + " outside (triggerMode: "
+ + triggerModeToString(pieMenu.triggerMode) + ", openButton: "
+ + mouseButtonToString(openButton) + ")");
+ break;
+ case TriggerMode.TriggerOnPress:
+ mousePress(root, 0, 0, closeButton);
+ tryCompare(currentIndexSignalSpy, "count", 0);
+ compare(pieMenu.visible, false, "Menu isn't closed when pressing "
+ + mouseButtonToString(closeButton) + " outside (triggerMode: "
+ + triggerModeToString(pieMenu.triggerMode) + ", openButton: "
+ + mouseButtonToString(openButton) + ")");
+ mouseRelease(root, 0, 0, closeButton);
+ tryCompare(currentIndexSignalSpy, "count", 0);
+ compare(pieMenu.visible, false, "Menu shouldn't be opened when releasing "
+ + mouseButtonToString(closeButton) + " outside (triggerMode: "
+ + triggerModeToString(pieMenu.triggerMode) + ", openButton: "
+ + mouseButtonToString(openButton) + ")");
+ break;
+ case TriggerMode.TriggerOnRelease:
+ mouseRelease(root, 0, 0, closeButton);
+ tryCompare(currentIndexSignalSpy, "count", 0);
+ compare(pieMenu.visible, false, "Menu is closed when releasing "
+ + mouseButtonToString(closeButton) + " outside");
+ break;
+ }
+
+ // Make the menu visible again.
+ if (pieMenu.triggerMode !== TriggerMode.TriggerOnRelease) {
+ mouseClick(root, 0, 0, openButton);
+ } else {
+ mousePress(root, 0, 0, openButton);
+ }
+ tryCompare(pieMenu, "visible", true);
+
+ switch (pieMenu.triggerMode) {
+ case TriggerMode.TriggerOnClick:
+ // Click on a section of the menu (index 1); it should trigger the item and then close the menu.
+ mouseClick(root, pieMenu.x + pieMenu.width / 2, pieMenu.y + pieMenu.height / 4, closeButton);
+ // The current index changes once when the item is selected (1) and once when the menu closes (-1).
+ tryCompare(currentIndexSignalSpy, "count", 2);
+ compare(actionSignalSpy.count, 1);
+ compare(actionSignalSpy.signalArguments[0][0], 1);
+ compare(pieMenu.currentIndex, -1);
+ compare(pieMenu.visible, false);
+ break;
+ case TriggerMode.TriggerOnPress:
+ // Press on a section of the menu (index 1); it should trigger the item and then close the menu.
+ mousePress(root, pieMenu.x + pieMenu.width / 2, pieMenu.y + pieMenu.height / 4, closeButton);
+ // The current index changes once when the item is selected (1) and once when the menu closes (-1).
+ tryCompare(currentIndexSignalSpy, "count", 2);
+ compare(actionSignalSpy.count, 1);
+ compare(actionSignalSpy.signalArguments[0][0], 1);
+ compare(pieMenu.currentIndex, -1);
+ compare(pieMenu.visible, false);
+
+ mouseRelease(root, pieMenu.x + pieMenu.width / 2, pieMenu.y + pieMenu.height / 4, closeButton);
+ // None of these should change after releasing.
+ tryCompare(currentIndexSignalSpy, "count", 2);
+ compare(actionSignalSpy.count, 1);
+ compare(pieMenu.currentIndex, -1);
+ compare(pieMenu.visible, false);
+ break;
+ case TriggerMode.TriggerOnRelease:
+ // Click/press on a section of the menu (index 1); it should trigger the item and then close the menu.
+ mouseRelease(root, pieMenu.x + pieMenu.width / 2, pieMenu.y + pieMenu.height / 4, closeButton);
+ // The current index changes once when the item is selected (1) and once when the menu closes (-1).
+ tryCompare(currentIndexSignalSpy, "count", 2);
+ compare(actionSignalSpy.count, 1);
+ compare(actionSignalSpy.signalArguments[0][0], 1);
+ compare(pieMenu.currentIndex, -1);
+ compare(pieMenu.visible, false);
+ }
+
+ currentIndexSignalSpy.clear();
+ actionSignalSpy.clear();
+ }
+ }
+ }
+
+ function test_selectionAngle_data() {
+ var data = [];
+
+ var dataRow = {};
+ dataRow.startAngle = -90;
+ dataRow.endAngle = 90;
+ dataRow.mouseX = 1;
+ dataRow.mouseY = 1;
+ dataRow.expectedAngle = -Math.PI / 4;
+ dataRow.expectedCurrentIndex = -1;
+ dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", top left";
+ data.push(dataRow);
+
+ dataRow = {};
+ dataRow.startAngle = -90;
+ dataRow.endAngle = 90;
+ dataRow.mouseX = menuWidth - 1;
+ dataRow.mouseY = menuHeight - 1;
+ dataRow.expectedAngle = Math.PI * 0.75;
+ dataRow.expectedCurrentIndex = -1;
+ dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", bottom right";
+ data.push(dataRow);
+
+ dataRow = {};
+ dataRow.startAngle = -90;
+ dataRow.endAngle = -270;
+ dataRow.mouseX = menuWidth / 2 - 1;
+ dataRow.mouseY = menuHeight * 0.75;
+ dataRow.expectedAngle = -3.1215953196166426;
+ dataRow.expectedCurrentIndex = 1;
+ dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", bottom left edge";
+ data.push(dataRow);
+
+ dataRow = {};
+ dataRow.startAngle = -90;
+ dataRow.endAngle = -270;
+ dataRow.mouseX = menuWidth / 2 + 1;
+ dataRow.mouseY = menuHeight * 0.75;
+ dataRow.expectedAngle = 3.1215953196166426;
+ dataRow.expectedCurrentIndex = 1;
+ dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", bottom right edge";
+ data.push(dataRow);
+
+ dataRow = {};
+ dataRow.startAngle = 0;
+ dataRow.endAngle = 190;
+ dataRow.mouseX = menuWidth / 2 - 1;
+ dataRow.mouseY = menuHeight * 0.75;
+ dataRow.expectedAngle = -3.1215953196166426;
+ dataRow.expectedCurrentIndex = 2;
+ dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", bottom left edge";
+ data.push(dataRow);
+
+ dataRow = {};
+ dataRow.startAngle = 0;
+ dataRow.endAngle = -90;
+ dataRow.mouseX = menuWidth / 4;
+ dataRow.mouseY = menuHeight / 2 - 1;
+ dataRow.expectedAngle = -1.550798992821746;
+ dataRow.expectedCurrentIndex = 2;
+ dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", section 2";
+ data.push(dataRow);
+
+ dataRow = {};
+ dataRow.startAngle = 0;
+ dataRow.endAngle = -90;
+ dataRow.mouseX = menuWidth / 4;
+ dataRow.mouseY = menuHeight / 4;
+ dataRow.expectedAngle = -0.7853981633974483;
+ dataRow.expectedCurrentIndex = 1;
+ dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", section 1";
+ data.push(dataRow);
+
+ dataRow = {};
+ dataRow.startAngle = 0;
+ dataRow.endAngle = -90;
+ dataRow.mouseX = menuWidth / 2 - 1;
+ dataRow.mouseY = menuHeight / 4;
+ dataRow.expectedAngle = -0.01999733397315053;
+ dataRow.expectedCurrentIndex = 0;
+ dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", section 0";
+ data.push(dataRow);
+
+ dataRow = {};
+ dataRow.startAngle = -190;
+ dataRow.endAngle = -90;
+ dataRow.mouseX = menuWidth / 2 + 1;
+ dataRow.mouseY = menuHeight * 0.75;
+ dataRow.expectedAngle = 3.1215953196166426;
+ dataRow.expectedCurrentIndex = 0;
+ dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", bottom right edge";
+ data.push(dataRow);
+
+ dataRow = {};
+ dataRow.startAngle = -90;
+ dataRow.endAngle = -190;
+ dataRow.mouseX = menuWidth / 2 + 1;
+ dataRow.mouseY = menuHeight * 0.75;
+ dataRow.expectedAngle = 3.1215953196166426;
+ dataRow.expectedCurrentIndex = 2;
+ dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", bottom right edge";
+ data.push(dataRow);
+
+ return data;
+ }
+
+ function test_selectionAngle(data) {
+ var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ root = pieMenuComponent.createObject(container);
+ var mouseArea = root.mouseArea;
+ var pieMenu = root.pieMenu;
+
+ compare(pieMenu.selectionAngle, 0);
+
+ pieMenu.__style.startAngle = data.startAngle;
+ pieMenu.__style.endAngle = data.endAngle;
+
+ waitForRendering(root);
+ root.forceActiveFocus();
+ // Don't allow bounds snapping by always opening within bounds.
+ mouseClick(root, menuWidth / 2, menuHeight / 2);
+ tryCompare(pieMenu, "visible", true);
+
+ mouseMove(root, data.mouseX, data.mouseY);
+ compare(pieMenu.selectionAngle, data.expectedAngle);
+ compare(pieMenu.currentIndex, data.expectedCurrentIndex);
+ }
+
+ function test_sectionAngles_data() {
+ var data = [];
+ var angleOrigin = 90;
+
+ var dataRow = {};
+ dataRow.startAngle = -90;
+ dataRow.endAngle = 90;
+ dataRow.section = 0;
+ dataRow.expectedSectionSize = MathUtils.degToRadOffset(60 + angleOrigin);
+ dataRow.expectedSectionStartAngle = MathUtils.degToRadOffset(-90);
+ dataRow.expectedSectionCenterAngle = MathUtils.degToRadOffset(-60);
+ dataRow.expectedSectionEndAngle = MathUtils.degToRadOffset(-30);
+ dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", section=" + dataRow.section;
+ data.push(dataRow);
+
+ dataRow = {};
+ dataRow.startAngle = 270;
+ dataRow.endAngle = 90;
+ dataRow.section = 0;
+ dataRow.expectedSectionSize = MathUtils.degToRadOffset(-60 + angleOrigin);
+ dataRow.expectedSectionStartAngle = MathUtils.degToRadOffset(270);
+ dataRow.expectedSectionCenterAngle = MathUtils.degToRadOffset(240);
+ dataRow.expectedSectionEndAngle = MathUtils.degToRadOffset(210);
+ dataRow.tag = "startAngle=" + dataRow.startAngle + ", endAngle=" + dataRow.endAngle + ", section=" + dataRow.section;
+ data.push(dataRow);
+
+ return data;
+ }
+
+ function test_sectionAngles(data) {
+ var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ root = pieMenuComponent.createObject(container);
+ var pieMenu = root.pieMenu;
+
+ pieMenu.__style.startAngle = data.startAngle;
+ pieMenu.__style.endAngle = data.endAngle;
+ compare(pieMenu.__protectedScope.sectionSize, data.expectedSectionSize);
+ compare(pieMenu.__protectedScope.sectionStartAngle(data.section), data.expectedSectionStartAngle);
+ compare(pieMenu.__protectedScope.sectionCenterAngle(data.section), data.expectedSectionCenterAngle);
+ compare(pieMenu.__protectedScope.sectionEndAngle(data.section), data.expectedSectionEndAngle);
+ }
+
+ function test_bounds_data() {
+ return [
+ { tag: "noSnapCenter", mouseX: container.width / 2, mouseY: container.height / 2,
+ expectedX: container.width / 2 - 100, expectedY: container.height / 2 - 100 },
+ { tag: "noSnapNearLeft", mouseX: 100, mouseY: container.height / 2,
+ expectedX: 0, expectedY: container.height / 2 - 100 },
+ { tag: "noSnapNearRight", mouseX: container.width - 100, mouseY: container.height / 2,
+ expectedX: container.width - menuWidth, expectedY: container.height / 2 - 100 },
+ { tag: "noSnapNearTop", mouseX: container.width / 2, mouseY: 100,
+ expectedX: container.width / 2 - 100, expectedY: 0 },
+ { tag: "noSnapNearBottom", mouseX: container.width / 2, mouseY: container.height - 100,
+ expectedX: container.width / 2 - 100, expectedY: container.height - menuHeight },
+ { tag: "noSnapNearTopLeft", mouseX: 100, mouseY: 100,
+ expectedX: 0, expectedY: 0 },
+ { tag: "noSnapNearTopRight", mouseX: container.width - 100, mouseY: 100,
+ expectedX: container.width - menuWidth, expectedY: 0 },
+ { tag: "noSnapNearBottomRight", mouseX: container.width - 100, mouseY: container.height - 100,
+ expectedX: container.width - menuWidth, expectedY: container.height - menuHeight },
+ { tag: "noSnapNearBottomLeft", mouseX: 100, mouseY: container.height - 100,
+ expectedX: 0, expectedY: container.height - menuHeight },
+ { tag: "leftEdge", mouseX: 10, mouseY: container.height / 2,
+ expectedX: 0, expectedY: container.height / 2 - 100 },
+ { tag: "rightEdge", mouseX: container.width - 10, mouseY: container.height / 2,
+ expectedX: container.width - menuHeight, expectedY: container.height / 2 - 100 },
+ { tag: "topEdge", mouseX: container.width / 2, mouseY: 10,
+ expectedX: container.width / 2 - 100, expectedY: 0 },
+ // The default start and end angles mean that the bottom edge won't snap.
+ { tag: "bottomEdge", mouseX: container.width / 2, mouseY: container.height - 10,
+ expectedX: container.width / 2 - 100, expectedY: container.height - 100 - 10 },
+ { tag: "topLeftCorner", mouseX: 10, mouseY: 10,
+ expectedX: 0, expectedY: 0 },
+ { tag: "topRightCorner", mouseX: container.width - 10, mouseY: 10,
+ expectedX: container.width - menuHeight, expectedY: 0 },
+ { tag: "bottomRightCorner", mouseX: container.width - 10, mouseY: container.height - 10,
+ expectedX: container.width - menuHeight, expectedY: container.height - 100 - 10 },
+ { tag: "bottomLeftCorner", mouseX: 10, mouseY: container.height - 10,
+ expectedX: 0, expectedY: container.height - 100 - 10 }
+ ]
+ }
+
+ function test_bounds(data) {
+ var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ root = pieMenuComponent.createObject(container);
+ var mouseArea = root.mouseArea;
+ var pieMenu = root.pieMenu;
+
+ var rootParent = pieMenu;
+ while (rootParent.parent) {
+ rootParent = rootParent.parent;
+ }
+ // Necessary due to QTBUG-36938
+ rootParent.width = 400;
+ rootParent.height = 400;
+
+ var originalStartAngle = pieMenu.__style.startAngle;
+ var originalEndAngle = pieMenu.__style.endAngle;
+
+ mouseClick(root, data.mouseX, data.mouseY);
+ tryCompare(pieMenu, "visible", true);
+
+ compare(pieMenu.x, data.expectedX);
+ compare(pieMenu.y, data.expectedY);
+
+ // Angles shouldn't change.
+ compare(pieMenu.__style.startAngle, originalStartAngle);
+ compare(pieMenu.__style.endAngle, originalEndAngle);
+
+ // Cancel the menu. Even if it's at the top left, this will land on the cancel area.
+ mouseClick(root, pieMenu.x + pieMenu.width / 2, pieMenu.y + pieMenu.height / 2);
+ compare(pieMenu.visible, false);
+
+ // Angles shouldn't change.
+ compare(pieMenu.__style.startAngle, originalStartAngle);
+ compare(pieMenu.__style.endAngle, originalEndAngle);
+ }
+
+ function test_hideItem_data() {
+ return [
+ { tag: "hideFirst", indexVisibility: [false, true, true], expectedIndexHits: [0, 1, 1], expectedText: ["item1", "item1", "item2"] },
+ { tag: "hideSecond", indexVisibility: [true, false, true], expectedIndexHits: [0, 1, 1], expectedText: ["item0", "item0", "item2"] },
+ { tag: "hideThird", indexVisibility: [true, true, false], expectedIndexHits: [0, 1, 1], expectedText: ["item0", "item0", "item1"] },
+ ];
+ }
+
+ function test_hideItem(data) {
+ var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ root = pieMenuComponent.createObject(container);
+ var mouseArea = root.mouseArea;
+ var pieMenu = root.pieMenu;
+
+ var originalStartAngle = pieMenu.__style.startAngle;
+ var originalEndAngle = pieMenu.__style.endAngle;
+
+ // Store the positions at which we should click before we remove any items.
+ var mousePositions = [Qt.point(40, 70), Qt.point(90, 30), Qt.point(160, 70)];
+
+ while (pieMenu.menuItems.length > 0) {
+ pieMenu.removeItem(pieMenu.menuItems[pieMenu.menuItems.length - 1]);
+ }
+
+ for (var i = 0; i < data.indexVisibility.length; ++i) {
+ var item = pieMenu.addItem("item" + i);
+ item.triggered.connect(function (){ root.actionTriggered(data.expectedIndexHits[i]) })
+ item.visible = data.indexVisibility[i];
+ }
+
+ // Angles shouldn't change.
+ compare(pieMenu.__style.startAngle, originalStartAngle);
+ compare(pieMenu.__style.endAngle, originalEndAngle);
+
+ for (i = 0; i < data.indexVisibility.length; ++i) {
+ actionSignalSpy.signalName = "onActionTriggered";
+ actionSignalSpy.target = root;
+
+ compare(pieMenu.visible, false);
+
+ // Make the menu visible.
+ mouseClick(root, 100, 100, Qt.LeftButton);
+ tryCompare(pieMenu, "visible", true);
+
+ var pos = mousePositions[i];
+
+ mouseMove(root, pos.x, pos.y);
+ // Not all styles have titles.
+ if (pieMenu.__style.title)
+ tryCompare(pieMenu.__panel.titleItem, "text", data.expectedText[i]);
+
+ mouseClick(root, pos.x, pos.y, Qt.LeftButton);
+
+ tryCompare(pieMenu, "visible", false);
+ compare(actionSignalSpy.count, 1);
+ compare(actionSignalSpy.signalArguments[0][0], data.expectedIndexHits[i]);
+
+ actionSignalSpy.clear();
+ }
+ }
+
+ function test_addItem() {
+ pieMenu = Qt.createQmlObject("import QtQuick.Extras 1.1; PieMenu {}", container);
+ compare(pieMenu.menuItems.length, 0);
+
+ pieMenu.addItem("Action 1");
+ compare(pieMenu.menuItems.length, 1);
+ }
+
+ function test_insertItem() {
+ pieMenu = Qt.createQmlObject("import QtQuick.Extras 1.1; PieMenu {}", container);
+ compare(pieMenu.menuItems.length, 0);
+
+ pieMenu.insertItem(0, "Action 1");
+ compare(pieMenu.menuItems.length, 1);
+ compare(pieMenu.menuItems[0].text, "Action 1");
+
+ pieMenu.insertItem(1, "Action 2");
+ compare(pieMenu.menuItems.length, 2);
+ compare(pieMenu.menuItems[0].text, "Action 1");
+ compare(pieMenu.menuItems[1].text, "Action 2");
+ }
+
+ function test_removeItem() {
+ var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ root = pieMenuComponent.createObject(container);
+ var pieMenu = root.pieMenu;
+
+ var originalLength = pieMenu.menuItems.length;
+ for (var i = 0; i < originalLength; ++i) {
+ pieMenu.removeItem(pieMenu.menuItems[pieMenu.menuItems.length - 1]);
+ compare(pieMenu.menuItems.length, originalLength - (i + 1));
+ }
+ }
+
+ function debugMousePosition(pieMenu, mouseX, mouseY, positionText) {
+ var rectItem = Qt.createQmlObject("import QtQuick 2.0; Rectangle { width: 10; height: 10; radius: 5; color: 'red' }", pieMenu);
+ rectItem.x = mouseX - rectItem.width / 2;
+ rectItem.y = mouseY - rectItem.height / 2;
+
+ var textItem = Qt.createQmlObject("import QtQuick 2.0; Text {}", rectItem);
+ textItem.text = positionText;
+ textItem.font.pixelSize = 8;
+ textItem.anchors.centerIn = textItem.parent;
+ }
+
+ function test_selectionItemOnMouseMove_QTRD3024() {
+ // Check when an item is hovered by the mouse, it gets made current
+ // as expected and the current item is cleared when the mouse moves outside the menu
+ var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ root = pieMenuComponent.createObject(container);
+ var mouseArea = root.mouseArea;
+ pieMenu = root.pieMenu;
+
+ // Make the menu visible at (0,0)
+ waitForRendering(root);
+ root.forceActiveFocus();
+ mouseClick(root, 0, 0);
+ tryCompare(pieMenu, "visible", true);
+
+ // Move the mouse over the menu
+ mouseMove(root, 0, 0);
+ compare(pieMenu.currentIndex, -1);
+
+ // We would use a data function for this, but we need access to properties
+ // of the style that change with each style.
+ var data = [];
+ var xCenter = pieMenu.width / 2;
+ var yCenter = pieMenu.height / 2;
+ var startAngleFunction = pieMenu.__protectedScope.sectionStartAngle;
+ var centerAngleFunction = pieMenu.__protectedScope.sectionCenterAngle;
+ var endAngleFunction = pieMenu.__protectedScope.sectionEndAngle;
+
+ var pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, centerAngleFunction(0), 90)
+ data.push({ name: "inside", mouseX: pos.x, mouseY: pos.y, expectedCurrentIndex: 0 });
+
+ pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, startAngleFunction(0) + MathUtils.degToRad(1), pieMenu.__style.cancelRadius + 10);
+ data.push({ name: "bottom", mouseX: pos.x, mouseY: pos.y, expectedCurrentIndex: 0 });
+
+ pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, centerAngleFunction(0), pieMenu.__style.cancelRadius + 10);
+ data.push({ name: "outside", mouseX: pos.x, mouseY: pos.y, expectedCurrentIndex: 0 });
+
+ pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, endAngleFunction(0) - MathUtils.degToRad(1), pieMenu.__style.radius - 1);
+ data.push({ name: "close to second", mouseX: pos.x, mouseY: pos.y, expectedCurrentIndex: 0 });
+
+ pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, centerAngleFunction(1), pieMenu.__style.radius - 1);
+ data.push({ name: "outside", mouseX: pos.x, mouseY: pos.y, expectedCurrentIndex: 1 });
+
+ pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, centerAngleFunction(1) - MathUtils.degToRad(10),
+ pieMenu.__style.cancelRadius + (pieMenu.__style.radius - pieMenu.__style.cancelRadius) / 2);
+ data.push({ name: "inside", mouseX: pos.x, mouseY: pos.y, expectedCurrentIndex: 1 });
+
+ pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, startAngleFunction(1) + MathUtils.degToRad(1),
+ pieMenu.__style.radius - 1);
+ data.push({ name: "close to first", mouseX: pos.x, mouseY: pos.y, expectedCurrentIndex: 1 });
+
+ pos = MathUtils.centerAlongCircle(xCenter, yCenter, 0, 0, centerAngleFunction(1), pieMenu.__style.cancelRadius + 10);
+ data.push({ name: "low center", mouseX: 100, mouseY: 50, expectedCurrentIndex: 1 });
+
+ for (var i = 0; i < data.length; ++i) {
+ var mouseX = data[i].mouseX;
+ var mouseY = data[i].mouseY;
+ var expectedCurrentIndex = data[i].expectedCurrentIndex;
+
+ // Illustrates the positions.
+// debugMousePosition(pieMenu, mouseX, mouseY, i);
+// wait(1000)
+
+ mouseMove(root, mouseX, mouseY);
+ compare(pieMenu.currentIndex, expectedCurrentIndex, data[i].name + ": current index should be "
+ + expectedCurrentIndex + " when mouse is at " + mouseX + ", " + mouseY);
+ }
+ }
+
+ function test_QTRD3027() {
+ // Check that an item's selection is cleared when the mouse moves outside
+ // its boundaries without changing the selectionAngle
+ var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ root = pieMenuComponent.createObject(container);
+ var mouseArea = root.mouseArea;
+ var pieMenu = root.pieMenu;
+
+ // Make the menu visible at (0,0)
+ root.forceActiveFocus();
+ mouseClick(root, 0, 0);
+ tryCompare(pieMenu, "visible", true);
+
+ // Move the mouse over the menu
+ mouseMove(root, 0, 0)
+ compare(pieMenu.currentIndex, -1)
+ // Move over middle item
+ mouseMove(root, 100, 50)
+ compare(pieMenu.currentIndex, 1)
+ selectedAngleChangedSpy.signalName = "onSelectionAngleChanged"
+ selectedAngleChangedSpy.target = pieMenu;
+ // Move outside the middle item without changing angle
+ mouseMove(root, 100, 98)
+ compare(pieMenu.currentIndex, -1)
+ compare(selectedAngleChangedSpy.count, 0)
+ }
+
+ function test_rotatedBoundingItem() {
+ var pieMenuComponent = Qt.createComponent("PieMenuRotatedBoundingItem.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ root = pieMenuComponent.createObject(container);
+ var mouseArea = root.mouseArea;
+ var pieMenu = root.pieMenu;
+
+ mouseClick(root, root.width / 2, root.height / 2, Qt.RightButton);
+ tryCompare(pieMenu, "visible", true);
+
+ mouseMove(root, 230, 145);
+ // Not all styles have titles.
+ if (pieMenu.__style.title)
+ tryCompare(pieMenu.__panel.titleItem, "text", "Action 1");
+
+ actionSignalSpy.signalName = "onActionTriggered";
+ actionSignalSpy.target = root;
+ mouseClick(root, 230, 145);
+ compare(actionSignalSpy.count, 1);
+ compare(actionSignalSpy.signalArguments[0][0], 0);
+ }
+
+ function test_boundingItem() {
+ var oldContainerWidth = container.width;
+ var oldContainerHeight = container.height;
+ container.width = 560;
+ container.height = 560;
+
+ // Tests boundingItem when there are nested margins.
+ var pieMenuComponent = Qt.createComponent("PieMenuBoundingItem.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ root = pieMenuComponent.createObject(container);
+ var mouseArea = root.mouseArea;
+ var pieMenu = root.pieMenu;
+
+ var mouseAreaAbsolutePos = mouseArea.mapToItem(root, 0, 0);
+ mouseClick(root, mouseAreaAbsolutePos.x + mouseArea.width / 2, mouseAreaAbsolutePos.y, Qt.RightButton);
+ compare(pieMenu.visible, true);
+ compare(pieMenu.y, -root.margins);
+
+ mouseClick(root, 0, 0);
+ compare(pieMenu.visible, false);
+
+ var mouseAreaCenterAbsolutePos = mouseArea.mapToItem(root, mouseArea.width / 2, mouseArea.height / 2);
+ mouseClick(root, mouseAreaCenterAbsolutePos.x, mouseAreaCenterAbsolutePos.y, Qt.RightButton);
+ compare(pieMenu.visible, true);
+ compare(pieMenu.mapToItem(root, 0, 0).x, mouseAreaCenterAbsolutePos.x - pieMenu.width / 2);
+ compare(pieMenu.mapToItem(root, 0, 0).y, mouseAreaCenterAbsolutePos.y - pieMenu.height / 2);
+
+ container.width = oldContainerWidth;
+ container.height = oldContainerHeight;
+ }
+
+ function test_longPressTriggerOnClick() {
+ // Tests that a menu that is opened on press or long press does not
+ // get closed by a release event when the triggerMode requires a
+ // press before the release (TriggerOnClick).
+ var pieMenuComponent = Qt.createComponent("PieMenu3ItemsLongPress.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ root = pieMenuComponent.createObject(container);
+ var pieMenu = root.pieMenu;
+
+ mousePress(root, 0, 0, Qt.LeftButton);
+ tryCompare(pieMenu, "visible", true);
+ compare(pieMenu.__mouseThief.receivedPressEvent, false);
+ compare(pieMenu.__protectedScope.pressedIndex, -1);
+
+ mouseRelease(root, 0, 0, Qt.LeftButton);
+ compare(pieMenu.visible, true);
+ compare(pieMenu.__mouseThief.receivedPressEvent, false);
+ compare(pieMenu.__protectedScope.pressedIndex, -1);
+
+ mousePress(root, 0, 0, Qt.LeftButton);
+ compare(pieMenu.visible, true);
+ compare(pieMenu.__mouseThief.receivedPressEvent, true);
+ compare(pieMenu.__protectedScope.pressedIndex, -1);
+
+ mouseRelease(root, 0, 0, Qt.LeftButton);
+ compare(pieMenu.visible, false);
+ compare(pieMenu.__mouseThief.receivedPressEvent, false);
+ compare(pieMenu.__protectedScope.pressedIndex, -1);
+ }
+
+ function test_keepMenuOpenWhenTriggered() {
+ // This functionality is used in the flat example.
+ var pieMenuComponent = Qt.createComponent("PieMenu3ItemsKeepOpen.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ root = pieMenuComponent.createObject(container);
+ var pieMenu = root.pieMenu;
+ actionSignalSpy.signalName = "onActionTriggered";
+ actionSignalSpy.target = root;
+
+ mouseClick(root, 0, 0, Qt.LeftButton);
+ tryCompare(pieMenu, "visible", true);
+
+ mouseClick(root, pieMenu.x + pieMenu.width / 4, pieMenu.y + pieMenu.height / 4, Qt.LeftButton);
+ tryCompare(pieMenu, "visible", true);
+ compare(actionSignalSpy.count, 1);
+ compare(actionSignalSpy.signalArguments[0][0], 0);
+
+ actionSignalSpy.clear();
+ mouseClick(root, pieMenu.x + pieMenu.width / 2, pieMenu.y + pieMenu.height / 4, Qt.LeftButton);
+ tryCompare(pieMenu, "visible", true);
+ compare(actionSignalSpy.count, 1);
+ compare(actionSignalSpy.signalArguments[0][0], 1);
+
+ actionSignalSpy.clear();
+ mouseClick(root, pieMenu.x + pieMenu.width * 0.75, pieMenu.y + pieMenu.height / 4, Qt.LeftButton);
+ tryCompare(pieMenu, "visible", true);
+ compare(actionSignalSpy.count, 1);
+ compare(actionSignalSpy.signalArguments[0][0], 2);
+ }
+
+ function test_pressedIndex() {
+ var pieMenuComponent = Qt.createComponent("PieMenu3Items.qml");
+ tryCompare(pieMenuComponent, "status", Component.Ready);
+ root = pieMenuComponent.createObject(container);
+ pieMenu = root.pieMenu;
+ actionSignalSpy.signalName = "onActionTriggered";
+ actionSignalSpy.target = root;
+
+ mouseClick(root, 0, 0, Qt.LeftButton);
+ tryCompare(pieMenu, "visible", true);
+ compare(pieMenu.__protectedScope.pressedIndex, -1);
+
+ mousePress(root, pieMenu.x + pieMenu.width / 4, pieMenu.y + pieMenu.height / 4, Qt.LeftButton);
+ tryCompare(pieMenu, "visible", true);
+ compare(pieMenu.__protectedScope.pressedIndex, 0);
+
+ mouseRelease(root, pieMenu.x + pieMenu.width / 4, pieMenu.y + pieMenu.height / 4, Qt.LeftButton);
+ tryCompare(pieMenu, "visible", false);
+ compare(actionSignalSpy.count, 1);
+ compare(actionSignalSpy.signalArguments[0][0], 0);
+ compare(pieMenu.__protectedScope.pressedIndex, -1);
+ }
+ }
+}
diff --git a/tests/auto/extras/data/tst_statusindicator.qml b/tests/auto/extras/data/tst_statusindicator.qml
new file mode 100644
index 00000000..e9fa6ac9
--- /dev/null
+++ b/tests/auto/extras/data/tst_statusindicator.qml
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtTest 1.0
+import QtQuick 2.1
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Private 1.0
+
+TestCase {
+ id: testCase
+ name: "Tests_StatusIndicator"
+ visible: windowShown
+ when: windowShown
+ width: 400
+ height: 400
+
+ property var indicator
+
+ function cleanup() {
+ if (indicator)
+ indicator.destroy();
+ }
+
+ function test_instance() {
+ indicator = Qt.createQmlObject("import QtQuick.Extras 1.3; StatusIndicator { }", testCase, "");
+ verify(indicator, "StatusIndicator: failed to create an instance")
+ verify(indicator.__style);
+ }
+
+ function test_active_data() {
+ if (StyleSettings.styleName === "Flat") {
+ return [
+ { tag: "active", active: true, expectedColor: { r: 18, g: 136, b: 203 } },
+ { tag: "inactive", active: false, expectedColor: { r: 179, g: 179, b: 179 } }
+ ];
+ }
+
+ return [
+ { tag: "active", active: true, expectedColor: { r: 255, g: 99, b: 99 } },
+ { tag: "inactive", active: false, expectedColor: { r: 52, g: 52, b: 52 } }
+ ];
+ }
+
+ function test_active(data) {
+ indicator = Qt.createQmlObject("import QtQuick.Extras 1.3; StatusIndicator { }", testCase, "");
+ verify(indicator);
+ compare(indicator.active, false);
+
+ indicator.active = data.active;
+ // Color is slightly different on some platforms/machines, like Windows.
+ var lenience = StyleSettings.styleName === "Flat" ? 0 : 2;
+
+ waitForRendering(indicator);
+ var image = grabImage(indicator);
+ fuzzyCompare(image.red(indicator.width / 2, indicator.height / 2), data.expectedColor.r, lenience);
+ fuzzyCompare(image.green(indicator.width / 2, indicator.height / 2), data.expectedColor.g, lenience);
+ fuzzyCompare(image.blue(indicator.width / 2, indicator.height / 2), data.expectedColor.b, lenience);
+ }
+
+ function test_color() {
+ var flatStyle = StyleSettings.styleName === "Flat";
+
+ indicator = Qt.createQmlObject("import QtQuick.Extras 1.3; StatusIndicator { }", testCase, "");
+ verify(indicator);
+ compare(indicator.color, flatStyle ? "#1288cb" : "#ff0000");
+
+ // The base style uses a gradient for its color, so pure blue will not be pure blue.
+ var expectedR = flatStyle ? 0 : 99;
+ var expectedG = flatStyle ? 0 : 99;
+ var expectedB = flatStyle ? 255 : 255;
+ var lenience = flatStyle ? 0 : 2;
+
+ indicator.active = true;
+ indicator.color = "#0000ff";
+ waitForRendering(indicator);
+ var image = grabImage(indicator);
+ fuzzyCompare(image.red(indicator.width / 2, indicator.height / 2), expectedR, lenience);
+ fuzzyCompare(image.green(indicator.width / 2, indicator.height / 2), expectedG, lenience);
+ fuzzyCompare(image.blue(indicator.width / 2, indicator.height / 2), expectedB, lenience);
+ }
+
+ function test_baseStyleHasOuterShadow() {
+ if (StyleSettings.styleName !== "Base")
+ return;
+
+ indicator = Qt.createQmlObject("import QtQuick.Extras 1.3; StatusIndicator { }", testCase, "");
+ verify(indicator);
+
+ // There should be a "shadow" here...
+ waitForRendering(indicator);
+ var image = grabImage(indicator);
+ verify(image.pixel(indicator.width / 2, 1) !== Qt.rgba(1, 1, 1, 1));
+ }
+}
diff --git a/tests/auto/extras/data/tst_togglebutton.qml b/tests/auto/extras/data/tst_togglebutton.qml
new file mode 100644
index 00000000..46b87f93
--- /dev/null
+++ b/tests/auto/extras/data/tst_togglebutton.qml
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtTest 1.0
+import QtQuick 2.1
+
+TestCase {
+ id: testcase
+ name: "Tests_ToggleButton"
+ visible: windowShown
+ when: windowShown
+ width: 400
+ height: 400
+
+ function test_instance() {
+ var button = Qt.createQmlObject('import QtQuick.Extras 1.3; ToggleButton { }', testcase, '');
+ verify (button, "ToggleButton: failed to create an instance")
+ verify(button.__style)
+ verify(button.checkable)
+ verify(!button.checked)
+ verify(!button.pressed)
+ button.destroy()
+ }
+
+ function test_largeText() {
+ // Should be no binding loop warnings.
+ var button = Qt.createQmlObject("import QtQuick.Extras 1.3; ToggleButton { "
+ + "anchors.centerIn: parent; text: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' }", testcase, "");
+ verify(button, "ToggleButton: failed to create an instance");
+ waitForRendering(button);
+ }
+}
diff --git a/tests/auto/extras/data/tst_tumbler.qml b/tests/auto/extras/data/tst_tumbler.qml
new file mode 100644
index 00000000..936269c8
--- /dev/null
+++ b/tests/auto/extras/data/tst_tumbler.qml
@@ -0,0 +1,503 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtTest 1.0
+import QtQuick 2.1
+import QtQuick.Extras 1.3
+import QtQuick.Extras.Styles 1.3
+import QtQuick.Extras.Private 1.0
+import "TestUtils.js" as TestUtils
+
+Item {
+ id: container
+ width: 200
+ height: 200
+
+ TestCase {
+ id: testCase
+ name: "Tests_Tumbler"
+ when: windowShown
+ anchors.fill: parent
+
+ property var tumbler: null
+
+ property Component simpleColumn: TumblerColumn {
+ model: ListModel {
+ Component.onCompleted: {
+ for (var i = 0; i < 5; ++i) {
+ append({value: i.toString()});
+ }
+ }
+ }
+ }
+
+ property Component simpleColumn6Items: TumblerColumn {
+ model: ListModel {
+ Component.onCompleted: {
+ for (var i = 0; i < 6; ++i) {
+ append({value: i.toString()});
+ }
+ }
+ }
+ }
+
+ function init() {
+ tumbler = Qt.createQmlObject("import QtQuick.Extras 1.3; Tumbler { }", container, "");
+ verify(tumbler, "Tumbler: failed to create an instance");
+ }
+
+ function cleanup() {
+ tumbler.destroy();
+ }
+
+ function test_instance() {
+ // Tests instance creation via init() => cleanup().
+ }
+
+ function columnXCenter(columnIndex) {
+ var columnWidth = tumbler.width / tumbler.columnCount;
+ var halfColumnWidth = (columnWidth) / 2;
+ return tumbler.__style.padding.left + halfColumnWidth + (columnWidth * columnIndex);
+ }
+
+ // visualItemIndex is from 0 to the amount of visible items.
+ function itemCenterPos(columnIndex, visualItemIndex) {
+ var halfDelegateHeight = tumbler.__style.__delegateHeight / 2;
+ var yCenter = tumbler.y + tumbler.__style.padding.top + halfDelegateHeight
+ + (tumbler.__style.__delegateHeight * visualItemIndex);
+ return Qt.point(columnXCenter(columnIndex), yCenter);
+ }
+
+ function test_currentIndex() {
+ var column = simpleColumn.createObject(tumbler);
+ compare(tumbler.addColumn(column), column);
+ compare(tumbler.currentIndexAt(0), 0);
+ compare(column.currentIndex, 0);
+ waitForRendering(tumbler);
+
+ var pos = Qt.point(columnXCenter(0), tumbler.height / 2);
+ mouseDrag(tumbler, pos.x, pos.y, 0, -tumbler.__style.__delegateHeight / 2, Qt.LeftButton, Qt.NoModifier, 200);
+ compare(tumbler.currentIndexAt(0), 1);
+ compare(column.currentIndex, 1);
+ }
+
+ function test_setCurrentIndexAt() {
+ var column = simpleColumn.createObject(tumbler);
+ compare(tumbler.addColumn(column), column);
+ compare(tumbler.currentIndexAt(0), 0);
+ waitForRendering(tumbler);
+
+ tumbler.setCurrentIndexAt(0, -1);
+ compare(tumbler.currentIndexAt(0), 0);
+
+ tumbler.setCurrentIndexAt(0, -2);
+ compare(tumbler.currentIndexAt(0), 0);
+
+ tumbler.setCurrentIndexAt(0, tumbler.getColumn(0).model.count);
+ compare(tumbler.currentIndexAt(0), 0);
+
+ tumbler.setCurrentIndexAt(0, tumbler.getColumn(0).model.count + 1);
+ compare(tumbler.currentIndexAt(0), 0);
+
+ tumbler.setCurrentIndexAt(-1, 0);
+ for (var i = 0; i < tumbler.columnCount; ++i) {
+ compare(tumbler.currentIndexAt(i), 0);
+ }
+
+ tumbler.setCurrentIndexAt(-1, 1);
+ for (i = 0; i < tumbler.columnCount; ++i) {
+ compare(tumbler.currentIndexAt(i), 0);
+ }
+
+ tumbler.setCurrentIndexAt(0, 1);
+ tryCompare(tumbler.__viewAt(0), "offset", 4);
+ compare(tumbler.currentIndexAt(0), 1);
+ }
+
+ function test_visible() {
+ var column = simpleColumn.createObject(tumbler);
+ compare(tumbler.addColumn(column), column);
+ column = simpleColumn.createObject(tumbler);
+ compare(tumbler.addColumn(column), column);
+ compare(tumbler.currentIndexAt(0), 0);
+ waitForRendering(tumbler);
+
+ tumbler.getColumn(1).visible = false;
+ verify(!tumbler.__viewAt(1).visible);
+ // Right-most column never has a separator.
+ compare(tumbler.__viewAt(1).parent.separator, null);
+
+ tumbler.getColumn(1).visible = true;
+ verify(tumbler.__viewAt(1).visible);
+
+ tumbler.getColumn(0).visible = false;
+ verify(!tumbler.__viewAt(0).visible);
+ if (StyleSettings.styleName === "Base")
+ verify(!tumbler.__viewAt(0).parent.separator.visible);
+ }
+
+ function test_keyboardNavigation() {
+ var column = simpleColumn.createObject(tumbler);
+ compare(tumbler.addColumn(column), column);
+ column = simpleColumn.createObject(tumbler);
+ compare(tumbler.addColumn(column), column);
+ compare(tumbler.currentIndexAt(0), 0);
+ waitForRendering(tumbler);
+
+ // Tab through each column twice.
+ for (var i = 0; i < 4; ++i) {
+ var columnIndex = i % 2;
+ // Speed it up.
+ tumbler.__highlightMoveDuration = 50;
+
+ keyClick(Qt.Key_Tab);
+ verify(tumbler.__viewAt(columnIndex).activeFocus);
+
+ // Navigate upwards through entire column.
+ for (var j = 0; j < column.model.count - 1; ++j) {
+ tryCompare(tumbler.__movementDelayTimer, "running", false);
+ keyClick(Qt.Key_Up);
+ tryCompare(tumbler.__viewAt(columnIndex), "offset", j + 1);
+ compare(tumbler.currentIndexAt(columnIndex), column.model.count - 1 - j);
+ }
+
+ tryCompare(tumbler.__movementDelayTimer, "running", false);
+ keyClick(Qt.Key_Up);
+ tryCompare(tumbler.__viewAt(columnIndex), "offset", 0);
+ compare(tumbler.currentIndexAt(columnIndex), 0);
+
+ // Navigate downwards through entire column.
+ for (j = 0; j < column.model.count - 1; ++j) {
+ tryCompare(tumbler.__movementDelayTimer, "running", false);
+ keyClick(Qt.Key_Down);
+ tryCompare(tumbler.__viewAt(columnIndex), "offset", column.model.count - 1 - j);
+ compare(tumbler.currentIndexAt(columnIndex), j + 1);
+ }
+
+ tryCompare(tumbler.__movementDelayTimer, "running", false);
+ keyClick(Qt.Key_Down);
+ tryCompare(tumbler.__viewAt(columnIndex), "offset", 0);
+ compare(tumbler.currentIndexAt(columnIndex), 0);
+ }
+
+ // Shift-tab through columns. Focus is on the last column.
+ for (i = 0; i < 4; ++i) {
+ keyClick(Qt.Key_Tab, Qt.ShiftModifier);
+ verify(tumbler.__viewAt(i % 2).activeFocus);
+ }
+
+ // Go back to the first column.
+ keyClick(Qt.Key_Tab, Qt.ShiftModifier);
+ verify(tumbler.__viewAt(0).activeFocus);
+ compare(tumbler.__viewAt(0).offset, 0);
+ }
+
+ property Component fourItemColumn: TumblerColumn {
+ model: 4
+ }
+
+ property Component fourItemDelegate: Item {
+ implicitHeight: 40
+
+ Text {
+ text: styleData.value
+ anchors.centerIn: parent
+ }
+ }
+
+ function test_itemsCorrectlyPositioned() {
+ // TODO: rewrite this test so that it tests supported usecases.
+ // Somehow it works with the Base style. It could be rewritten to use an
+ // equal amount of items for the model and visibleItemCount, judging from
+ // the snippet in QTBUG-40298.
+ if (StyleSettings.styleName === "Flat")
+ skip("Not a valid test case as the model count is less than the visibleItemCount");
+
+ tumbler.height = 120;
+ // By default, the delegate height is based on the height of the tumbler,
+ // but it starts off at 0.
+ compare(tumbler.__style.__delegateHeight, 0);
+
+ var column = fourItemColumn.createObject(tumbler);
+ column.delegate = fourItemDelegate;
+ compare(tumbler.addColumn(column), column);
+ // Now that the delegate has changed, the binding is reevaluated and we get 120 / 3.
+ compare(tumbler.__style.__delegateHeight, 40);
+ waitForRendering(tumbler);
+
+ keyClick(Qt.Key_Tab)
+ verify(tumbler.__viewAt(0).activeFocus);
+ var firstItemCenterPos = itemCenterPos(0, 1);
+ var firstItem = tumbler.__viewAt(0).itemAt(firstItemCenterPos.x, firstItemCenterPos.y);
+ var actualPos = container.mapFromItem(firstItem, 0, 0);
+ compare(actualPos.x, tumbler.__style.padding.left);
+ compare(actualPos.y, tumbler.__style.padding.top + 40);
+
+ keyClick(Qt.Key_Down);
+ tryCompare(tumbler.__viewAt(0), "offset", 3.0);
+ firstItemCenterPos = itemCenterPos(0, 0);
+ firstItem = tumbler.__viewAt(0).itemAt(firstItemCenterPos.x, firstItemCenterPos.y);
+ verify(firstItem);
+ // Test QTBUG-40298.
+ actualPos = container.mapFromItem(firstItem, 0, 0);
+ compare(actualPos.x, tumbler.__style.padding.left);
+ compare(actualPos.y, tumbler.__style.padding.top);
+
+ var secondItemCenterPos = itemCenterPos(0, 1);
+ var secondItem = tumbler.__viewAt(0).itemAt(secondItemCenterPos.x, secondItemCenterPos.y);
+ verify(secondItem);
+ verify(firstItem.y < secondItem.y);
+
+ var thirdItemCenterPos = itemCenterPos(0, 2);
+ var thirdItem = tumbler.__viewAt(0).itemAt(thirdItemCenterPos.x, thirdItemCenterPos.y);
+ verify(thirdItem);
+ verify(firstItem.y < thirdItem.y);
+ verify(secondItem.y < thirdItem.y);
+ }
+
+ property Component oneHundredItemColumn: TumblerColumn {
+ model: ListModel {
+ Component.onCompleted: {
+ for (var i = 0; i < 100; ++i) {
+ append({value: i.toString()});
+ }
+ }
+ }
+ }
+
+ function test_resizeAfterFlicking() {
+ // Test QTBUG-40367 (which is actually invalid because it was my fault :)).
+ var column = oneHundredItemColumn.createObject(tumbler);
+ compare(tumbler.addColumn(column), column);
+ waitForRendering(tumbler);
+
+ // Flick in some direction.
+ var pos = Qt.point(columnXCenter(0), tumbler.__style.padding.top);
+ mouseDrag(tumbler, pos.x, pos.y, 0, tumbler.height - tumbler.__style.padding.bottom,
+ Qt.LeftButton, Qt.NoModifier, 300);
+ tryCompare(tumbler.__viewAt(0), "offset", StyleSettings.styleName === "Flat" ? 6.0 : 4.0);
+
+ tumbler.height += 100;
+ var padding = tumbler.__style.padding;
+ compare(tumbler.__style.__delegateHeight,
+ (tumbler.height - padding.top - padding.bottom) / tumbler.__style.visibleItemCount);
+ waitForRendering(tumbler);
+ pos = itemCenterPos(0, 1);
+ var ninetyEighthItem = tumbler.__viewAt(0).itemAt(pos.x, pos.y);
+ verify(ninetyEighthItem);
+ }
+
+ property Component dayOfMonthColumn: TumblerColumn {
+ model: ListModel {
+ Component.onCompleted: {
+ for (var i = 0; i < 31; ++i) {
+ append({value: i.toString()});
+ }
+ }
+ }
+ }
+
+ property Component yearColumn: TumblerColumn {
+ model: ListModel {
+ Component.onCompleted: {
+ for (var i = 2000; i < 2100; ++i) {
+ append({value: i.toString()});
+ }
+ }
+ }
+ }
+
+ function test_focusPastLastColumn() {
+ var column = dayOfMonthColumn.createObject(tumbler);
+ compare(tumbler.addColumn(column), column);
+ column = yearColumn.createObject(tumbler);
+ compare(tumbler.addColumn(column), column);
+
+ var mouseArea = Qt.createQmlObject(
+ "import QtQuick 2.2; MouseArea { activeFocusOnTab: true; width: 50; height: 50 }", container, "");
+
+ keyClick(Qt.Key_Tab);
+ verify(tumbler.__viewAt(0).activeFocus);
+ verify(tumbler.getColumn(0).activeFocus);
+ verify(!tumbler.__viewAt(1).activeFocus);
+ verify(!tumbler.getColumn(1).activeFocus);
+
+ keyClick(Qt.Key_Tab);
+ verify(!tumbler.__viewAt(0).activeFocus);
+ verify(!tumbler.getColumn(0).activeFocus);
+ verify(tumbler.__viewAt(1).activeFocus);
+ verify(tumbler.getColumn(1).activeFocus);
+
+ keyClick(Qt.Key_Tab);
+ verify(!tumbler.__viewAt(0).activeFocus);
+ verify(!tumbler.getColumn(0).activeFocus);
+ verify(!tumbler.__viewAt(1).activeFocus);
+ verify(!tumbler.getColumn(1).activeFocus);
+ verify(mouseArea.activeFocus);
+
+ mouseArea.destroy();
+ }
+
+ function test_datePicker() {
+ tumbler.destroy();
+
+ var component = Qt.createComponent("TumblerDatePicker.qml");
+ compare(component.status, Component.Ready);
+ tumbler = component.createObject(container);
+ // Should not be any warnings.
+
+ // March.
+ tumbler.setCurrentIndexAt(1, 2);
+ compare(tumbler.currentIndexAt(1), 2);
+ compare(tumbler.getColumn(1).currentIndex, 2);
+
+ // 30th of March.
+ tumbler.setCurrentIndexAt(0, 29);
+ compare(tumbler.currentIndexAt(0), 29);
+ compare(tumbler.getColumn(0).currentIndex, 29);
+
+ // February.
+ tumbler.setCurrentIndexAt(1, 1);
+ compare(tumbler.currentIndexAt(1), 1);
+ compare(tumbler.getColumn(1).currentIndex, 1);
+ compare(tumbler.getColumn(0).currentIndex, 27);
+ }
+
+ property Component displacementStyle: TumblerStyle {
+ visibleItemCount: 5
+
+ delegate: Item {
+ objectName: "delegate" + styleData.index
+ implicitHeight: (control.height - padding.top - padding.bottom) / visibleItemCount
+
+ property real displacement: styleData.displacement
+
+ Text {
+ text: styleData.value
+ anchors.centerIn: parent
+ }
+
+ Text {
+ anchors.right: parent.right
+ text: styleData.displacement.toFixed(1)
+ }
+ }
+ }
+
+ function test_displacement_data() {
+ var data = [
+ // At 0 offset, the first item is current.
+ { index: 0, offset: 0, expectedDisplacement: 0 },
+ { index: 1, offset: 0, expectedDisplacement: -1 },
+ { index: 5, offset: 0, expectedDisplacement: 1 },
+ // When we start to move the first item down, the second item above it starts to become current.
+ { index: 0, offset: 0.25, expectedDisplacement: -0.25 },
+ { index: 1, offset: 0.25, expectedDisplacement: -1.25 },
+ { index: 5, offset: 0.25, expectedDisplacement: 0.75 },
+ { index: 0, offset: 0.5, expectedDisplacement: -0.5 },
+ { index: 1, offset: 0.5, expectedDisplacement: -1.5 },
+ { index: 5, offset: 0.5, expectedDisplacement: 0.5 },
+ // By this stage, the delegate at index 1 is destroyed, so we can't test its displacement.
+ { index: 0, offset: 0.75, expectedDisplacement: -0.75 },
+ { index: 5, offset: 0.75, expectedDisplacement: 0.25 },
+ { index: 0, offset: 4.75, expectedDisplacement: 1.25 },
+ { index: 1, offset: 4.75, expectedDisplacement: 0.25 },
+ { index: 0, offset: 4.5, expectedDisplacement: 1.5 },
+ { index: 1, offset: 4.5, expectedDisplacement: 0.5 },
+ { index: 0, offset: 4.25, expectedDisplacement: 1.75 },
+ { index: 1, offset: 4.25, expectedDisplacement: 0.75 }
+ ];
+ for (var i = 0; i < data.length; ++i) {
+ var row = data[i];
+ row.tag = "delegate" + row.index + " offset=" + row.offset + " expectedDisplacement=" + row.expectedDisplacement;
+ }
+ return data;
+ }
+
+ function test_displacement(data) {
+ tumbler.style = displacementStyle;
+
+ var column = simpleColumn6Items.createObject(tumbler);
+ compare(tumbler.addColumn(column), column);
+ waitForRendering(tumbler);
+ compare(tumbler.columnCount, 1);
+ compare(tumbler.__viewAt(0).count, 6);
+
+ var delegate = TestUtils.findChild(tumbler, "delegate" + data.index);
+ verify(delegate);
+
+ tumbler.__viewAt(0).offset = data.offset;
+ compare(delegate.displacement, data.expectedDisplacement);
+ }
+
+ function test_visibleItemCount_data() {
+ var data = [
+ // e.g. {0: 2} = {delegate index: y pos / delegate height}
+ // Skip item at index 3, because it's out of view.
+ { model: 6, visibleItemCount: 5, expectedYPositions: {0: 2, 1: 3, 2: 4, 4: 0} },
+ { model: 5, visibleItemCount: 3, expectedYPositions: {0: 1, 1: 2, 4: 0} },
+ // Takes up the whole view.
+ { model: 2, visibleItemCount: 1, expectedYPositions: {0: 0} },
+ ];
+
+ for (var i = 0; i < data.length; ++i) {
+ data[i].tag = "items=" + data[i].model + ", visibleItemCount=" + data[i].visibleItemCount;
+ }
+ return data;
+ }
+
+ function test_visibleItemCount(data) {
+ tumbler.style = displacementStyle;
+ tumbler.__style.visibleItemCount = data.visibleItemCount;
+
+ var column = simpleColumn.createObject(tumbler);
+ column.model = data.model;
+ compare(tumbler.addColumn(column), column);
+ waitForRendering(tumbler);
+ compare(tumbler.columnCount, 1);
+ compare(tumbler.__viewAt(0).count, data.model);
+
+ for (var delegateIndex = 0; delegateIndex < data.visibleItemCount; ++delegateIndex) {
+ if (data.expectedYPositions.hasOwnProperty(delegateIndex)) {
+ var delegate = TestUtils.findChild(tumbler, "delegate" + delegateIndex);
+ verify(delegate, "Delegate found at index " + delegateIndex);
+ var expectedYPos = data.expectedYPositions[delegateIndex] * tumbler.__style.__delegateHeight;
+ compare(delegate.mapToItem(tumbler.__viewAt(0), 0, 0).y, expectedYPos);
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/extras/extras.pro b/tests/auto/extras/extras.pro
new file mode 100644
index 00000000..66ca9573
--- /dev/null
+++ b/tests/auto/extras/extras.pro
@@ -0,0 +1,32 @@
+TEMPLATE = app
+TARGET = tst_extras
+
+CONFIG += qmltestcase console
+CONFIG += insignificant_test # requires qtgraphicaleffects (QTBUG-35112)
+
+SOURCES += $$PWD/tst_extras.cpp
+
+TESTDATA = $$PWD/data/*
+
+OTHER_FILES += \
+ $$PWD/data/tst_circulargauge.qml \
+ $$PWD/data/tst_circulartickmarklabel.qml \
+ $$PWD/data/tst_common.qml \
+ $$PWD/data/tst_dial.qml \
+ $$PWD/data/tst_piemenu.qml \
+ $$PWD/data/tst_delaybutton.qml \
+ $$PWD/data/tst_statusindicator.qml \
+ $$PWD/data/tst_thermometergauge.qml \
+ $$PWD/data/tst_togglebutton.qml \
+ $$PWD/data/tst_tumbler.qml \
+ $$PWD/data/PieMenu3Items.qml \
+ $$PWD/data/PieMenu3ItemsLongPress.qml \
+ $$PWD/data/PieMenu3ItemsKeepOpen.qml \
+ $$PWD/data/PieMenuVisibleOnCompleted.qml \
+ $$PWD/data/PieMenuVisibleButNoParent.qml \
+ $$PWD/data/tst_gauge.qml \
+ $$PWD/data/tst_picture.qml \
+ $$PWD/data/TestUtils.js \
+ $$PWD/data/TumblerDatePicker.qml \
+ $$PWD/data/PieMenuRotatedBoundingItem.qml \
+ $$PWD/data/PieMenuBoundingItem.qml
diff --git a/tests/auto/extras/tst_extras.cpp b/tests/auto/extras/tst_extras.cpp
new file mode 100644
index 00000000..92abacbb
--- /dev/null
+++ b/tests/auto/extras/tst_extras.cpp
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtQuickTest/quicktest.h>
+
+QUICK_TEST_MAIN(extras)
diff --git a/tests/auto/paint/paint.pro b/tests/auto/paint/paint.pro
new file mode 100644
index 00000000..48ec8c02
--- /dev/null
+++ b/tests/auto/paint/paint.pro
@@ -0,0 +1,6 @@
+TEMPLATE = app
+TARGET = tst_paint
+QT += qml quick testlib
+CONFIG += testcase insignificant_test
+
+SOURCES += $$PWD/tst_paint.cpp
diff --git a/tests/auto/paint/tst_paint.cpp b/tests/auto/paint/tst_paint.cpp
new file mode 100644
index 00000000..e7a99b09
--- /dev/null
+++ b/tests/auto/paint/tst_paint.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest>
+#include <QtQml>
+#include <QtQuick>
+
+class tst_Paint : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void bounds_data();
+ void bounds();
+};
+
+void tst_Paint::bounds_data()
+{
+ QTest::addColumn<QString>("name");
+
+ QTest::newRow("CircularGauge") << "CircularGauge";
+ QTest::newRow("Dial") << "Dial";
+ QTest::newRow("Gauge") << "Gauge";
+ QTest::newRow("PieMenu") << "PieMenu";
+ QTest::newRow("DelayButton") << "DelayButton";
+ QTest::newRow("ToggleButton") << "ToggleButton";
+ QTest::newRow("Tumbler") << "Tumbler";
+}
+
+void tst_Paint::bounds()
+{
+ QFETCH(QString, name);
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData(QStringLiteral("import QtQuick.Extras 1.2; %1 { }").arg(name).toUtf8(), QUrl());
+ QQuickItem *control = qobject_cast<QQuickItem*>(component.create());
+ QVERIFY(control);
+
+ const int w = control->width();
+ const int h = control->height();
+ QVERIFY(w > 0);
+ QVERIFY(h > 0);
+
+ static const int margin = 10;
+ static const QColor bg = Qt::yellow;
+
+ QQuickWindow window;
+ window.setColor(bg);
+ window.resize(w + 2 * margin, h + 2 * margin);
+ control->setParentItem(window.contentItem());
+ control->setPosition(QPoint(margin, margin));
+ window.create();
+ window.show();
+
+ QTest::qWaitForWindowExposed(&window);
+
+ const QRect bounds(margin, margin, w, h);
+ const QImage image = window.grabWindow();
+
+ for (int x = 0; x < image.width(); ++x) {
+ for (int y = 0; y < image.height(); ++y) {
+ if (!bounds.contains(x, y)) {
+ const QByteArray msg = QString("painted outside bounds (%1,%2 %3x%4) at (%5,%6)").arg(bounds.x()).arg(bounds.y()).arg(bounds.width()).arg(bounds.height()).arg(x).arg(y).toUtf8();
+ const QColor px = image.pixel(x, y);
+ QVERIFY2(px == bg, msg);
+ }
+ }
+ }
+}
+
+QTEST_MAIN(tst_Paint)
+
+#include "tst_paint.moc"
diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro
new file mode 100644
index 00000000..0453716e
--- /dev/null
+++ b/tests/benchmarks/benchmarks.pro
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+SUBDIRS = \
+ statusindicator
diff --git a/tests/benchmarks/statusindicator/LotsOfIndicatorsActive.qml b/tests/benchmarks/statusindicator/LotsOfIndicatorsActive.qml
new file mode 100644
index 00000000..ff8424f2
--- /dev/null
+++ b/tests/benchmarks/statusindicator/LotsOfIndicatorsActive.qml
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Extras 1.3
+
+Rectangle {
+ id: root
+ width: 240
+ height: 240
+ color: "#444"
+
+ Repeater {
+ model: 50
+
+ delegate: StatusIndicator {
+ x: Math.floor(index % 10) * 8
+ y: Math.floor(index / 10) * 8
+ width: 8
+ height: 8
+ color: Qt.rgba(36 / 255, 141 / 255, 254 / 255)
+ active: true
+ }
+ }
+}
diff --git a/tests/benchmarks/statusindicator/LotsOfIndicatorsInactive.qml b/tests/benchmarks/statusindicator/LotsOfIndicatorsInactive.qml
new file mode 100644
index 00000000..dd5a19a2
--- /dev/null
+++ b/tests/benchmarks/statusindicator/LotsOfIndicatorsInactive.qml
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Extras 1.3
+
+Rectangle {
+ id: root
+ width: 240
+ height: 240
+ color: "#444"
+
+ Repeater {
+ model: 50
+
+ delegate: StatusIndicator {
+ x: Math.floor(index % 10) * 8
+ y: Math.floor(index / 10) * 8
+ width: 8
+ height: 8
+ color: Qt.rgba(36 / 255, 141 / 255, 254 / 255)
+ active: false
+ }
+ }
+}
diff --git a/tests/benchmarks/statusindicator/statusindicator.pro b/tests/benchmarks/statusindicator/statusindicator.pro
new file mode 100644
index 00000000..d66b5515
--- /dev/null
+++ b/tests/benchmarks/statusindicator/statusindicator.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+TARGET = tst_bench_statusindicator
+QT = core quick testlib
+
+SOURCES += \
+ tst_statusindicator.cpp
+
+OTHER_FILES += \
+ LotsOfIndicatorsOn.qml \
+ LotsOfIndicatorsOff.qml
+
+# Define SRCDIR equal to test's source directory
+DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/tests/benchmarks/statusindicator/tst_statusindicator.cpp b/tests/benchmarks/statusindicator/tst_statusindicator.cpp
new file mode 100644
index 00000000..3aa7678a
--- /dev/null
+++ b/tests/benchmarks/statusindicator/tst_statusindicator.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Extras module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtQml/QQmlComponent>
+#include <QtQml/QQmlEngine>
+#include <QtQuick/QQuickItem>
+#include <QtQuick/QQuickWindow>
+
+class tst_StatusIndicator: public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void benchmarkCreation_data();
+ void benchmarkCreation();
+};
+
+void tst_StatusIndicator::benchmarkCreation_data()
+{
+ QTest::addColumn<bool>("active");
+
+ QTest::newRow("active") << true;
+ QTest::newRow("inactive") << false;
+}
+
+void tst_StatusIndicator::benchmarkCreation()
+{
+ QFETCH(bool, active);
+
+ QQuickWindow window;
+ window.resize(240, 240);
+ window.create();
+
+ QQmlEngine engine;
+ // TODO: fix
+ QString path = QString::fromLatin1(SRCDIR "/LotsOfIndicators%1.qml").arg(active ? "Active" : "Inactive");
+ QQmlComponent component(&engine, QUrl::fromLocalFile(path));
+ QVERIFY2(!component.isError(), qPrintable(component.errorString()));
+ QVERIFY(component.isReady());
+ QBENCHMARK {
+ QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+ root->setParentItem(window.contentItem());
+ window.grabWindow();
+ }
+}
+
+QTEST_MAIN(tst_StatusIndicator)
+
+#include "tst_statusindicator.moc"
diff --git a/tests/tests.pro b/tests/tests.pro
index 85e4f3a5..86fcc232 100644
--- a/tests/tests.pro
+++ b/tests/tests.pro
@@ -1,2 +1,2 @@
TEMPLATE = subdirs
-SUBDIRS += auto
+SUBDIRS += auto benchmarks