Compare commits

..
168 Commits
Author SHA1 Message Date
budtmo 226e088390 Updated Appium server to version 1.11.1 2019-02-21 17:57:20 +01:00
budtmo 3574b9825b Merge branch 'master' of github.com:budtmo/docker-android 2019-02-19 10:26:23 +01:00
budtmo d34d635114 Using Appium 1.11.0 2019-02-19 10:26:09 +01:00
Budi UtomoandGitHub 43d38adf76 Updated readme 2019-02-14 13:20:11 +01:00
Budi UtomoandGitHub a2d3c05a1c Merge pull request #145 from fossabot/master
Add license scan report and status
2019-02-12 15:53:56 +01:00
Budi UtomoandGitHub a4c7919209 Merge branch 'master' into master 2019-02-12 15:31:20 +01:00
Budi UtomoandGitHub 2e59c45142 Added PR badge 2019-02-11 10:42:37 +01:00
fossabot 664ad07905 Add license scan report and status
Signed-off-by: fossabot <badges@fossa.io>
2019-02-07 00:55:06 -08:00
Budi UtomoandGitHub 4b7de9d645 Merge pull request #143 from nonVoid/master
change timeout in generated nodeconfig.js from 30000 to 30 [because of Selenium 3.x]
2019-01-31 16:19:57 +01:00
nonVoidandGitHub 5d1cf8e671 Merge branch 'master' into master 2019-01-31 15:41:09 +01:00
Felix Weber 9441d537b7 change timeout in generated nodeconfig.js from 30000 to 30 2019-01-31 15:32:51 +01:00
Budi UtomoandGitHub a40acea0ba Merge pull request #142 from nonVoid/master
Fixed #135
2019-01-31 14:32:29 +01:00
Felix Weber 54811c0c81 change SCREEN_DEPTH to 24+32 in noVNC(xvfb) settings 2019-01-31 14:11:01 +01:00
budtmo 893abf99e4 Added release badge 2019-01-31 10:40:19 +01:00
budtmo 14b6091277 Deleted old video 2019-01-30 15:01:28 +01:00
budtmo 5acbce6654 Renamed 2019-01-30 14:58:31 +01:00
butomo1989 1c844033f6 Merge branch 'master' of github.com:butomo1989/docker-android 2019-01-16 10:49:17 +01:00
butomo1989 83ba9bb79e Using Appium 1.10.1 2019-01-16 10:49:05 +01:00
Budi UtomoandGitHub 712d3485ad Merge pull request #139 from nichotined/master
Added documentation how to connect emulator to the host
2019-01-16 09:36:35 +01:00
Nicholas FrederickandGitHub 04512a0d16 Update README.md
Added Control Android connected to host (Emulator or Real Device)
2019-01-15 22:30:58 +07:00
butomo1989 cf0ebd7eb9 Fixed #138 2019-01-15 10:19:42 +01:00
butomo1989 32cb68f6c9 Updated base image 2019-01-08 10:48:11 +01:00
Budi UtomoandGitHub 98b0b3a140 Merge pull request #134 from tadashi0713/add_unittest_relaxed_security
Add unittest to run appium with relaxed security
2019-01-07 09:20:58 +01:00
Tadashi NemotoandGitHub 2c9c421c35 Merge branch 'master' into add_unittest_relaxed_security 2019-01-05 15:59:12 +09:00
tadashi0713 afea49a2c8 Add unittest to run appium with relaxed security 2019-01-05 15:56:24 +09:00
butomo1989 442a10afd2 Fixed wrong file 2019-01-02 13:32:09 +01:00
butomo1989 478e0d0e51 Added blog about integration between Genymotion and DockerAndroid 2019-01-02 13:29:40 +01:00
butomo1989 17d09eb835 Renamed 2018-11-29 09:16:30 +01:00
butomo1989 09c3fbe765 Edited wrong port 2018-11-29 09:09:07 +01:00
butomo1989 b285d8a1da Renamed type for consistency in article 2018-11-29 09:07:26 +01:00
Budi UtomoandGitHub 46d3a4f8c1 Removed because the content of it is old 2018-11-22 16:39:23 +01:00
butomo1989 033be6d7c4 Keep ssh sessions alive 2018-11-22 12:17:17 +01:00
butomo1989 84ed95aac1 Merge branch 'master' of github.com:butomo1989/docker-android 2018-11-19 13:01:28 +01:00
butomo1989 c298cc7ae1 Enabled of using existing security group 2018-11-19 13:01:18 +01:00
Budi UtomoandGitHub 0ab0eaffcf Typo 2018-11-19 10:53:53 +01:00
butomo1989 0e00cffe4d Corrected the example of json file for Genymotion on AWS 2018-11-15 15:02:29 +01:00
butomo1989 3dc73b4573 Enabled custom security group 2018-11-14 13:56:41 +01:00
Budi UtomoandGitHub 711cbfef72 Updated lines 2018-11-09 15:58:36 +01:00
butomo1989 67a0935fc5 Using custom_ami doesnt need android_version 2018-11-08 12:54:20 +01:00
butomo1989 55012f9ac0 Enable custom AMI which given from the user 2018-11-07 16:29:14 +01:00
butomo1989 2e379769e9 Added engress for AWS deployment for Genymotion 2018-11-05 14:49:59 +01:00
butomo1989 2ffb3a0c3d Added Android version for Google Analytics 2018-11-05 14:28:36 +01:00
butomo1989 e49d2a58cb Enabled GA 2018-10-26 15:54:04 +02:00
butomo1989 099afef2a1 Added header 2018-10-26 15:18:27 +02:00
butomo1989 67a4468b05 Modified file type 2018-10-26 15:05:14 +02:00
butomo1989 21306b5b08 Linked license in README 2018-10-26 15:03:44 +02:00
butomo1989 500fff9da4 Added google analytics and automation script for Genymotion 2018-10-26 15:00:46 +02:00
butomo1989 68db6315d4 Enabled Android 9.0 2018-10-23 16:22:03 +02:00
butomo1989 2ad579c77b Added Android 9.0 2018-10-23 16:17:12 +02:00
Budi UtomoandGitHub bc5cb96ca9 Merge pull request #124 from stazdx/aks-terraform
Custom charts added for deployment on Azure
2018-10-15 12:50:40 +02:00
Staz Dx 85b2312b7f Kompose/volumes.yaml deleted 2018-10-12 18:17:12 -05:00
Staz Dx b518b38c35 Custom chart for running in AKS (recommended) 2018-10-12 18:15:21 -05:00
Staz Dx 1ebdbc7873 Custom chart for running in AKS (recommended) 2018-10-12 18:14:26 -05:00
Budi UtomoandGitHub b3c8cb3cce Merge pull request #123 from stazdx/aks-terraform
Running it in (Azure Kubernetes Service) AKS by using Terraform, Azure CLI, Kompose & Kubectl
2018-10-11 08:18:00 +02:00
Staz Dx 05aa522965 Running in AKS using Terraform, Azure CLI, Kompose & Kubectl 2018-10-10 18:27:18 -05:00
Budi UtomoandGitHub 2a48fc6f71 Merge pull request #122 from kjlubick/patch-1
Added steps for deploying on GCE
2018-10-06 15:19:37 +02:00
Kevin LubickandGitHub fd4a5a0763 Add a bit more verbosity 2018-10-05 14:47:17 -04:00
Kevin LubickandGitHub 7c085db7a3 Add Cloud instructions for GCE 2018-10-05 11:12:55 -04:00
butomo1989 e5817ebe7d Formatted 2018-09-27 15:13:46 +02:00
butomo1989 2ed92c97e1 Added sample of docker terraform 2018-09-27 15:12:03 +02:00
butomo1989 156fc288c7 Using the latest base image 2018-09-27 09:48:27 +02:00
butomo1989 c790d05e19 Using the needed rules in security group 2018-09-26 17:38:28 +02:00
butomo1989 78b9b79212 Renamed the tag 2018-09-21 13:57:31 +02:00
Budi UtomoandGitHub 57ae8a1f16 Merge pull request #119 from lilinor/contribution
update genymotion readme file
2018-09-17 18:16:28 +02:00
butomo1989 fc90713016 Fixed broken link 2018-09-14 16:19:46 +02:00
butomo1989 948b5cc07b Merge branch 'master' of github.com:butomo1989/docker-android 2018-09-14 15:37:10 +02:00
butomo1989 dfc86227e0 Added instruction to use camera 2018-09-14 15:37:00 +02:00
Budi UtomoandGitHub dfa70768ab Merge pull request #118 from tadashi0713/add-aws-intro
Added AWS instruction
2018-09-14 10:27:26 +02:00
Tadashi NemotoandGitHub a34a7e8339 Add AWS Instruction
Instruction to use EC2 Bare Metal Instance
2018-09-14 12:37:03 +09:00
lilinor e9726a86af update genymotion readme file 2018-09-13 17:46:14 +02:00
butomo1989 4e5370b85b Cleaned up 2018-09-04 12:01:47 +02:00
butomo1989 da177442ce Cleaned up 2018-09-04 10:34:49 +02:00
butomo1989 e2800863e8 Deleted old badge 2018-09-03 12:05:23 +02:00
butomo1989 c4bd3dcf55 Updated version of Selenium Grid in examples 2018-09-03 10:28:58 +02:00
butomo1989 ac594d96e9 Updated base image 2018-09-03 10:04:48 +02:00
butomo1989 a49cc2950e Cleaned up 2018-08-30 13:46:14 +02:00
butomo1989 6b657dd13e Replaced the hard code 2018-08-30 13:36:53 +02:00
butomo1989 aa7a798f62 Connect to Genymotion emulator automatically 2018-08-30 13:35:03 +02:00
butomo1989 ccec2c5969 Using specific version of appium as base image because a release issue with it 2018-08-30 12:05:49 +02:00
butomo1989 e45bc0010f Enabled adb remotely 2018-08-29 13:02:44 +02:00
butomo1989 efd1f07e58 Fixed escape char 2018-08-27 14:32:33 +02:00
butomo1989 73418a8b4f Fixed escape char 2018-08-27 14:30:51 +02:00
Budi UtomoandGitHub ad444fd738 Merge pull request #116 from bonigarcia/master
Fix chromedriver version for Android 5.0.1
2018-08-27 09:48:28 +02:00
Boni Garcia 12391277e6 Fix chromedriver version for Android 5.0.1 2018-08-27 09:31:06 +02:00
Budi UtomoandGitHub c50f185c65 Merge pull request #115 from stazdx/master
Added documentation about Azure
2018-08-27 09:11:18 +02:00
stazdxandGitHub 62090f73b4 Merge pull request #1 from stazdx/azure-docs
Enable nested virtualization on Azure
2018-08-24 17:49:41 -05:00
stazdxandGitHub 7bce737447 Enable nested virtualization on Azure 2018-08-24 17:49:10 -05:00
butomo1989 f2c6ab79bb Enabled key pair 2018-08-24 16:14:04 +02:00
butomo1989 afcbd4a7e7 Merge branch 'master' into release-1.4 2018-08-21 16:45:54 +02:00
Budi UtomoandGitHub 9a714e5fb3 Merge pull request #111 from devilankur18/custom_args
Able to pass custom arguments to Emulator
2018-08-21 16:23:22 +02:00
Ankur Agarwal a6394bcf74 added support for custom arguments while running/creating emulator 2018-08-21 17:50:50 +05:30
butomo1989 43d0bb1292 Merge branch 'release-1.4' of github.com:butomo1989/docker-android into release-1.4 2018-08-21 09:49:41 +02:00
butomo1989 e56352bf74 Added provider id 2018-08-21 09:49:10 +02:00
Budi UtomoandGitHub 7746b0ce1a Merge pull request #112 from red-avtovo/appium_latest
Appium latest image
2018-08-21 08:55:25 +02:00
Aleksandr Bochev 806443e956 switched to base image latest appium 2018-08-20 17:38:53 +02:00
butomo1989 a5d0e6eba2 Always use the latest AMI image 2018-08-20 11:46:09 +02:00
butomo1989 ac9371a2ed Merge branch 'master' into release-1.4 2018-08-20 09:51:35 +02:00
Budi UtomoandGitHub f3abb0a828 Merge pull request #110 from devilankur18/emulator_backup_restore
AVD initialisation based on devices xml file
2018-08-16 18:04:20 +02:00
Ankur Agarwal c653efc7b1 fixes related to initialization 2018-08-16 12:36:51 +00:00
butomo1989 bcd7d9a29b Back to user mode 2018-08-14 09:14:25 +02:00
butomo1989 dd7ef41590 Added integration with Genymotion in AWS 2018-08-11 19:38:47 +02:00
butomo1989 d7c9730712 Fixed issue #90 2018-08-03 15:58:07 +02:00
butomo1989 735bc64a2d Cleaned up 2018-08-03 15:56:36 +02:00
butomo1989 307d6502af Fixed string 2018-08-02 12:52:31 +02:00
butomo1989 91a4e270c6 Refactored code 2018-08-02 11:42:19 +02:00
Budi UtomoandGitHub d13e60a122 Merge pull request #104 from devilankur18/master
Added device_id support via ENV variable or auto uuid values
2018-07-31 09:04:58 +02:00
Ankur AgarwalandGitHub c4be3a1ac0 Merge branch 'master' into master 2018-07-31 01:24:15 +05:30
Ankur AgarwalandGitHub 7c7eed4a3d Fixing trailing whitespaces 2018-07-31 01:17:01 +05:30
Budi UtomoandGitHub d0271e0be0 Merge pull request #103 from mehrdad-abdoli/master
Update Google Play Store app
2018-07-30 17:00:42 +02:00
App-Test 9d71ecded7 Update Google Play Services and some other useful stuff by adb 2018-07-30 16:30:19 +04:30
App-Test 81af88e7a4 Update Google Play Services and some other useful stuff by adb 2018-07-30 16:28:41 +04:30
App-Test a8f7fd2d02 Update Google Play Services and some other useful stuff by adb 2018-07-30 16:26:57 +04:30
App-Test de71e5156c Update Google Play Services and some other useful stuff by adb 2018-07-30 16:19:05 +04:30
Ankur AgarwalandGitHub bcf27f0489 Added logging 2018-07-28 23:20:06 +05:30
Ankur AgarwalandGitHub 972445a8bc Assign device_id via environment variable 2018-07-28 23:07:03 +05:30
App-Test 460e0b8daf Update Google Play Services and some other useful stuff by adb 2018-07-28 16:53:26 +04:30
Budi UtomoandGitHub 3673d195ea Updated Readme 2018-07-25 12:27:09 +02:00
Budi UtomoandGitHub 77c6ac8507 Updated Readme 2018-07-25 12:24:34 +02:00
Budi UtomoandGitHub cd35f4a3ab Merge pull request #100 from bonigarcia/master
Download proper version of chromedriver for each Android version
2018-07-25 12:20:11 +02:00
Boni Garcia 217df7cd65 Include browser name, browser version, and chromedriver version in Docker images table 2018-07-25 11:44:21 +02:00
Boni Garcia ccfdef4fe8 Set default chromedriver version 2018-07-24 17:18:41 +02:00
Boni Garcia b40ec48136 Download proper version of chromedriver 2018-07-24 15:59:11 +02:00
Budi UtomoandGitHub 064331de0e Merge pull request #97 from shadow1163/issue87
Once container start, add flag -wipe-data to command.
2018-07-20 08:01:40 +02:00
Budi UtomoandGitHub 5ef52ca622 Merge branch 'master' into issue87 2018-07-20 07:57:23 +02:00
junbo 15c51a4ab1 roll back is_initialized 2018-07-20 09:53:46 +08:00
Budi UtomoandGitHub 7e2b364c08 Merge pull request #96 from JoeSSS/patch-2
Add information about connecting to adb from outside the container in README
2018-07-19 13:02:04 +02:00
Serghei MoretandGitHub 0b18e4995c Update README.md 2018-07-19 12:41:04 +02:00
Serghei MoretandGitHub f0fb5ef009 Update README.md 2018-07-19 12:39:16 +02:00
Serghei MoretandGitHub ec0c381fb6 Update README.md 2018-07-19 12:38:24 +02:00
Serghei MoretandGitHub 58f7693024 Add adbkey part to README 2018-07-19 12:35:28 +02:00
junbo 40f6e67d83 fix issue 87 2018-07-19 18:11:59 +08:00
Budi UtomoandGitHub 852daa4e32 Merge pull request #92 from red-avtovo/mymaster
Initialise emulator just once
2018-07-10 19:10:49 +02:00
Aleksandr Bochev bf65a73eb1 removed time dependency 2018-07-10 18:45:29 +02:00
Aleksandr Bochev 3577d7e0a1 fixed emulator is unauthorized
performed avd creation just once
2018-07-10 18:34:53 +02:00
Budi UtomoandGitHub 1371744b36 Merge pull request #89 from JoeSSS/patch-1
Fix issue #86
2018-07-09 21:20:51 +02:00
Serghei MoretandGitHub cf3b1cf683 Fix adb getting into the loop 2018-07-09 18:06:58 +02:00
Budi UtomoandGitHub 416a88143f Updated README.md 2018-07-06 10:33:17 +02:00
butomo1989 55719bb638 Use Chrome driver version for Chrome that is inside Emulator 2018-07-05 22:40:41 +02:00
butomo1989 c22fe34e7c Updated README.md 2018-07-05 21:21:24 +02:00
butomo1989 69154410f2 Updated 2018-07-05 21:11:21 +02:00
butomo1989 4975ebcc47 Cleaned up 2018-07-05 21:06:00 +02:00
butomo1989 e4180a6e65 Passed chrome driver version through environment variable 2018-07-05 20:10:47 +02:00
butomo1989 e22b8f141e Removed arm image 2018-07-05 20:04:25 +02:00
butomo1989 7d29525b48 Build version 8.0 and 8.1 2018-07-05 19:56:14 +02:00
butomo1989 f47cc495b0 Merge branch 'release-1.1' of github.com:butomo1989/docker-android into release-1.1 2018-07-05 19:51:46 +02:00
butomo1989 bc516d5a8e Updated permission 2018-07-05 19:11:14 +02:00
Budi UtomoandGitHub b54fcd2087 Merge pull request #72 from greenerchen/patch-2
Build docker images with play store
2018-07-05 17:50:00 +02:00
Greener ChenandGitHub 7e7d12e4e8 Merge branch 'release-1.1' into patch-2 2018-07-05 23:34:22 +08:00
Budi UtomoandGitHub 8d9fc61158 Merge pull request #83 from bonigarcia/master
Use latest version of chromedriver
2018-07-05 17:01:19 +02:00
Budi UtomoandGitHub bc5635ed0a Merge pull request #81 from JoeSSS/JoeSSS-patch-1
Support for Android 8.0 and 8.1
2018-07-05 15:32:59 +02:00
Serghei MoretandGitHub 0b7ca97939 Merge branch 'release-1.1' into JoeSSS-patch-1 2018-07-05 15:28:54 +02:00
Budi UtomoandGitHub 7e0a2e4770 Merge pull request #85 from red-avtovo/sdk_installation_cleanup
cleaned sdk installation
2018-07-05 15:25:35 +02:00
Serghei Moret c82443e221 Update release.sh 2018-07-05 14:29:54 +02:00
Boni Garcia 1d7b7c2ac7 Improve script to download latest version of chromedriver automatically 2018-07-05 12:56:10 +02:00
Aleksandr Bochev 59f792f7c0 cleaned sdk installation 2018-07-05 12:23:13 +02:00
Boni Garcia 84ac59f66a Update chromedriver version to 2.40 2018-07-05 11:41:09 +02:00
Serghei MoretandGitHub d176e69cc1 Let default emulator pick the right kernel 2018-07-03 20:46:23 +02:00
Serghei MoretandGitHub 59f61e057e Update Emulator_x86 2018-07-03 20:44:13 +02:00
butomo1989 601d58c51f Changed apk path 2018-06-28 01:03:27 +02:00
butomo1989 ac33a1f687 Changed apk path 2018-06-28 00:47:49 +02:00
butomo1989 91ebdbf5ab Edited permission 2018-06-28 00:43:26 +02:00
butomo1989 c8fb92e400 Using adb version inside container 2018-06-26 22:53:34 +02:00
butomo1989 80a64e82dd Added demo how to use Genymotion cloud 2018-06-25 23:53:06 +02:00
butomo1989 780278b519 Edited README.md 2018-06-25 22:56:05 +02:00
butomo1989 b4544ae90f Cleaned up Dockerfile 2018-06-25 22:54:01 +02:00
butomo1989 0af1143e72 Deleted genymotion manual installation 2018-06-25 22:48:30 +02:00
Diego MolinaandGitHub 9d0c66fb2b Merge branch 'master' into patch-2 2018-04-09 11:38:33 +02:00
Greener Chen 2b02843cfd Build docker images with play store for emulators with x86 processor and API 24 or later version 2018-03-12 01:41:16 +08:00
353 changed files with 2120 additions and 43466 deletions
+4
View File
@@ -16,7 +16,11 @@ env:
- ANDROID_VERSION=6.0
- ANDROID_VERSION=7.0
- ANDROID_VERSION=7.1.1
- ANDROID_VERSION=8.0
- ANDROID_VERSION=8.1
- ANDROID_VERSION=9.0
- REAL_DEVICE=True
- GENYMOTION=True
script: bash travis.sh
+37
View File
@@ -0,0 +1,37 @@
# Docker-Android's Anonymous Aggregate User Behaviour Analytics
Docker-Android has begun gathering anonymous aggregate user behaviour analytics and reporting these to Google Analytics. You are notified about this when you start Docker-Android.
## Why?
Docker-Android is provided free of charge for our internal and external users and we don't have direct communication with its users nor time resources to ask directly for their feedback. As a result, we now use anonymous aggregate user analytics to help us understand how Docker-Android is being used, the most common used features based on how, where and when people use it. With this information we can prioritize some features over other ones.
## What?
Docker-Android's analytics record some shared information for every event:
- The Google Analytics version i.e. `1` (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#v)
- The Google Analytics anonymous IP setting is enabled i.e. `1` (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#aip)
- The Docker-Android analytics tracking ID e.g. `UA-133466903-1` (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#tid)
- The release version of machine, e.g. `Linux_version_4.4.16-boot2docker_(gcc_version_4.9.2_(Debian_4.9.2-10)_)_#1_SMP_Fri_Jul_29_00:13:24_UTC_2016` This does not allow us to track individual users but does enable us to accurately measure user counts vs. event counts (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#cid)
- Docker-Android analytics hit type, e.g. `event` (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#t)
- Application type, e.g. `Emulator` (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#ec)
- Description will contains information about Emulator configuration, e.g. `Processor type`. (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#el)
- Docker-Android application name, e.g. `docker-android` (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#an)
- Docker-Android application version, e.g. `1.5-p0` (https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#av)
With the recorded information, it is not possible for us to match any particular real user.
As far as we can tell it would be impossible for Google to match the randomly generated analytics user ID to any other Google Analytics user ID. If Google turned evil the only thing they could do would be to lie about anonymising IP addresses and attempt to match users based on IP addresses.
## When/Where?
Docker-Android's analytics are sent throughout Docker-Android's execution to Google Analytics over HTTPS.
## Who?
Docker-Android's analytics are accessible to Docker-Android's current maintainers. Contact [@butomo1989](https://github.com/butomo1989) if you are a maintainer and need access.
## How?
The code is viewable in [this lines](./src/appium.sh#L225-L247).
## Opting out before starting Docker-Android
Docker-Android analytics helps us, maintainers and leaving it on is appreciated. However, if you want to opt out and not send any information, you can do this by using passing environment variable GA=false to the Docker container.
## Disclaimer
This document and the implementation are based on the great idea implemented by [Homebrew](https://github.com/Homebrew/brew/blob/master/docs/Analytics.md)
-13
View File
@@ -1,13 +0,0 @@
Copyright 2016 budi utomo
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.
+36
View File
@@ -0,0 +1,36 @@
## License Information
Copyright 2016 budi utomo
This program is subject to the terms of the Apache License, Version 2.0 AND the following amendments on forks and data processing. Thus, this is a Custom Apache 2.0 License, NOT a dual-license model you may choose from.
You can 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.
## Forks
Additionally to Apache-2.0, when you fork this repo you are required to either remove our Google Analytics tracking ID: UA-133466903-1 or stop usage gathering completely.
## Data processing agreement
By using this software you agree that the following non-PII (non personally identifiable information) data will be collected, processed and used by the maintainers for the purpose of improving the docker-android project. Anonymisation with respect of the IP address means that only the first two octets of the IP address are collected.
By using this software you also grant us a nonexclusive, irrevocable, world-wide, perpetual royalty-free permission to use, modify and publish these data for all purposes, internally or publicly, including the right to sub-license said permission rights.
We collect, process and use the following data:
* Release version of Docker-Android
* Anonymized IP address (only first two octets)
* Country and city
* Date and time when Docker-Android started
* User (it will collect the information about Release Version of Machine)
* Application type, e.g. Emulator or Device or Genymotion
* Emulator configuration, e.g. Processor type, Device name, Appium mode, Selenium grid mode and mobile test mode
## End of License Information
More information about anonymized data collection can be seen [here](Analytics.md)
+1 -1
View File
@@ -1 +1 @@
Budi Utomo <budi.ut.1989@gmail.com>
Budi Utomo <budtmo.os@gmail.com>
+81 -179
View File
@@ -2,24 +2,23 @@
<img id="header" src="./images/logo_dockerandroid_small.png" />
</p>
[![Analytics](https://ga-beacon.appspot.com/UA-133466903-1/github/budtmo/docker-android/README.md)](https://github.com/igrigorik/ga-beacon "Analytics")
[![Join the chat at https://gitter.im/butomo1989/docker-android](https://badges.gitter.im/butomo1989/docker-android.svg)](https://gitter.im/butomo1989/docker-android?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/butomo1989/docker-android.svg?branch=master)](https://travis-ci.org/butomo1989/docker-android)
[![Docker Pulls](https://img.shields.io/docker/pulls/butomo1989/docker-android-x86-7.1.1.svg?style=flat-square&style=plastic)](https://hub.docker.com/r/butomo1989/docker-android-x86-7.1.1/)
[![codecov](https://codecov.io/gh/butomo1989/docker-android/branch/master/graph/badge.svg)](https://codecov.io/gh/butomo1989/docker-android)
[![Build Status](https://travis-ci.org/budtmo/docker-android.svg?branch=master)](https://travis-ci.org/budtmo/docker-android)
[![codecov](https://codecov.io/gh/budtmo/docker-android/branch/master/graph/badge.svg)](https://codecov.io/gh/budtmo/docker-android)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/3f000ffb97db45a59161814e1434c429)](https://www.codacy.com/app/butomo1989/docker-appium?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=butomo1989/docker-appium&amp;utm_campaign=Badge_Grade)
[![GitHub release](https://img.shields.io/github/release/budtmo/docker-android.svg)](https://github.com/budtmo/docker-android/releases)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fbudtmo%2Fdocker-android.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fbudtmo%2Fdocker-android?ref=badge_shield)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
Docker-Android is a docker image built to be used for everything related to mobile website testing and Android project.
<p align="center">
<a href="https://youtu.be/pQdpjuYwvp8"><img src="./images/appiumconf2018.png" alt="Appium Conference 2018" width="600"></a>
</p>
Emulator - Samsung Device | Emulator - Nexus Device | Real Device
:---------------------------:|:---------------------------:|:---------------------------:
![][emulator samsung] |![][emulator nexus] |![][real device]
Purpose
-------
Purposes
--------
1. Run UI tests for mobile websites with [appium]
2. Build Android project and run unit tests with the latest build-tools
@@ -36,25 +35,24 @@ Advantages compare with other docker-android projects
4. Ability to control emulator from outside container by using adb connect
5. Support real devices with screen mirroring
6. Ability to record video during test execution for debugging
7. Open source with more features coming
7. Integrated with other cloud solutions, e.g. [Genymotion Cloud](https://www.genymotion.com/cloud/)
8. Open source with more features coming
List of Docker images
---------------------
|Supported OS |Android version |API level |Image name |Image status |
|:---|:---|:---|:---|:---:|
|Linux|5.0.1|21|butomo1989/docker-android-x86-5.0.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-5.0.1.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-5.0.1 "Get your own image badge on microbadger.com")|
|Linux|5.1.1|22|butomo1989/docker-android-x86-5.1.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-5.1.1.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-5.1.1 "Get your own image badge on microbadger.com")|
|Linux|6.0|23|butomo1989/docker-android-x86-6.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-6.0.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-6.0 "Get your own image badge on microbadger.com")|
|Linux|7.0|24|butomo1989/docker-android-x86-7.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-7.0.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-7.0 "Get your own image badge on microbadger.com")|
|Linux|7.1.1|25|butomo1989/docker-android-x86-7.1.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-x86-7.1.1.svg)](https://microbadger.com/images/butomo1989/docker-android-x86-7.1.1 "Get your own image badge on microbadger.com")|
|OSX / Windows|5.0.1|21|butomo1989/docker-android-arm-5.0.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-5.0.1.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-5.0.1 "Get your own image badge on microbadger.com")|
|OSX / Windows|5.1.1|22|butomo1989/docker-android-arm-5.1.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-5.1.1.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-5.1.1 "Get your own image badge on microbadger.com")|
|OSX / Windows|6.0|23|butomo1989/docker-android-arm-6.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-6.0.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-6.0 "Get your own image badge on microbadger.com")|
|OSX / Windows|7.0|24|butomo1989/docker-android-arm-7.0|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-7.0.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-7.0 "Get your own image badge on microbadger.com")|
|OSX / Windows|7.1.1|25|butomo1989/docker-android-arm-7.1.1|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-arm-7.1.1.svg)](https://microbadger.com/images/butomo1989/docker-android-arm-7.1.1 "Get your own image badge on microbadger.com")|
|All |-|-|butomo1989/docker-android-real-device|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-real-device.svg)](https://microbadger.com/images/butomo1989/docker-android-real-device "Get your own image badge on microbadger.com")|
|Linux|All|All|butomo1989/docker-android-genymotion|[![](https://images.microbadger.com/badges/image/butomo1989/docker-android-genymotion.svg)](https://microbadger.com/images/butomo1989/docker-android-genymotion "Get your own image badge on microbadger.com")|
|OS |Android |API |Browser |Browser version |Chromedriver |Image |Size |
|:---|:---|:---|:---|:---|:---|:---|:---|
|Linux|5.0.1|21|browser|37.0|2.21|budtmo/docker-android-x86-5.0.1|[![](https://images.microbadger.com/badges/image/budtmo/docker-android-x86-5.0.1.svg)](https://microbadger.com/images/budtmo/docker-android-x86-5.0.1 "Get your own image badge on microbadger.com")|
|Linux|5.1.1|22|browser|39.0|2.13|budtmo/docker-android-x86-5.1.1|[![](https://images.microbadger.com/badges/image/budtmo/docker-android-x86-5.1.1.svg)](https://microbadger.com/images/budtmo/docker-android-x86-5.1.1 "Get your own image badge on microbadger.com")|
|Linux|6.0|23|browser|44.0|2.18|budtmo/docker-android-x86-6.0|[![](https://images.microbadger.com/badges/image/budtmo/docker-android-x86-6.0.svg)](https://microbadger.com/images/budtmo/docker-android-x86-6.0 "Get your own image badge on microbadger.com")|
|Linux|7.0|24|chrome|51.0|2.23|budtmo/docker-android-x86-7.0|[![](https://images.microbadger.com/badges/image/budtmo/docker-android-x86-7.0.svg)](https://microbadger.com/images/budtmo/docker-android-x86-7.0 "Get your own image badge on microbadger.com")|
|Linux|7.1.1|25|chrome|55.0|2.28|budtmo/docker-android-x86-7.1.1|[![](https://images.microbadger.com/badges/image/budtmo/docker-android-x86-7.1.1.svg)](https://microbadger.com/images/budtmo/docker-android-x86-7.1.1 "Get your own image badge on microbadger.com")|
|Linux|8.0|26|chrome|58.0|2.31|budtmo/docker-android-x86-8.0|[![](https://images.microbadger.com/badges/image/budtmo/docker-android-x86-8.0.svg)](https://microbadger.com/images/budtmo/docker-android-x86-8.0 "Get your own image badge on microbadger.com")|
|Linux|8.1|27|chrome|61.0|2.33|budtmo/docker-android-x86-8.1|[![](https://images.microbadger.com/badges/image/budtmo/docker-android-x86-8.1.svg)](https://microbadger.com/images/budtmo/docker-android-x86-8.1 "Get your own image badge on microbadger.com")|
|Linux|9.0|28|chrome|66.0|2.40|budtmo/docker-android-x86-9.0|[![](https://images.microbadger.com/badges/image/budtmo/docker-android-x86-9.0.svg)](https://microbadger.com/images/budtmo/docker-android-x86-9.0 "Get your own image badge on microbadger.com")|
|All |-|-|-|-|-|budtmo/docker-android-real-device|[![](https://images.microbadger.com/badges/image/budtmo/docker-android-real-device.svg)](https://microbadger.com/images/budtmo/docker-android-real-device "Get your own image badge on microbadger.com")|
|Linux|All|All|All|All|All|budtmo/docker-android-genymotion|[![](https://images.microbadger.com/badges/image/budtmo/docker-android-genymotion.svg)](https://microbadger.com/images/budtmo/docker-android-genymotion "Get your own image badge on microbadger.com")|
List of Devices
---------------
@@ -76,19 +74,16 @@ Docker is installed in your system.
Quick Start
-----------
1. Run docker-android
1. Run Docker-Android
- For ***Linux OS***, please use image name that contains "x86"
```bash
docker run --privileged -d -p 6080:6080 -p 5554:5554 -p 5555:5555 -e DEVICE="Samsung Galaxy S6" --name android-container butomo1989/docker-android-x86-7.1.1
docker run --privileged -d -p 6080:6080 -p 5554:5554 -p 5555:5555 -e DEVICE="Samsung Galaxy S6" --name android-container budtmo/docker-android-x86-8.1
```
- For ***OSX*** and ***Windows OS***, please use image name that contains "arm"
- For ***OSX*** and ***Windows OS***, please use Virtual Machine that support Virtualization with Ubuntu OS
```bash
docker run --privileged -d -p 6080:6080 -p 5554:5554 -p 5555:5555 -e DEVICE="Samsung Galaxy S6" --name android-container butomo1989/docker-android-arm-7.1.1
```
2. Verify the ip address of docker host.
@@ -102,103 +97,59 @@ Quick Start
3. Open ***http://docker-host-ip-address:6080*** from web browser.
Run Appium Server
-----------------
Custom configurations
---------------------
Appium is automation test framework to test mobile website and mobile application, including android. To be able to use appium, you need to run appium-server. You run appium server inside docker-android container by ***opening port 4723*** and ***passing an environment variable APPIUM=true***.
```bash
docker run --privileged -d -p 6080:6080 -p 5554:5554 -p 5555:5555 -p 4723:4723 -e DEVICE="Samsung Galaxy S6" -e APPIUM=true --name android-container butomo1989/docker-android-x86-7.1.1
```
### Connect to Selenium Grid
It is also possible to connect appium server that run inside docker-android with selenium grid by passing following environment variables:
- CONNECT\_TO\_GRID=true
- APPIUM_HOST="\<host\_ip\_address>"
- APPIUM_PORT=\<port\_number>
- SELENIUM_HOST="\<host\_ip\_address>"
- SELENIUM_PORT=\<port\_number>
To run tests for mobile browser, following parameter can be passed:
- MOBILE\_WEB\_TEST=true
```bash
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -e DEVICE="Samsung Galaxy S6" -e APPIUM=true -e CONNECT_TO_GRID=true -e APPIUM_HOST="127.0.0.1" -e APPIUM_PORT=4723 -e SELENIUM_HOST="172.17.0.1" -e SELENIUM_PORT=4444 -e MOBILE_WEB_TEST=true --name android-container butomo1989/docker-android-x86-7.1.1
```
### Share Volume
If you want to use appium to test UI of your android application, you need to share volume where the APK is located to folder ***/root/tmp***.
```bash
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -v $PWD/example/sample_apk:/root/tmp -e DEVICE="Nexus 5" -e APPIUM=true -e CONNECT_TO_GRID=true -e APPIUM_HOST="127.0.0.1" -e APPIUM_PORT=4723 -e SELENIUM_HOST="172.17.0.1" -e SELENIUM_PORT=4444 --name android-container butomo1989/docker-android-x86-7.1.1
```
### Video Recording
You can deactivate auto_record by changing the value to "False" in docker-compose file. e.g. change value to "False" in this [line].
### Docker-Compose
![][compose]
There is [example of compose file] to run complete selenium grid and docker-android container as nodes. [docker-compose] version [1.13.0] or higher is required to be able to execute that compose file.
```bash
docker-compose up -d
```
[This document](README_CUSTOM_CONFIG.md) contains custom configurations of Docker-Android that you might need, e.g. Proxy, Changing language on fly, etc.
Build Android project
---------------------
docker-android can be used for building Android project and executing its unit test. This following steps will illustrate how to build Android project:
Docker-Android can be used for building Android project and executing its unit test. This following steps will illustrate how to build Android project:
1. Clone [this sample test project](https://github.com/googlesamples/android-testing).
```bash
git clone git@github.com:googlesamples/android-testing.git
```
```bash
git clone git@github.com:googlesamples/android-testing.git
```
2. Build the project
```bash
docker run -it --rm -v $PWD/android-testing/ui/espresso/BasicSample:/root/tmp butomo1989/docker-android-x86-7.1.1 tmp/gradlew build
```bash
docker run -it --rm -v $PWD/android-testing/ui/espresso/BasicSample:/root/tmp budtmo/docker-android-x86-8.1 tmp/gradlew build
```
Control Android connected to host (Emulator or Real Device)
-----------------------------------------------------------
1. Create a docker container with this command
```
$ docker run --privileged -d -p 6080:6080 -p 5554:5554 -p 5555:5555 -p 4723:4723 --name android-container-appium budtmo/docker-android-real-device
```
2. Open noVNC [http://localhost:6080](http://localhost:6080)
Proxy
-----
3. Open terminal by clicking right on **noVNC** window >> **Terminal emulator**
You can enable proxy inside container by passing following environment variables:
4. To connect to host's adb (make sure your host have adb and connected to the device.)
- HTTP_PROXY="\<docker\_bridge\_ip\_address>"
- HTTPS_PROXY="\<docker\_bridge\_ip\_address>"
- NO_PROXY="localhost"
```
$ adb -H host.docker.internal devices
```
To specify port, just add `-P port_number`
Relaxed Security
-----
```
$ adb -H host.docker.internal -P 5037 devices
```
5. Now your container can access your host devices. But, you need to add `remoteAdbHost` and `adbPort` desired capabilities to make **Appium** can recognise those devices.
Pass environment variable RELAXED_SECURITY=true to disable additional security check to use some advanced features.
Genymotion
----------
![Genymotion](images/logo_genymotion.png)
Docker-Android supports [Genymotion Cloud]. What you need is [device.json] and run following command
```bash
export USER="xxx"
export PASS="xxx"
export LICENSE="xxx"
docker run -it --rm -p 4723:4723 -v $PWD/genymotion/example/sample_devices:/root/tmp -e USER=$USER -e PASS=$PASS -e LICENSE=$LICENSE butomo1989/docker-android-genymotion
```
You can also use [this docker-compose file].
Appium and Selenium Grid
------------------------
If you want to use Appium and Selenium Grid, you can follow [this document](README_APPIUM_AND_SELENIUM.md). It also contains sample and use cases.
Control android emulator outside container
------------------------------------------
@@ -249,76 +200,29 @@ SMS Simulation
![][sms]
How to use docker-android in VMWare or Parallels Desktop
---------------
The following instructions are used for OS X. You'll need [docker-machine-parallels](https://github.com/Parallels/docker-machine-parallels) to create a virtual machine (vm) with tiny core linux for running docker images. After that, you may start the vm you created for VMWare Fusion or Parallels Desktop and run a docker container inside this vm. If you're going to use the android docker of emulator with x86 processor, setup this vm for nested virtualization and kvm support before you run a docker container.
Google Play Services and Google Play Store
------------------------------------------
1. Install docker-machine-parallels via Homebrew:
```bash
$ brew install docker-machine-parallels
```
Docker-Android contains Google Play Service (v12.8.74) and Google Play Store (v11.0.50). Both applications are downloaded from [apklinker](https://www.apklinker.com/), so please be aware of it in case you use private/company account to that applications.
2. Create a virtual machine for running docker images based on the virtual machine tool you use
VMWARE
------
2.1. Create a virtual machine of VMWare Fusion
```bash
$ docker-machine create --driver=vmwarefusion vmware-dev
```
This [document](README_VMWARE.md) shows you how to configure Virtual Machine on VMWARE to be able to run Docker-Android.
2.2. Create a virtual machine of Parallels Desktop
```bash
$ docker-machine create --driver=parallels prl-dev
```
This utility `docker-machine-parallels` will fetch boot2docker.iso to create a vm of VMWare fusion or Parallels Desktop. When the vm is created, you'll see it's booted with VMWare fusion or Parallels Desktop where the network of vm is set to NAT and one IP is assigned. You'll be able to connect to vnc service inside the docker image through that IP. Say it's `10.211.55.3` and we'll use it later.
Cloud
-----
3. Setup the virtual machine for nested virtualization support
This [document](README_CLOUD.md) contains information about deploying Docker-Android on cloud services.
3.1. Shutdown the vm by running the command below in the boot2docker vm before you setup it.
```bash
# shutdown -h now
```
Genymotion
----------
If you use VMWare Fusion, go to menu bar > Vitual Machine > Settings > Processors and Memory, expand Advanced options, and select `Enable hypervisor applications in this virtual machine`.
![Enable nested virtualization for VMWare Fusion](images/vmwarefusion_enable_nested_virtualization.png)
If you use Parallels Desktop, open settings screen of that vm and go to `CPU & Memory` under `hardware` tab, expand Advanced settings and select `Enable nested virtualization`.
![Enable nested virtualization for Parallels Desktop](images/parallels_enable_nested_virtualization.png)
<p align="center">
<img id="geny" src="./images/logo_genymotion_and_dockerandroid.png" />
</p>
4. Enable kvm inside virtual machine
4.1. Run as an account other than root to install kvm packages using tce-load.
```bash
# su docker
$ tce-load -wi kvm
```
4.2. Run as root to load kvm module after kvm packages install.
```bash
$ sudo modprobe kvm_intel
```
4.3. Check if the kvm device is loaded.
```bash
$ ls /dev/kvm
```
4.4. Check if your CPU supports hardware virtualization now
```bash
$ egrep -c '(vmx|svm)' /proc/cpuinfo
```
If **0** it means that your CPU doesn't support hardware virtualization.
If **1** or more it does - but you still need to make sure that virtualization is enabled in the BIOS.
5. You may now run a docker container
5.1. Let's run a docker image for an emulator with x86 processor.
```bash
docker run --privileged -d -p 6080:6080 -p 5554:5554 -p 5555:5555 -e DEVICE="Samsung Galaxy S6" --name android-container butomo1989/docker-android-x86-7.1.1
```
When the services inside this docker container are running, connect to http://10.211.55.3:6080/vnc.html (the IP we got when the docker machine was created) and login. The emulator with x86 processor should be running on screen.
For you who do not have ressources to maintain the simulator or to buy machines or need different device profiles, you need to give a try to [Genymotion Cloud](https://www.genymotion.com/cloud/). Docker-Android is integrated with Genymotion on different cloud services, e.g. Genymotion Cloud, AWS, GCP, Alibaba Cloud. Please follow [this document](README_GENYMOTION.md) or [this blog](https://medium.com/genymobile/run-your-appium-tests-using-docker-android-genymotion-cloud-e4817132ccd8) for more detail.
Troubleshooting
---------------
@@ -332,20 +236,18 @@ Special Thanks
--------------
- [Gian Christanto] for creating a great logo!
LICENSE
--------------
See [License](LICENSE.md)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fbudtmo%2Fdocker-android.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fbudtmo%2Fdocker-android?ref=badge_large)
[appium]: <https://appium.io>
[espresso]: <https://google.github.io/android-testing-support-library/docs/espresso/>
[espresso]: <https://developer.android.com/training/testing/espresso/>
[robotium]: <https://github.com/RobotiumTech/robotium>
[emulator samsung]: <images/emulator_samsung_galaxy_s6.png>
[emulator nexus]: <images/emulator_nexus_5.png>
[real device]: <images/real_device.png>
[compose]: <images/compose.png>
[line]: <https://github.com/butomo1989/docker-android/blob/master/docker-compose.yml#L70>
[example of compose file]: <docker-compose.yml>
[docker-compose]: <https://docs.docker.com/compose/install/>
[1.13.0]: <https://github.com/docker/compose/releases/tag/1.13.0>
[Genymotion Cloud]: <https://cloud.geny.io/signin>
[device.json]: <genymotion/example/sample_devices/devices.json>
[this docker-compose file]: <genymotion/example/geny.yml>
[adb_connection]: <images/adb_connection.png>
[sms]: <images/SMS.png>
[gian christanto]: <https://www.linkedin.com/in/gian-christanto-0b398b131/>
+54
View File
@@ -0,0 +1,54 @@
Run Appium Server
-----------------
Appium is automation test framework to test mobile website and mobile application, including Android. To be able to use Appium, you need to run appium-server. You run Appium-Server inside docker-android container by ***opening port 4723*** and ***passing an environment variable APPIUM=true***.
```bash
docker run --privileged -d -p 6080:6080 -p 5554:5554 -p 5555:5555 -p 4723:4723 -e DEVICE="Samsung Galaxy S6" -e APPIUM=true --name android-container budtmo/docker-android-x86-8.1
```
### Share Volume
If you want to use appium to test UI of your android application, you need to share volume where the APK is located to folder ***/root/tmp***.
```bash
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -v $PWD/example/sample_apk:/root/tmp -e DEVICE="Nexus 5" -e APPIUM=true -e CONNECT_TO_GRID=true -e APPIUM_HOST="127.0.0.1" -e APPIUM_PORT=4723 -e SELENIUM_HOST="172.17.0.1" -e SELENIUM_PORT=4444 --name android-container budtmo/docker-android-x86-8.1
```
### Connect to Selenium Grid
It is also possible to connect appium server that run inside docker-android with selenium grid by passing following environment variables:
- CONNECT\_TO\_GRID=true
- APPIUM_HOST="\<host\_ip\_address>"
- APPIUM_PORT=\<port\_number>
- SELENIUM_HOST="\<host\_ip\_address>"
- SELENIUM_PORT=\<port\_number>
To run tests for mobile browser, following parameter can be passed:
- MOBILE\_WEB\_TEST=true
```bash
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -e DEVICE="Samsung Galaxy S6" -e APPIUM=true -e CONNECT_TO_GRID=true -e APPIUM_HOST="127.0.0.1" -e APPIUM_PORT=4723 -e SELENIUM_HOST="172.17.0.1" -e SELENIUM_PORT=4444 -e MOBILE_WEB_TEST=true --name android-container budtmo/docker-android-x86-8.1
```
### Video Recording
You can deactivate auto_record by changing the value to "False" in docker-compose file. e.g. change value to "False" in this [line](docker-compose.yml#L70).
### Relaxed Security
Pass environment variable RELAXED_SECURITY=true to disable additional security check to use some advanced features.
### Docker-Compose
![][compose]
There is [example of compose file](docker-compose.yml) to run complete selenium grid and docker-android container as nodes. [docker-compose](https://docs.docker.com/compose/install/) version [1.13.0](https://github.com/docker/compose/releases/tag/1.13.0) or higher is required to be able to execute that compose file.
```bash
docker-compose up -d
```
[compose]: <images/compose.png>
+25
View File
@@ -0,0 +1,25 @@
Azure
-----
Make sure that the nodes, pods, containers for your emulators are generated within a **VM** of series **Dv3** or **Ev3**.
Reference: https://docs.microsoft.com/en-us/azure/virtual-machines/windows/nested-virtualization
AWS
-----
Make sure that containers for your emulators are generated within a EC2 Bare Metal Instance(i3.metal)
Reference: https://aws.amazon.com/jp/blogs/aws/new-amazon-ec2-bare-metal-instances-with-direct-access-to-hardware/
Google Cloud (GCE)
------------------
Make sure your instances for your emulators have Nested Virtualization enabled
Reference: https://cloud.google.com/compute/docs/instances/enable-nested-virtualization-vm-instances
One the disk and instance are created as [specified here](https://cloud.google.com/compute/docs/instances/enable-nested-virtualization-vm-instances#enablenestedvirt),
the emulator can be brought up as follows:
# Assume app.apk is in /tmp
docker run --privileged -d -e DEVICE="Samsung Galaxy S6" --volume /tmp:/APK \
--name android_em budtmo/docker-android-x86-8.1
docker exec android_em adb wait-for-device
docker exec android_em adb install /APK/app.apk
+46
View File
@@ -0,0 +1,46 @@
Proxy
-----
You can enable proxy inside container by passing following environment variables:
- HTTP_PROXY="\<docker\_bridge\_ip\_address>"
- HTTPS_PROXY="\<docker\_bridge\_ip\_address>"
- NO_PROXY="localhost"
Language
--------
You can change the language setting of Android Emulator on the fly by passing following environment variable:
- LANGUAGE="\<language>"
- COUNTRY="\<country>"
Camera
------
Passing following environment variable to be able to connect laptop / pc camera to Android emulator:
- EMULATOR_ARGS="-camera-back webcam0"
Custom Emulator Arguments
-------------------------
If you want to add more arguments for running emulator, you can ***pass an environment variable EMULATOR_ARGS*** while running docker command.
```bash
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -e DEVICE="Samsung Galaxy S6" -e EMULATOR_ARGS="-no-snapshot-load -partition-size 512" --name android-container budtmo/docker-android-x86-8.1
```
Back & Restore
--------------
If you want to backup/reuse the avds created with furture upgrades or for replication, run the container with two extra mounts
- -v local_backup/.android:/root/.android
- -v local_backup/android_emulator:/root/android_emulator
```bash
docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -v local_backup/.android:/root/.android -v local_backup/android_emulator:local_backup/android_emulator -e DEVICE="Nexus 5" --name android-container budtmo/docker-android-x86-8.1
```
For the first run, this will create a new avd and all the changes will be accessible in the `local_backup` directory. Now for all future runs, it will reuse the avds. Even this should work with new releases of `docker-android`
+26
View File
@@ -0,0 +1,26 @@
Genymotion Cloud
----------------
![Genymotion](images/logo_genymotion.png)
You can easily scale your Appium tests on Genymotion Android virtual devices in the cloud. They are available on SaaS or as virtual images on AWS, GCP or Alibaba Cloud.
1. On SaaS <br />
Use [device.json](genymotion/example/sample_devices/devices.json) to define the device to start. You can specify the port on which the device will start so you don't need to change the device name in your tests every time you need to run those tests. Then run following command
```bash
export USER="xxx"
export PASS="xxx"
export LICENSE="xxx"
docker run -it --rm -p 4723:4723 -v $PWD/genymotion/example/sample_devices:/root/tmp -e TYPE=SaaS -e USER=$USER -e PASS=$PASS -e LICENSE=$LICENSE budtmo/docker-android-genymotion
```
2. On PaaS (AWS) <br />
Use [aws.json](genymotion/example/sample_devices/aws.json) to define configuration of EC2 instance and run following command:
```bash
docker run -it --rm -p 4723:4723 -v $PWD/genymotion/example/sample_devices:/root/tmp -v ~/.aws:/root/.aws -e TYPE=aws budtmo/docker-android-genymotion
```
You can also use [this docker-compose file](genymotion/example/geny.yml).
+71
View File
@@ -0,0 +1,71 @@
VMWare Fusion on OSX
--------------------
The following instructions are used for OS X. You'll need [docker-machine-parallels](https://github.com/Parallels/docker-machine-parallels) to create a virtual machine (vm) with tiny core linux for running docker images. After that, you may start the vm you created for VMWare Fusion or Parallels Desktop and run a docker container inside this vm. If you're going to use the android docker of emulator with x86 processor, setup this vm for nested virtualization and kvm support before you run a docker container.
1. Install docker-machine-parallels via Homebrew:
```bash
$ brew install docker-machine-parallels
```
2. Create a virtual machine for running docker images based on the virtual machine tool you use
2.1. Create a virtual machine of VMWare Fusion
```bash
$ docker-machine create --driver=vmwarefusion vmware-dev
```
2.2. Create a virtual machine of Parallels Desktop
```bash
$ docker-machine create --driver=parallels prl-dev
```
This utility `docker-machine-parallels` will fetch boot2docker.iso to create a vm of VMWare fusion or Parallels Desktop. When the vm is created, you'll see it's booted with VMWare fusion or Parallels Desktop where the network of vm is set to NAT and one IP is assigned. You'll be able to connect to vnc service inside the docker image through that IP. Say it's `10.211.55.3` and we'll use it later.
3. Setup the virtual machine for nested virtualization support
3.1. Shutdown the vm by running the command below in the boot2docker vm before you setup it.
```bash
# shutdown -h now
```
If you use VMWare Fusion, go to menu bar > Vitual Machine > Settings > Processors and Memory, expand Advanced options, and select `Enable hypervisor applications in this virtual machine`.
![Enable nested virtualization for VMWare Fusion](images/vmwarefusion_enable_nested_virtualization.png)
If you use Parallels Desktop, open settings screen of that vm and go to `CPU & Memory` under `hardware` tab, expand Advanced settings and select `Enable nested virtualization`.
![Enable nested virtualization for Parallels Desktop](images/parallels_enable_nested_virtualization.png)
4. Enable kvm inside virtual machine
4.1. Run as an account other than root to install kvm packages using tce-load.
```bash
# su docker
$ tce-load -wi kvm
```
4.2. Run as root to load kvm module after kvm packages install.
```bash
$ sudo modprobe kvm_intel
```
4.3. Check if the kvm device is loaded.
```bash
$ ls /dev/kvm
```
4.4. Check if your CPU supports hardware virtualization now
```bash
$ egrep -c '(vmx|svm)' /proc/cpuinfo
```
If **0** it means that your CPU doesn't support hardware virtualization.
If **1** or more it does - but you still need to make sure that virtualization is enabled in the BIOS.
5. You may now run a docker container
5.1. Let's run a docker image for an emulator with x86 processor.
```bash
docker run --privileged -d -p 6080:6080 -p 5554:5554 -p 5555:5555 -e DEVICE="Samsung Galaxy S6" --name android-container budtmo/docker-android-x86-8.1
```
When the services inside this docker container are running, connect to http://10.211.55.3:6080/vnc.html (the IP we got when the docker machine was created) and login. The emulator with x86 processor should be running on screen.
+86
View File
@@ -0,0 +1,86 @@
# Kubernetes & Azure (AKS, Terraform, Kompose, Kubectl, Azure CLI)
- Azure CLI configuration
- Infrastructure as code for Azure
- Generating Kubernetes configuration files with Kompose (Services, Deployments, Pods & Persistent volumes)
- Terraform with Azure Provider
- Kubectl configuration
## Setting up Azure CLI
- Install Azure CLI -> https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest
- Execute ```sh $ az login ``` and authenticate with your Azure account
- Execute ```sh $ az account show --query "{subscriptionId:id, tenantId:tenantId" ``` . Then copy subscriptionId and tenantId
- Execute ```sh $ az account set --subscription="${SUBSCRIPTION_ID}" ``` . Replace ${SUBSCRIPTION_ID} for your subscriptionId copied
## Create infrastucture in Azure (AKS Service with node master)
Terraform version >= v0.11.7
- Install Terraform -> https://www.terraform.io/downloads.html
- Edit vars with Azure Account values in ```sh terraform.tfvars ```
- After that:
```sh
$ terraform init
$ terraform plan
$ terraform apply
```
## Setting up Kubectl with Azure account
- For apply Kubernetes files:
First configurate azure-cli with Azure account and install kubernetes tools with az:
```sh
$ az aks install-cli
```
Then log in in to the Azure Container Registry (if you're using it, but dockerhub or other):
```sh
$ az acr login
```
After that, connect to cluster with Kubectl:
```sh
$ az aks get-credentials --resource-group docker-android --name k8s-docker-android
```
## Running with custom K8s files (Recommended)
- You can use this approach or Kompose (Next 2 steps)
```sh
$ kubectl create -f volumes.yaml
$ kubectl create -f services_deployments.yaml
```
## Generate Kube files with Kompose
- Install Kompose -> https://github.com/kubernetes/kompose
Kompose version: >= 1.1.0
- For convert to Kompose:
```sh
$ cd kompose
$ kompose convert -f ../kompose.yml
```
## Execute Kube files (Kompose)
- First create Persistent Volume Claims, then Services; finally Deployments files. For example:
```sh
$ cd kompose
$ kubectl create -f nexus-7.1.1-claim0-persistentvolumeclaim.yaml
$ kubectl create -f nexus-7.1.1-claim1-persistentvolumeclaim.yaml
$ kubectl create -f nexus-7.1.1-service.yaml
$ kubectl create -f nexus-7.1.1-deployment.yaml
```
+114
View File
@@ -0,0 +1,114 @@
# Note: It requires docker-compose 1.13.0
#
# Usage: docker-compose up -d
version: "3"
services:
# Selenium hub
selenium_hub:
image: selenium/hub:3.14.0-curium
ports:
- 4444:4444
# There is a bug for using appium. Issue: https://github.com/butomo1989/docker-android/issues/73
# Real devices
#real_device:
# image: butomo1989/docker-android-real-device
# privileged: true
# depends_on:
# - selenium_hub
# ports:
# - 6080:6080
# volumes:
# - ./video-real-device:/tmp/video
# - /dev/bus/usb:/dev/bus/usb
# - ~/.android:/root/.android
# environment:
# - CONNECT_TO_GRID=true
# - APPIUM=true
# - SELENIUM_HOST=selenium_hub
# - AUTO_RECORD=true
# - BROWSER_NAME=chrome
# Using Appium Docker Android
real_device:
image: appium/appium
depends_on:
- selenium_hub
network_mode: "service:selenium_hub"
privileged: true
volumes:
- /dev/bus/usb:/dev/bus/usb
- ~/.android:/root/.android
- ../example/sample_apk:/root/tmp
environment:
- CONNECT_TO_GRID=true
- SELENIUM_HOST=selenium_hub
# Enable it for msite testing
#- BROWSER_NAME=chrome
# Docker-Android for Android application testing
nexus_7.1.1:
image: butomo1989/docker-android-x86-7.1.1
privileged: true
# Increase scale number if needed
#scale: 1
depends_on:
- selenium_hub
- real_device
ports:
- 6080
# Change path of apk that you want to test. I use sample_apk that I provide in folder "example"
volumes:
- ../example/sample_apk:/root/tmp/sample_apk
- ../video-nexus_7.1.1:/tmp/video
environment:
- DEVICE=Nexus 5
- CONNECT_TO_GRID=true
- APPIUM=true
- SELENIUM_HOST=selenium_hub
- AUTO_RECORD=true
# Docker-Android for mobile website testing with chrome browser
# Chrome browser exists only for version 7.0 and 7.1.1
samsung_galaxy_web_7.1.1:
image: butomo1989/docker-android-x86-8.1
privileged: true
# Increase scale number if needed
#scale: 1
depends_on:
- selenium_hub
- real_device
ports:
- 6080
volumes:
- ../video-samsung_7.1.1:/tmp/video
environment:
- DEVICE=Samsung Galaxy S6
- CONNECT_TO_GRID=true
- APPIUM=true
- SELENIUM_HOST=selenium_hub
- MOBILE_WEB_TEST=true
- AUTO_RECORD=true
# Docker-Android for mobile website testing with default browser
# Default browser exists only for version 5.0.1, 5.1.1 and 6.0
samsung_galaxy_web_5.1.1:
image: butomo1989/docker-android-x86-5.1.1
privileged: true
# Increase scale number if needed
#scale: 1
depends_on:
- selenium_hub
- real_device
ports:
- 6080
volumes:
- ../video-samsung_5.1.1:/tmp/video
environment:
- DEVICE=Samsung Galaxy S6
- CONNECT_TO_GRID=true
- APPIUM=true
- SELENIUM_HOST=selenium_hub
- MOBILE_WEB_TEST=true
- AUTO_RECORD=true
@@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: nexus-7.1.1-claim0
name: nexus-7.1.1-claim0
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}
@@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: nexus-7.1.1-claim1
name: nexus-7.1.1-claim1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}
@@ -0,0 +1,53 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f ../kompose.yml
kompose.version: 1.1.0 (36652f6)
creationTimestamp: null
labels:
io.kompose.service: nexus-7.1.1
name: nexus-7.1.1
spec:
replicas: 1
strategy:
type: Recreate
template:
metadata:
creationTimestamp: null
labels:
io.kompose.service: nexus-7.1.1
spec:
containers:
- env:
- name: APPIUM
value: "true"
- name: AUTO_RECORD
value: "true"
- name: CONNECT_TO_GRID
value: "true"
- name: DEVICE
value: Nexus 5
- name: SELENIUM_HOST
value: selenium_hub
image: butomo1989/docker-android-x86-7.1.1
name: nexus-7.1.1
ports:
- containerPort: 6080
resources: {}
securityContext:
privileged: true
volumeMounts:
- mountPath: /root/tmp/sample_apk
name: nexus-7.1.1-claim0
- mountPath: /tmp/video
name: nexus-7.1.1-claim1
restartPolicy: Always
volumes:
- name: nexus-7.1.1-claim0
persistentVolumeClaim:
claimName: nexus-7.1.1-claim0
- name: nexus-7.1.1-claim1
persistentVolumeClaim:
claimName: nexus-7.1.1-claim1
status: {}
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f ../kompose.yml
kompose.version: 1.1.0 (36652f6)
creationTimestamp: null
labels:
io.kompose.service: nexus-7.1.1
name: nexus-7.1.1
spec:
ports:
- name: "6080"
port: 6080
targetPort: 6080
selector:
io.kompose.service: nexus-7.1.1
status:
loadBalancer: {}
@@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: real-device-claim0
name: real-device-claim0
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}
@@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: real-device-claim1
name: real-device-claim1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}
@@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: real-device-claim2
name: real-device-claim2
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}
@@ -0,0 +1,50 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f ../kompose.yml
kompose.version: 1.1.0 (36652f6)
creationTimestamp: null
labels:
io.kompose.service: real-device
name: real-device
spec:
replicas: 1
strategy:
type: Recreate
template:
metadata:
creationTimestamp: null
labels:
io.kompose.service: real-device
spec:
containers:
- env:
- name: CONNECT_TO_GRID
value: "true"
- name: SELENIUM_HOST
value: selenium_hub
image: appium/appium
name: real-device
resources: {}
securityContext:
privileged: true
volumeMounts:
- mountPath: /dev/bus/usb
name: real-device-claim0
- mountPath: /root/.android
name: real-device-claim1
- mountPath: /root/tmp
name: real-device-claim2
restartPolicy: Always
volumes:
- name: real-device-claim0
persistentVolumeClaim:
claimName: real-device-claim0
- name: real-device-claim1
persistentVolumeClaim:
claimName: real-device-claim1
- name: real-device-claim2
persistentVolumeClaim:
claimName: real-device-claim2
status: {}
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f ../kompose.yml
kompose.version: 1.1.0 (36652f6)
creationTimestamp: null
labels:
io.kompose.service: real-device
name: real-device
spec:
clusterIP: None
ports:
- name: headless
port: 55555
targetPort: 0
selector:
io.kompose.service: real-device
status:
loadBalancer: {}
@@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: samsung-galaxy-web-5.1.1-claim0
name: samsung-galaxy-web-5.1.1-claim0
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}
@@ -0,0 +1,50 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f ../kompose.yml
kompose.version: 1.1.0 (36652f6)
creationTimestamp: null
labels:
io.kompose.service: samsung-galaxy-web-5.1.1
name: samsung-galaxy-web-5.1.1
spec:
replicas: 1
strategy:
type: Recreate
template:
metadata:
creationTimestamp: null
labels:
io.kompose.service: samsung-galaxy-web-5.1.1
spec:
containers:
- env:
- name: APPIUM
value: "true"
- name: AUTO_RECORD
value: "true"
- name: CONNECT_TO_GRID
value: "true"
- name: DEVICE
value: Samsung Galaxy S6
- name: MOBILE_WEB_TEST
value: "true"
- name: SELENIUM_HOST
value: selenium_hub
image: butomo1989/docker-android-x86-5.1.1
name: samsung-galaxy-web-5.1.1
ports:
- containerPort: 6080
resources: {}
securityContext:
privileged: true
volumeMounts:
- mountPath: /tmp/video
name: samsung-galaxy-web-5.1.1-claim0
restartPolicy: Always
volumes:
- name: samsung-galaxy-web-5.1.1-claim0
persistentVolumeClaim:
claimName: samsung-galaxy-web-5.1.1-claim0
status: {}
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f ../kompose.yml
kompose.version: 1.1.0 (36652f6)
creationTimestamp: null
labels:
io.kompose.service: samsung-galaxy-web-5.1.1
name: samsung-galaxy-web-5.1.1
spec:
ports:
- name: "6080"
port: 6080
targetPort: 6080
selector:
io.kompose.service: samsung-galaxy-web-5.1.1
status:
loadBalancer: {}
@@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: samsung-galaxy-web-7.1.1-claim0
name: samsung-galaxy-web-7.1.1-claim0
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}
@@ -0,0 +1,50 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f ../kompose.yml
kompose.version: 1.1.0 (36652f6)
creationTimestamp: null
labels:
io.kompose.service: samsung-galaxy-web-7.1.1
name: samsung-galaxy-web-7.1.1
spec:
replicas: 1
strategy:
type: Recreate
template:
metadata:
creationTimestamp: null
labels:
io.kompose.service: samsung-galaxy-web-7.1.1
spec:
containers:
- env:
- name: APPIUM
value: "true"
- name: AUTO_RECORD
value: "true"
- name: CONNECT_TO_GRID
value: "true"
- name: DEVICE
value: Samsung Galaxy S6
- name: MOBILE_WEB_TEST
value: "true"
- name: SELENIUM_HOST
value: selenium_hub
image: butomo1989/docker-android-x86-8.1
name: samsung-galaxy-web-7.1.1
ports:
- containerPort: 6080
resources: {}
securityContext:
privileged: true
volumeMounts:
- mountPath: /tmp/video
name: samsung-galaxy-web-7.1.1-claim0
restartPolicy: Always
volumes:
- name: samsung-galaxy-web-7.1.1-claim0
persistentVolumeClaim:
claimName: samsung-galaxy-web-7.1.1-claim0
status: {}
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f ../kompose.yml
kompose.version: 1.1.0 (36652f6)
creationTimestamp: null
labels:
io.kompose.service: samsung-galaxy-web-7.1.1
name: samsung-galaxy-web-7.1.1
spec:
ports:
- name: "6080"
port: 6080
targetPort: 6080
selector:
io.kompose.service: samsung-galaxy-web-7.1.1
status:
loadBalancer: {}
@@ -0,0 +1,27 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert -f ../kompose.yml
kompose.version: 1.1.0 (36652f6)
creationTimestamp: null
labels:
io.kompose.service: selenium-hub
name: selenium-hub
spec:
replicas: 1
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
io.kompose.service: selenium-hub
spec:
containers:
- image: selenium/hub:3.14.0-curium
name: selenium-hub
ports:
- containerPort: 4444
resources: {}
restartPolicy: Always
status: {}
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert -f ../kompose.yml
kompose.version: 1.1.0 (36652f6)
creationTimestamp: null
labels:
io.kompose.service: selenium-hub
name: selenium-hub
spec:
ports:
- name: "4444"
port: 4444
targetPort: 4444
selector:
io.kompose.service: selenium-hub
status:
loadBalancer: {}
+48
View File
@@ -0,0 +1,48 @@
resource "azurerm_container_service" "container_service" {
name = "k8s-docker-android"
resource_group_name = "${var.resource_group_name}"
location = "${var.resource_group_location}"
orchestration_platform = "Kubernetes"
master_profile {
count = "${var.master_count}"
dns_prefix = "${var.dns_name_prefix}-master"
}
agent_pool_profile {
name = "agentpools"
count = "${var.linux_agent_count}"
dns_prefix = "${var.dns_name_prefix}-agent"
vm_size = "${var.linux_agent_vm_size}"
}
linux_profile {
admin_username = "${var.linux_admin_username}"
ssh_key {
key_data = "${var.linux_admin_ssh_publickey}"
}
}
service_principal {
client_id = "${var.service_principal_client_id}"
client_secret = "${var.service_principal_client_secret}"
}
diagnostics_profile {
enabled = false
}
tags {
Source = "K8s with Terraform"
}
}
output "master_fqdn" {
value = "${azurerm_container_service.container_service.master_profile.fqdn}"
}
output "ssh_command_master0" {
value = "ssh ${var.linux_admin_username}@${azurerm_container_service.container_service.master_profile.fqdn} -A -p 22"
}
+11
View File
@@ -0,0 +1,11 @@
# Use this if you can't specify your credentials in file but you need ingress in the UI console.
provider "azurerm" {}
#Use this if you can specify your credentials and no more configuration is necessary
#provider "azurerm" {
# subscription_id = "${var.subscription_id}"
# client_id = "${var.service_principal_client_id}"
# client_secret = "${var.service_principal_client_secret}"
# tenant_id = "${var.tenant_id}"
#}
+147
View File
@@ -0,0 +1,147 @@
apiVersion: v1
kind: Service
metadata:
name: selenium
spec:
ports:
- name: "4444"
port: 4444
targetPort: 4444
selector:
app: selenium
type: LoadBalancer
---
apiVersion: v1
kind: Deployment
metadata:
name: selenium-deployment
labels:
app: selenium
spec:
replicas: 1
template:
metadata:
labels:
app: selenium
spec:
containers:
- image: selenium/hub:3.14.0-curium
name: selenium-hub
ports:
- containerPort: 4444
resources: {}
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: real-device
spec:
clusterIP: None
ports:
- name: headless
port: 55555
targetPort: 0
selector:
app: real-device
type: LoadBalancer
---
apiVersion: v1
kind: Deployment
metadata:
labels:
app: real-device
name: real-device
spec:
replicas: 1
template:
metadata:
labels:
app: real-device
spec:
containers:
- env:
- name: CONNECT_TO_GRID
value: "true"
- name: SELENIUM_HOST
value: selenium_hub
image: appium/appium
name: real-device
securityContext:
privileged: true
volumeMounts:
- mountPath: /dev/bus/usb
name: real-device-claim0
- mountPath: /root/.android
name: real-device-claim1
- mountPath: /root/tmp
name: real-device-claim2
restartPolicy: Always
volumes:
- name: real-device-claim0
persistentVolumeClaim:
claimName: real-device-claim0
- name: real-device-claim1
persistentVolumeClaim:
claimName: real-device-claim1
- name: real-device-claim2
persistentVolumeClaim:
claimName: real-device-claim2
---
apiVersion: v1
kind: Service
metadata:
name: nexus-7.1.1
spec:
ports:
- name: "6080"
port: 6080
targetPort: 6080
selector:
app: nexus-7.1.1
type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: nexus-7.1.1
name: nexus-7.1.1
spec:
replicas: 1
template:
metadata:
labels:
app: nexus-7.1.1
spec:
containers:
- env:
- name: APPIUM
value: "true"
- name: AUTO_RECORD
value: "true"
- name: CONNECT_TO_GRID
value: "true"
- name: DEVICE
value: Nexus 5
- name: SELENIUM_HOST
value: selenium_hub
image: butomo1989/docker-android-x86-7.1.1
name: nexus-7.1.1
ports:
- containerPort: 6080
securityContext:
privileged: true
volumeMounts:
- mountPath: /root/tmp/sample_apk
name: nexus-7.1.1-claim0
- mountPath: /tmp/video
name: nexus-7.1.1-claim1
restartPolicy: Always
volumes:
- name: nexus-7.1.1-claim0
persistentVolumeClaim:
claimName: nexus-7.1.1-claim0
- name: nexus-7.1.1-claim1
persistentVolumeClaim:
claimName: nexus-7.1.1-claim1
+19
View File
@@ -0,0 +1,19 @@
resource_group_name = "docker-android"
resource_group_location = "West US"
dns_name_prefix = "docker-android"
linux_agent_count = "1"
#Only use Dv3 or Ev3 series
linux_agent_vm_size = "Standard_D2_v3"
linux_admin_username = "(Insert any username here!)"
linux_admin_ssh_publickey = "(Insert ssh key here!)"
master_count = "1"
# Azure credentials
service_principal_client_id = "(Insert principal key client id here!)"
service_principal_client_secret = "(Insert principal key client secret here!)"
subscription_id = "(Insert subscription id here!)"
tenant_id = "(Insert tenant id here!)"
+62
View File
@@ -0,0 +1,62 @@
variable "resource_group_name" {
type = "string"
description = "Name of the azure resource group."
}
variable "resource_group_location" {
type = "string"
description = "Location of the azure resource group."
}
variable "dns_name_prefix" {
type = "string"
description = "Sets the domain name prefix for the cluster. The suffix 'master' will be added to address the master agents and the suffix 'agent' will be added to address the linux agents."
}
variable "linux_agent_count" {
type = "string"
default = "1"
description = "The number of Kubernetes linux agents in the cluster. Allowed values are 1-100 (inclusive). The default value is 1."
}
variable "linux_agent_vm_size" {
type = "string"
default = "Standard_D2_v2"
description = "The size of the virtual machine used for the Kubernetes linux agents in the cluster."
}
variable "linux_admin_username" {
type = "string"
description = "User name for authentication to the Kubernetes linux agent virtual machines in the cluster."
}
variable "linux_admin_ssh_publickey" {
type = "string"
description = "Configure all the linux virtual machines in the cluster with the SSH RSA public key string. The key should include three parts, for example 'ssh-rsa AAAAB...snip...UcyupgH azureuser@linuxvm'"
}
variable "master_count" {
type = "string"
default = "1"
description = "The number of Kubernetes masters for the cluster. Allowed values are 1, 3, and 5. The default value is 1."
}
variable "service_principal_client_id" {
type = "string"
description = "The client id of the azure service principal used by Kubernetes to interact with Azure APIs."
}
variable "service_principal_client_secret" {
type = "string"
description = "The client secret of the azure service principal used by Kubernetes to interact with Azure APIs."
}
variable "subscription_id" {
type = "string"
description = "Your Azure subscription"
}
variable "tenant_id" {
type = "string"
description = "Your Azure Tenant id"
}
+69
View File
@@ -0,0 +1,69 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
app: real-device-claim0
name: real-device-claim0
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
app: real-device-claim1
name: real-device-claim1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
app: real-device-claim2
name: real-device-claim2
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
app: nexus-7.1.1-claim0
name: nexus-7.1.1-claim0
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
app: nexus-7.1.1-claim1
name: nexus-7.1.1-claim1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
+7 -7
View File
@@ -6,14 +6,14 @@ version: "2.2"
services:
# Selenium hub
selenium_hub:
image: selenium/hub:3.12.0-americium
image: selenium/hub:3.14.0-curium
ports:
- 4444:4444
# There is a bug for using appium. Issue: https://github.com/butomo1989/docker-android/issues/73
# There is a bug for using appium. Issue: https://github.com/budtmo/docker-android/issues/73
# Real devices
#real_device:
# image: butomo1989/docker-android-real-device
# image: budtmo/docker-android-real-device
# privileged: true
# depends_on:
# - selenium_hub
@@ -49,7 +49,7 @@ services:
# Docker-Android for Android application testing
nexus_7.1.1:
image: butomo1989/docker-android-x86-7.1.1
image: budtmo/docker-android-x86-7.1.1
privileged: true
# Increase scale number if needed
scale: 1
@@ -60,7 +60,7 @@ services:
- 6080
# Change path of apk that you want to test. I use sample_apk that I provide in folder "example"
volumes:
- $PWD/example/sample_apk:/opt
- $PWD/example/sample_apk:/root/tmp/sample_apk
- ./video-nexus_7.1.1:/tmp/video
environment:
- DEVICE=Nexus 5
@@ -72,7 +72,7 @@ services:
# Docker-Android for mobile website testing with chrome browser
# Chrome browser exists only for version 7.0 and 7.1.1
samsung_galaxy_web_7.1.1:
image: butomo1989/docker-android-x86-7.1.1
image: budtmo/docker-android-x86-8.1
privileged: true
# Increase scale number if needed
scale: 1
@@ -94,7 +94,7 @@ services:
# Docker-Android for mobile website testing with default browser
# Default browser exists only for version 5.0.1, 5.1.1 and 6.0
samsung_galaxy_web_5.1.1:
image: butomo1989/docker-android-x86-5.1.1
image: budtmo/docker-android-x86-5.1.1
privileged: true
# Increase scale number if needed
scale: 1
+44
View File
@@ -0,0 +1,44 @@
provider "docker" {
host = "unix:///var/run/docker.sock"
}
resource "docker_image" "selenium_hub_img" {
name = "selenium/hub:3.14.0-curium"
}
resource "docker_image" "docker_android_img" {
name = "budtmo/docker-android-x86-8.1:latest"
}
resource "docker_network" "private_network" {
name = "private_network"
}
resource "docker_container" "selenium_hub_con" {
image = "${docker_image.selenium_hub_img.latest}"
name = "selenium_hub_con"
networks = ["${docker_network.private_network.id}"]
ports {
internal = 4444
external = 4444
}
}
resource "docker_container" "samsung_s6_con" {
image = "${docker_image.docker_android_img.latest}"
name = "samsung_s6_con"
privileged = true
depends_on = ["docker_container.selenium_hub_con"]
networks = ["${docker_network.private_network.id}"]
ports {
internal = 6080
external = 6080
}
env = [
"DEVICE=Samsung Galaxy S6",
"CONNECT_TO_GRID=true",
"APPIUM=true",
"MOBILE_WEB_TEST=true",
"AUTO_RECORD=true"
]
}
-146
View File
@@ -1,146 +0,0 @@
FROM appium/appium:1.8.1-p2
LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>"
#=============
# Set WORKDIR
#=============
WORKDIR /root
#==================
# General Packages
#------------------
# xterm
# Terminal emulator
# supervisor
# Process manager
# socat
# Port forwarder
#------------------
# NoVNC Packages
#------------------
# x11vnc
# VNC server for X display
# openbox
# Windows manager
# menu
# Debian menu
# python-numpy
# Numpy, For faster performance: https://github.com/novnc/websockify/issues/77
# net-tools
# Netstat
#------------------
# Video Recording
#------------------
# ffmpeg
# Video recorder
# jq
# Sed for JSON data
#==================
RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
xterm \
supervisor \
socat \
x11vnc \
openbox \
menu \
python-numpy \
net-tools \
ffmpeg \
jq \
&& rm -rf /var/lib/apt/lists/*
#=======
# noVNC
# Use same commit id that docker-selenium uses
# https://github.com/elgalu/docker-selenium/blob/236b861177bd2917d864e52291114b1f5e4540d7/Dockerfile#L412-L413
#=======
ENV NOVNC_SHA="b403cb92fb8de82d04f305b4f14fa978003890d7" \
WEBSOCKIFY_SHA="558a6439f14b0d85a31145541745e25c255d576b"
RUN wget -nv -O noVNC.zip "https://github.com/kanaka/noVNC/archive/${NOVNC_SHA}.zip" \
&& unzip -x noVNC.zip \
&& rm noVNC.zip \
&& mv noVNC-${NOVNC_SHA} noVNC \
&& wget -nv -O websockify.zip "https://github.com/kanaka/websockify/archive/${WEBSOCKIFY_SHA}.zip" \
&& unzip -x websockify.zip \
&& mv websockify-${WEBSOCKIFY_SHA} ./noVNC/utils/websockify \
&& rm websockify.zip \
&& ln noVNC/vnc_auto.html noVNC/index.html
#======================
# Install SDK packages
#======================
ARG ANDROID_VERSION=5.0.1
ARG API_LEVEL=21
ARG PROCESSOR=x86
ARG SYS_IMG=x86_64
ARG IMG_TYPE=google_apis
ARG BROWSER=android
ENV ANDROID_VERSION=$ANDROID_VERSION \
API_LEVEL=$API_LEVEL \
PROCESSOR=$PROCESSOR \
SYS_IMG=$SYS_IMG \
IMG_TYPE=$IMG_TYPE \
BROWSER=$BROWSER
ENV PATH ${PATH}:${ANDROID_HOME}/build-tools
RUN echo y | sdkmanager "platforms;android-${API_LEVEL}" && \
echo y | sdkmanager "system-images;android-${API_LEVEL};${IMG_TYPE};${SYS_IMG}" && \
echo y | sdkmanager "emulator"
RUN rm ${ANDROID_HOME}/tools/emulator \
&& ln -s ${ANDROID_HOME}/emulator/emulator64-${PROCESSOR} ${ANDROID_HOME}/tools/emulator
ENV LD_LIBRARY_PATH=$ANDROID_HOME/emulator/lib64:$ANDROID_HOME/emulator/lib64/qt/lib
#==============================================
# Download chrome driver v2.26
# to be able to use chrome browser in emulator
# Issue: https://github.com/butomo1989/docker-android/commit/6406504f944dae73d0a0c5d8e71a17a47dff9b33
#==============================================
RUN wget -nv -O chrome.zip "https://chromedriver.storage.googleapis.com/2.26/chromedriver_linux64.zip" \
&& unzip -x chrome.zip \
&& rm chrome.zip
#================================================
# noVNC Default Configurations
# These Configurations can be changed through -e
#================================================
ENV DISPLAY=:0 \
SCREEN=0 \
SCREEN_WIDTH=1600 \
SCREEN_HEIGHT=900 \
SCREEN_DEPTH=16 \
LOCAL_PORT=5900 \
TARGET_PORT=6080 \
TIMEOUT=1 \
VIDEO_PATH=/tmp/video \
LOG_PATH=/var/log/supervisor
#===============
# Expose Ports
#---------------
# 4723
# Appium port
# 6080
# noVNC port
# 5554
# Emulator port
# 5555
# ADB connection port
#===============
EXPOSE 4723 6080 5554 5555
#======================
# Add Emulator Devices
#======================
COPY devices /root/devices
#===================
# Run docker-appium
#===================
COPY src /root/src
COPY supervisord.conf /root/
RUN chmod -R +x /root/src && chmod +x /root/supervisord.conf
HEALTHCHECK --interval=2s --timeout=40s --retries=1 \
CMD adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done'
CMD /usr/bin/supervisord --configuration supervisord.conf
+29 -15
View File
@@ -1,4 +1,4 @@
FROM appium/appium:1.8.1-p2
FROM appium/appium:1.11.1-p0
LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>"
@@ -86,33 +86,47 @@ RUN wget -nv -O noVNC.zip "https://github.com/kanaka/noVNC/archive/${NOVNC_SHA}
ARG ANDROID_VERSION=5.0.1
ARG API_LEVEL=21
ARG PROCESSOR=x86
ARG SYS_IMG=x86_64
ARG SYS_IMG=x86
ARG IMG_TYPE=google_apis
ARG BROWSER=android
ARG CHROME_DRIVER=2.40
ARG GOOGLE_PLAY_SERVICE=12.8.74
ARG GOOGLE_PLAY_STORE=11.0.50
ARG APP_RELEASE_VERSION=1.5-p0
ENV ANDROID_VERSION=$ANDROID_VERSION \
API_LEVEL=$API_LEVEL \
PROCESSOR=$PROCESSOR \
SYS_IMG=$SYS_IMG \
IMG_TYPE=$IMG_TYPE \
BROWSER=$BROWSER
BROWSER=$BROWSER \
CHROME_DRIVER=$CHROME_DRIVER \
GOOGLE_PLAY_SERVICE=$GOOGLE_PLAY_SERVICE \
GOOGLE_PLAY_STORE=$GOOGLE_PLAY_STORE \
GA=true \
GA_ENDPOINT=https://www.google-analytics.com/collect \
GA_TRACKING_ID=UA-133466903-1 \
GA_API_VERSION="1" \
APP_RELEASE_VERSION=$APP_RELEASE_VERSION \
APP_TYPE=Emulator
ENV PATH ${PATH}:${ANDROID_HOME}/build-tools
RUN echo y | sdkmanager "platforms;android-${API_LEVEL}" && \
echo y | sdkmanager "system-images;android-${API_LEVEL};${IMG_TYPE};${SYS_IMG}" && \
echo y | sdkmanager "emulator"
RUN rm ${ANDROID_HOME}/tools/emulator \
&& ln -s ${ANDROID_HOME}/emulator/emulator64-${PROCESSOR} ${ANDROID_HOME}/tools/emulator
ENV LD_LIBRARY_PATH=$ANDROID_HOME/emulator/lib64:$ANDROID_HOME/emulator/lib64/qt/lib
RUN yes | sdkmanager --licenses && \
sdkmanager "platforms;android-${API_LEVEL}" "system-images;android-${API_LEVEL};${IMG_TYPE};${SYS_IMG}" "emulator"
#==============================================
# Download chrome driver v2.26
# to be able to use chrome browser in emulator
# Issue: https://github.com/butomo1989/docker-android/commit/6406504f944dae73d0a0c5d8e71a17a47dff9b33
# Download proper version of chromedriver
# to be able to use Chrome browser in emulator
#==============================================
RUN wget -nv -O chrome.zip "https://chromedriver.storage.googleapis.com/2.26/chromedriver_linux64.zip" \
RUN wget -nv -O chrome.zip "https://chromedriver.storage.googleapis.com/${CHROME_DRIVER}/chromedriver_linux64.zip" \
&& unzip -x chrome.zip \
&& rm chrome.zip
#================================================================
# Download Google Play Services APK and Play Store from apklinker
#================================================================
Run wget -nv -O google_play_services.apk "https://www.apklinker.com/wp-content/uploads/uploaded_apk/5b5155e5ef4f8/com.google.android.gms_${GOOGLE_PLAY_SERVICE}-020700-204998136_12874013_MinAPI21_(x86)(nodpi)_apklinker.com.apk"
Run wget -nv -O google_play_store.apk "https://www.apklinker.com/wp-content/uploads/uploaded_apk/5b632b1164e31/com.android.vending_${GOOGLE_PLAY_STORE}-all-0-PR-206665793_81105000_MinAPI16_(armeabi,armeabi-v7a,mips,mips64,x86,x86_64)(240,320,480dpi)_apklinker.com.apk"
#================================================
# noVNC Default Configurations
# These Configurations can be changed through -e
@@ -121,7 +135,7 @@ ENV DISPLAY=:0 \
SCREEN=0 \
SCREEN_WIDTH=1600 \
SCREEN_HEIGHT=900 \
SCREEN_DEPTH=16 \
SCREEN_DEPTH=24+32 \
LOCAL_PORT=5900 \
TARGET_PORT=6080 \
TIMEOUT=1 \
@@ -155,6 +169,6 @@ COPY supervisord.conf /root/
RUN chmod -R +x /root/src && chmod +x /root/supervisord.conf
HEALTHCHECK --interval=2s --timeout=40s --retries=1 \
CMD adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done'
CMD timeout 40 adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done'
CMD /usr/bin/supervisord --configuration supervisord.conf
+40 -16
View File
@@ -1,4 +1,4 @@
FROM appium/appium:1.8.1-p2
FROM appium/appium:1.11.1-p0
LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>"
@@ -16,6 +16,13 @@ WORKDIR /root
# Process manager
# socat
# Port forwarder
# keychain
# ssh-key creator
#------------------
# Genymotion spec
#------------------
# bzip2
# File compression
#------------------
# NoVNC Packages
#------------------
@@ -41,6 +48,8 @@ RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
xterm \
supervisor \
socat \
keychain \
bzip2 \
x11vnc \
openbox \
menu \
@@ -71,6 +80,7 @@ RUN wget -nv -O noVNC.zip "https://github.com/kanaka/noVNC/archive/${NOVNC_SHA}
# noVNC Default Configurations
# These Configurations can be changed through -e
#================================================
ARG APP_RELEASE_VERSION=1.5-p0
ENV DISPLAY=:0 \
SCREEN=0 \
SCREEN_WIDTH=1600 \
@@ -80,22 +90,38 @@ ENV DISPLAY=:0 \
TARGET_PORT=6080 \
TIMEOUT=1 \
VIDEO_PATH=/tmp/video \
LOG_PATH=/var/log/supervisor
LOG_PATH=/var/log/supervisor \
GA=true \
GA_ENDPOINT=https://www.google-analytics.com/collect \
GA_TRACKING_ID=UA-133466903-1 \
GA_API_VERSION="1" \
APP_RELEASE_VERSION=$APP_RELEASE_VERSION \
APP_TYPE=Genymotion
#====================
# Install genymotion
#====================
ENV GENYMOTION_VERSION=2.12.1 \
PATH="${PATH}:/root/genymotion"
COPY genymotion/${GENYMOTION_VERSION}/genymotion /root/genymotion
RUN echo | ssh-keygen -q
ARG GENYMOTION_VERSION=2.12.1
ENV GENYMOTION=true \
GENYMOTION_VERSION=$GENYMOTION_VERSION \
PATH="${PATH}:/opt/genymobile/genymotion/" \
APPIUM_LOG=$LOG_PATH/appium.log
RUN wget -nv -O genymotion.bin "https://dl.genymotion.com/releases/genymotion-${GENYMOTION_VERSION}/genymotion-${GENYMOTION_VERSION}-linux_x64.bin" \
&& chmod +x ./genymotion.bin \
&& yes | ./genymotion.bin \
&& rm genymotion.bin
COPY genymotion/generate_config.sh genymotion/geny_start.sh genymotion/enable_adb.sh /root/
#=======================
# Set default variables
#=======================
ENV APPIUM_LOG=$LOG_PATH/appium.log
ENV GENYMOTION=true
COPY genymotion/generate_config.sh /root
RUN chmod +x /root/generate_config.sh
#===================
# Install Terraform
#===================
ARG TERRAFORM_VERSION=0.11.7
ENV TERRAFORM_VERSION=$TERRAFORM_VERSION
RUN wget -nv -O terraform.zip "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip" \
&& unzip -x terraform.zip \
&& rm terraform.zip
#===============
# Expose Ports
@@ -114,8 +140,6 @@ EXPOSE 4723 6080 5555
#=======================
COPY src /root/src
COPY supervisord.conf /root/
RUN chmod -R +x /root/src && chmod +x /root/supervisord.conf
COPY genymotion/geny_start.sh /root
RUN chmod +x /root/geny_start.sh
RUN chmod -R +x /root/src && chmod +x /root/supervisord.conf /root/geny_start.sh
RUN gmtool --cloud config use_custom_sdk=on sdk_path=/root
CMD ["./geny_start.sh"]
+9 -2
View File
@@ -1,4 +1,4 @@
FROM appium/appium:1.8.1-p2
FROM appium/appium:1.11.1-p0
LABEL maintainer "Budi Utomo <budi.ut.1989@gmail.com>"
@@ -71,6 +71,7 @@ RUN wget -nv -O noVNC.zip "https://github.com/kanaka/noVNC/archive/${NOVNC_SHA}
# noVNC Default Configurations
# These Configurations can be changed through -e
#================================================
ARG APP_RELEASE_VERSION=1.5-p0
ENV DISPLAY=:0 \
SCREEN=0 \
SCREEN_WIDTH=1600 \
@@ -80,7 +81,13 @@ ENV DISPLAY=:0 \
TARGET_PORT=6080 \
TIMEOUT=1 \
VIDEO_PATH=/tmp/video \
LOG_PATH=/var/log/supervisor
LOG_PATH=/var/log/supervisor \
GA=true \
GA_ENDPOINT=https://www.google-analytics.com/collect \
GA_TRACKING_ID=UA-133466903-1 \
GA_API_VERSION="1" \
APP_RELEASE_VERSION=$APP_RELEASE_VERSION \
APP_TYPE=Device
#=========================
# Set default variables
@@ -1,478 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype Blend
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-blend
\brief Merges two source items by using a blend mode.
Blend mode can be selected with the \l{Blend::mode}{mode} property.
\table
\header
\li source
\li foregroundSource
\li Effect applied
\row
\li \image Original_bug.png
\li \image Original_butterfly.png
\li \image Blend_bug_and_butterfly.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet Blend-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that is going to be the base when
\l{Blend::foregroundSource}{foregroundSource} is blended over it.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the item that is going to be blended over the
\l{Blend::source}{source}.
\note It is not supported to let the effect include itself, for
instance by setting foregroundSource to the effect's parent.
*/
property variant foregroundSource
/*!
This property defines the mode which is used when foregroundSource is
blended over source. Values are case insensitive.
\table
\header
\li mode
\li description
\row
\li normal
\li The pixel component values from foregroundSource are written
over source by using alpha blending.
\row
\li addition
\li The pixel component values from source and foregroundSource are
added together and written.
\row
\li average
\li The pixel component values from source and foregroundSource are
averaged and written.
\row
\li color
\li The lightness value from source is combined with hue and
saturation from foregroundSource and written.
\row
\li colorBurn
\li The darker pixels from source are darkened more, if both source
and foregroundSource pixels are light the result is light.
\row
\li colorDodge
\li The lighter pixels from source are lightened more, if both
source and foregroundSource pixels are dark the result is dark.
\row
\li darken
\li The darker pixel component value from source and
foregroundSource is written.
\row
\li darkerColor
\li The lower luminance pixel rgb-value from source and
foregroundSource is written.
\row
\li difference
\li The absolute pixel component value difference between source and
foregroundSource is written.
\row
\li divide
\li The pixel component values from source is divided by the value
from foregroundSource and written.
\row
\li exclusion
\li The pixel component value difference with reduced contrast
between source and foregroundSource is written.
\row
\li hardLight
\li The pixel component values from source are lightened or darkened
according to foregroundSource values and written.
\row
\li hue
\li The hue value from foregroundSource is combined with saturation
and lightness from source and written.
\row
\li lighten
\li The lightest pixel component value from source and
foregroundSource is written.
\row
\li lighterColor
\li The higher luminance pixel rgb-value from source and
foregroundSource is written.
\row
\li lightness
\li The lightness value from foregroundSource is combined with hue
and saturation from source and written.
\row
\li multiply
\li The pixel component values from source and foregroundSource are
multiplied together and written.
\row
\li negation
\li The inverted absolute pixel component value difference between
source and foregroundSource is written.
\row
\li saturation
\li The saturation value from foregroundSource is combined with hue
and lightness from source and written.
\row
\li screen
\li The pixel values from source and foregroundSource are negated,
then multiplied, negated again, and written.
\row
\li subtract
\li Pixel value from foregroundSource is subracted from source and
written.
\row
\li softLight
\li The pixel component values from source are lightened or darkened
slightly according to foregroundSource values and written.
\endtable
\table
\header
\li Example source
\li Example foregroundSource
\row
\li \image Original_bug.png
\li \image Original_butterfly.png
\endtable
\table
\header
\li Output examples with different mode values
\li
\li
\row
\li \image Blend_mode1.png
\li \image Blend_mode2.png
\li \image Blend_mode3.png
\row
\li \b { mode: normal }
\li \b { mode: addition }
\li \b { mode: average }
\row
\li \image Blend_mode4.png
\li \image Blend_mode5.png
\li \image Blend_mode6.png
\row
\li \b { mode: color }
\li \b { mode: colorBurn }
\li \b { mode: colorDodge }
\row
\li \image Blend_mode7.png
\li \image Blend_mode8.png
\li \image Blend_mode9.png
\row
\li \b { mode: darken }
\li \b { mode: darkerColor }
\li \b { mode: difference }
\row
\li \image Blend_mode10.png
\li \image Blend_mode11.png
\li \image Blend_mode12.png
\row
\li \b { mode: divide }
\li \b { mode: exclusion }
\li \b { mode: hardlight }
\row
\li \image Blend_mode13.png
\li \image Blend_mode14.png
\li \image Blend_mode15.png
\row
\li \b { mode: hue }
\li \b { mode: lighten }
\li \b { mode: lighterColor }
\row
\li \image Blend_mode16.png
\li \image Blend_mode17.png
\li \image Blend_mode18.png
\row
\li \b { mode: lightness }
\li \b { mode: negation }
\li \b { mode: multiply }
\row
\li \image Blend_mode19.png
\li \image Blend_mode20.png
\li \image Blend_mode21.png
\row
\li \b { mode: saturation }
\li \b { mode: screen }
\li \b { mode: subtract }
\row
\li \image Blend_mode22.png
\row
\li \b { mode: softLight }
\endtable
*/
property string mode: "normal"
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in the
cache must be updated. Memory consumption is increased, because an extra
buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to false.
*/
property bool cached: false
SourceProxy {
id: backgroundSourceProxy
input: rootItem.source
}
SourceProxy {
id: foregroundSourceProxy
input: rootItem.foregroundSource
}
ShaderEffectSource {
id: cacheItem
anchors.fill: parent
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant backgroundSource: backgroundSourceProxy.output
property variant foregroundSource: foregroundSourceProxy.output
property string mode: rootItem.mode
anchors.fill: parent
fragmentShader: fragmentShaderBegin + blendModeNormal + fragmentShaderEnd
function buildFragmentShader() {
var shader = fragmentShaderBegin
switch (mode.toLowerCase()) {
case "addition" : shader += blendModeAddition; break;
case "average" : shader += blendModeAverage; break;
case "color" : shader += blendModeColor; break;
case "colorburn" : shader += blendModeColorBurn; break;
case "colordodge" : shader += blendModeColorDodge; break;
case "darken" : shader += blendModeDarken; break;
case "darkercolor" : shader += blendModeDarkerColor; break;
case "difference" : shader += blendModeDifference; break;
case "divide" : shader += blendModeDivide; break;
case "exclusion" : shader += blendModeExclusion; break;
case "hardlight" : shader += blendModeHardLight; break;
case "hue" : shader += blendModeHue; break;
case "lighten" : shader += blendModeLighten; break;
case "lightercolor" : shader += blendModeLighterColor; break;
case "lightness" : shader += blendModeLightness; break;
case "negation" : shader += blendModeNegation; break;
case "normal" : shader += blendModeNormal; break;
case "multiply" : shader += blendModeMultiply; break;
case "saturation" : shader += blendModeSaturation; break;
case "screen" : shader += blendModeScreen; break;
case "subtract" : shader += blendModeSubtract; break;
case "softlight" : shader += blendModeSoftLight; break;
default: shader += "gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);"; break;
}
shader += fragmentShaderEnd
fragmentShader = shader
// Workaraound for a bug just to make sure display gets updated when the mode changes.
backgroundSourceChanged()
}
Component.onCompleted: {
buildFragmentShader()
}
onModeChanged: {
buildFragmentShader()
}
property string blendModeAddition: "result.rgb = min(rgb1 + rgb2, 1.0);"
property string blendModeAverage: "result.rgb = 0.5 * (rgb1 + rgb2);"
property string blendModeColor: "result.rgb = HSLtoRGB(vec3(RGBtoHSL(rgb2).xy, RGBtoL(rgb1)));"
property string blendModeColorBurn: "result.rgb = clamp(1.0 - ((1.0 - rgb1) / max(vec3(1.0 / 256.0), rgb2)), vec3(0.0), vec3(1.0));"
property string blendModeColorDodge: "result.rgb = clamp(rgb1 / max(vec3(1.0 / 256.0), (1.0 - rgb2)), vec3(0.0), vec3(1.0));"
property string blendModeDarken: "result.rgb = min(rgb1, rgb2);"
property string blendModeDarkerColor: "result.rgb = 0.3 * rgb1.r + 0.59 * rgb1.g + 0.11 * rgb1.b > 0.3 * rgb2.r + 0.59 * rgb2.g + 0.11 * rgb2.b ? rgb2 : rgb1;"
property string blendModeDifference: "result.rgb = abs(rgb1 - rgb2);"
property string blendModeDivide: "result.rgb = clamp(rgb1 / rgb2, 0.0, 1.0);"
property string blendModeExclusion: "result.rgb = rgb1 + rgb2 - 2.0 * rgb1 * rgb2;"
property string blendModeHardLight: "result.rgb = vec3(channelBlendHardLight(rgb1.r, rgb2.r), channelBlendHardLight(rgb1.g, rgb2.g), channelBlendHardLight(rgb1.b, rgb2.b));"
property string blendModeHue: "result.rgb = HSLtoRGB(vec3(RGBtoHSL(rgb2).x, RGBtoHSL(rgb1).yz));"
property string blendModeLighten: "result.rgb = max(rgb1, rgb2);"
property string blendModeLighterColor: "result.rgb = 0.3 * rgb1.r + 0.59 * rgb1.g + 0.11 * rgb1.b > 0.3 * rgb2.r + 0.59 * rgb2.g + 0.11 * rgb2.b ? rgb1 : rgb2;"
property string blendModeLightness: "result.rgb = HSLtoRGB(vec3(RGBtoHSL(rgb1).xy, RGBtoL(rgb2)));"
property string blendModeMultiply: "result.rgb = rgb1 * rgb2;"
property string blendModeNegation: "result.rgb = 1.0 - abs(1.0 - rgb1 - rgb2);"
property string blendModeNormal: "result.rgb = rgb2; a = max(color1.a, color2.a);"
property string blendModeSaturation: "lowp vec3 hsl1 = RGBtoHSL(rgb1); result.rgb = HSLtoRGB(vec3(hsl1.x, RGBtoHSL(rgb2).y, hsl1.z));"
property string blendModeScreen: "result.rgb = 1.0 - (vec3(1.0) - rgb1) * (vec3(1.0) - rgb2);"
property string blendModeSubtract: "result.rgb = max(rgb1 - rgb2, vec3(0.0));"
property string blendModeSoftLight: "result.rgb = rgb1 * ((1.0 - rgb1) * rgb2 + (1.0 - (1.0 - rgb1) * (1.0 - rgb2)));"
property string fragmentShaderBegin: "
varying mediump vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D backgroundSource;
uniform lowp sampler2D foregroundSource;
highp float RGBtoL(highp vec3 color) {
highp float cmin = min(color.r, min(color.g, color.b));
highp float cmax = max(color.r, max(color.g, color.b));
highp float l = (cmin + cmax) / 2.0;
return l;
}
highp vec3 RGBtoHSL(highp vec3 color) {
highp float cmin = min(color.r, min(color.g, color.b));
highp float cmax = max(color.r, max(color.g, color.b));
highp float h = 0.0;
highp float s = 0.0;
highp float l = (cmin + cmax) / 2.0;
highp float diff = cmax - cmin;
if (diff > 1.0 / 256.0) {
if (l < 0.5)
s = diff / (cmin + cmax);
else
s = diff / (2.0 - (cmin + cmax));
if (color.r == cmax)
h = (color.g - color.b) / diff;
else if (color.g == cmax)
h = 2.0 + (color.b - color.r) / diff;
else
h = 4.0 + (color.r - color.g) / diff;
h /= 6.0;
}
return vec3(h, s, l);
}
highp float hueToIntensity(highp float v1, highp float v2, highp float h) {
h = fract(h);
if (h < 1.0 / 6.0)
return v1 + (v2 - v1) * 6.0 * h;
else if (h < 1.0 / 2.0)
return v2;
else if (h < 2.0 / 3.0)
return v1 + (v2 - v1) * 6.0 * (2.0 / 3.0 - h);
return v1;
}
highp vec3 HSLtoRGB(highp vec3 color) {
highp float h = color.x;
highp float l = color.z;
highp float s = color.y;
if (s < 1.0 / 256.0)
return vec3(l, l, l);
highp float v1;
highp float v2;
if (l < 0.5)
v2 = l * (1.0 + s);
else
v2 = (l + s) - (s * l);
v1 = 2.0 * l - v2;
highp float d = 1.0 / 3.0;
highp float r = hueToIntensity(v1, v2, h + d);
highp float g = hueToIntensity(v1, v2, h);
highp float b = hueToIntensity(v1, v2, h - d);
return vec3(r, g, b);
}
lowp float channelBlendHardLight(lowp float c1, lowp float c2) {
return c2 > 0.5 ? (1.0 - (1.0 - 2.0 * (c2 - 0.5)) * (1.0 - c1)) : (2.0 * c1 * c2);
}
void main() {
lowp vec4 result = vec4(0.0);
lowp vec4 color1 = texture2D(backgroundSource, qt_TexCoord0);
lowp vec4 color2 = texture2D(foregroundSource, qt_TexCoord0);
lowp vec3 rgb1 = color1.rgb / max(1.0/256.0, color1.a);
lowp vec3 rgb2 = color2.rgb / max(1.0/256.0, color2.a);
highp float a = max(color1.a, color1.a * color2.a);
"
property string fragmentShaderEnd: "
gl_FragColor.rgb = mix(rgb1, result.rgb, color2.a);
gl_FragColor.rbg *= a;
gl_FragColor.a = a;
gl_FragColor *= qt_Opacity;
}
"
}
}
@@ -1,207 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype BrightnessContrast
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-color
\brief Adjusts brightness and contrast.
This effect adjusts the source item colors.
Brightness adjustment changes the perceived luminance of the source item.
Contrast adjustment increases or decreases the color
and brightness variations.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_bug.png
\li \image BrightnessContrast_bug.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet BrightnessContrast-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that provides the source pixels
for the effect.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines how much the source brightness is increased or
decreased.
The value ranges from -1.0 to 1.0. By default, the property is set to \c
0.0 (no change).
\table
\header
\li Output examples with different brightness values
\li
\li
\row
\li \image BrightnessContrast_brightness1.png
\li \image BrightnessContrast_brightness2.png
\li \image BrightnessContrast_brightness3.png
\row
\li \b { brightness: -0.25 }
\li \b { brightness: 0 }
\li \b { brightness: 0.5 }
\row
\li \l contrast: 0
\li \l contrast: 0
\li \l contrast: 0
\endtable
*/
property real brightness: 0.0
/*!
This property defines how much the source contrast is increased or
decreased. The decrease of the contrast is linear, but the increase is
applied with a non-linear curve to allow very high contrast adjustment at
the high end of the value range.
\table
\header
\li Contrast adjustment curve
\row
\li \image BrightnessContrast_contrast_graph.png
\endtable
The value ranges from -1.0 to 1.0. By default, the property is set to \c 0.0 (no change).
\table
\header
\li Output examples with different contrast values
\li
\li
\row
\li \image BrightnessContrast_contrast1.png
\li \image BrightnessContrast_contrast2.png
\li \image BrightnessContrast_contrast3.png
\row
\li \b { contrast: -0.5 }
\li \b { contrast: 0 }
\li \b { contrast: 0.5 }
\row
\li \l brightness: 0
\li \l brightness: 0
\li \l brightness: 0
\endtable
*/
property real contrast: 0.0
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
ShaderEffectSource {
id: cacheItem
anchors.fill: parent
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant source: sourceProxy.output
property real brightness: rootItem.brightness
property real contrast: rootItem.contrast
anchors.fill: parent
blending: !rootItem.cached
fragmentShader: "
varying mediump vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform highp float brightness;
uniform highp float contrast;
void main() {
highp vec4 pixelColor = texture2D(source, qt_TexCoord0);
pixelColor.rgb /= max(1.0/256.0, pixelColor.a);
highp float c = 1.0 + contrast;
highp float contrastGainFactor = 1.0 + c * c * c * c * step(0.0, contrast);
pixelColor.rgb = ((pixelColor.rgb - 0.5) * (contrastGainFactor * contrast + 1.0)) + 0.5;
pixelColor.rgb = mix(pixelColor.rgb, vec3(step(0.0, brightness)), abs(brightness));
gl_FragColor = vec4(pixelColor.rgb * pixelColor.a, pixelColor.a) * qt_Opacity;
}
"
}
}
@@ -1,155 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype ColorOverlay
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-color
\brief Alters the colors of the source item by applying an overlay color.
The effect is similar to what happens when a colorized glass is put on top
of a grayscale image. The color for the overlay is given in the RGBA format.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_butterfly.png
\li \image ColorOverlay_butterfly.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet ColorOverlay-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that provides the source pixels
for the effect.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the RGBA color value which is used to colorize the
source.
By default, the property is set to \c "transparent".
\table
\header
\li Output examples with different color values
\li
\li
\row
\li \image ColorOverlay_color1.png
\li \image ColorOverlay_color2.png
\li \image ColorOverlay_color3.png
\row
\li \b { color: #80ff0000 }
\li \b { color: #8000ff00 }
\li \b { color: #800000ff }
\endtable
*/
property color color: "transparent"
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
ShaderEffectSource {
id: cacheItem
anchors.fill: parent
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant source: sourceProxy.output
property color color: rootItem.color
anchors.fill: parent
fragmentShader: "
varying mediump vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform highp vec4 color;
void main() {
highp vec4 pixelColor = texture2D(source, qt_TexCoord0);
gl_FragColor = vec4(mix(pixelColor.rgb/max(pixelColor.a, 0.00390625), color.rgb/max(color.a, 0.00390625), color.a) * pixelColor.a, pixelColor.a) * qt_Opacity;
}
"
}
}
@@ -1,294 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype Colorize
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-color
\brief Sets the color in the HSL color space.
The effect is similar to what happens when a colorized glass is put on top
of a grayscale image. Colorize uses the hue, saturation, and lightness (HSL)
color space. You can specify a desired value for each property. You can
shift all HSL values with the
\l{QtGraphicalEffects1::HueSaturation}{HueSaturation} effect.
Alternatively, you can use the
\l{QtGraphicalEffects1::ColorOverlay}{ColorOverlay} effect to colorize the
source item in the RGBA color space.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_bug.png
\li \image Colorize_bug.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet Colorize-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that provides the source pixels
for the effect.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the hue value which is used to colorize the
source.
The value ranges from 0.0 to 1.0. By default, the property is set to \c
0.0, which produces a slightly red color.
\table
\header
\li Allowed hue values
\row
\li \image Colorize_hue_scale.png
\endtable
\table
\header
\li Output examples with different hue values
\li
\li
\row
\li \image Colorize_hue1.png
\li \image Colorize_hue2.png
\li \image Colorize_hue3.png
\row
\li \b { hue: 0.2 }
\li \b { hue: 0.5 }
\li \b { hue: 0.8 }
\row
\li \l saturation: 1
\li \l saturation: 1
\li \l saturation: 1
\row
\li \l lightness: 0
\li \l lightness: 0
\li \l lightness: 0
\endtable
*/
property real hue: 0.0
/*!
This property defines the saturation value which is used to colorize the
source.
The value ranges from 0.0 (desaturated) to 1.0 (saturated). By default,
the property is set to \c 1.0 (saturated).
\table
\header
\li Output examples with different saturation values
\li
\li
\row
\li \image Colorize_saturation1.png
\li \image Colorize_saturation2.png
\li \image Colorize_saturation3.png
\row
\li \b { saturation: 0 }
\li \b { saturation: 0.5 }
\li \b { saturation: 1 }
\row
\li \l hue: 0
\li \l hue: 0
\li \l hue: 0
\row
\li \l lightness: 0
\li \l lightness: 0
\li \l lightness: 0
\endtable
*/
property real saturation: 1.0
/*!
This property defines how much the source lightness value is increased
or decreased.
Unlike hue and saturation properties, lightness does not set the used
value, but it shifts the existing source pixel lightness value.
The value ranges from -1.0 (decreased) to 1.0 (increased). By default,
the property is set to \c 0.0 (no change).
\table
\header
\li Output examples with different lightness values
\li
\li
\row
\li \image Colorize_lightness1.png
\li \image Colorize_lightness2.png
\li \image Colorize_lightness3.png
\row
\li \b { lightness: -0.75 }
\li \b { lightness: 0 }
\li \b { lightness: 0.75 }
\row
\li \l hue: 0
\li \l hue: 0
\li \l hue: 0
\row
\li \l saturation: 1
\li \l saturation: 1
\li \l saturation: 1
\endtable
*/
property real lightness: 0.0
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
ShaderEffectSource {
id: cacheItem
anchors.fill: parent
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant source: sourceProxy.output
property real hue: rootItem.hue
property real saturation: rootItem.saturation
property real lightness: rootItem.lightness
anchors.fill: parent
fragmentShader: "
varying mediump vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform highp float hue;
uniform highp float saturation;
uniform highp float lightness;
highp float RGBtoL(highp vec3 color) {
highp float cmin = min(color.r, min(color.g, color.b));
highp float cmax = max(color.r, max(color.g, color.b));
highp float l = (cmin + cmax) / 2.0;
return l;
}
highp float hueToIntensity(highp float v1, highp float v2, highp float h) {
h = fract(h);
if (h < 1.0 / 6.0)
return v1 + (v2 - v1) * 6.0 * h;
else if (h < 1.0 / 2.0)
return v2;
else if (h < 2.0 / 3.0)
return v1 + (v2 - v1) * 6.0 * (2.0 / 3.0 - h);
return v1;
}
highp vec3 HSLtoRGB(highp vec3 color) {
highp float h = color.x;
highp float l = color.z;
highp float s = color.y;
if (s < 1.0 / 256.0)
return vec3(l, l, l);
highp float v1;
highp float v2;
if (l < 0.5)
v2 = l * (1.0 + s);
else
v2 = (l + s) - (s * l);
v1 = 2.0 * l - v2;
highp float d = 1.0 / 3.0;
highp float r = hueToIntensity(v1, v2, h + d);
highp float g = hueToIntensity(v1, v2, h);
highp float b = hueToIntensity(v1, v2, h - d);
return vec3(r, g, b);
}
void main() {
lowp vec4 sample = texture2D(source, qt_TexCoord0);
sample = vec4(sample.rgb / max(1.0/256.0, sample.a), sample.a);
highp float light = RGBtoL(sample.rgb);
highp float c = step(0.0, lightness);
sample.rgb = HSLtoRGB(vec3(hue, saturation, mix(light, c, abs(lightness))));
gl_FragColor = vec4(sample.rgb * sample.a, sample.a) * qt_Opacity;
}
"
}
}
@@ -1,342 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype ConicalGradient
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-gradient
\brief Draws a conical gradient.
A gradient is defined by two or more colors, which are blended seamlessly.
The colors start from the specified angle and end at 360 degrees larger
angle value.
\table
\header
\li Effect applied
\row
\li \image ConicalGradient.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet ConicalGradient-example.qml example
*/
Item {
id: rootItem
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
/*!
This property defines the starting angle where the color at the gradient
position of 0.0 is rendered. Colors at larger position values are
rendered into larger angle values and blended seamlessly. Angle values
increase clockwise.
\table
\header
\li Output examples with different angle values
\li
\li
\row
\li \image ConicalGradient_angle1.png
\li \image ConicalGradient_angle2.png
\li \image ConicalGradient_angle3.png
\row
\li \b { angle: 0 }
\li \b { angle: 45 }
\li \b { angle: 185 }
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\endtable
*/
property real angle: 0.0
/*!
\qmlproperty real QtGraphicalEffects1::ConicalGradient::horizontalOffset
\qmlproperty real QtGraphicalEffects1::ConicalGradient::verticalOffset
The horizontalOffset and verticalOffset properties define the offset in
pixels for the center point of the gradient compared to the item center.
The value ranges from -inf to inf. By default, the properties are set to \c
0.
\table
\header
\li Output examples with different horizontalOffset values
\li
\li
\row
\li \image ConicalGradient_horizontalOffset1.png
\li \image ConicalGradient_horizontalOffset2.png
\li \image ConicalGradient_horizontalOffset3.png
\row
\li \b { horizontalOffset: -50 }
\li \b { horizontalOffset: 0 }
\li \b { horizontalOffset: 50 }
\row
\li \l angle: 0
\li \l angle: 0
\li \l angle: 0
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\endtable
*/
property real horizontalOffset: 0.0
property real verticalOffset: 0.0
/*!
This property defines the item that is going to be filled with gradient.
Source item gets rendered into an intermediate pixel buffer and the
alpha values from the result are used to determine the gradient's pixels
visibility in the display. The default value for source is undefined and
in that case whole effect area is filled with gradient.
\table
\header
\li Output examples with different source values
\li
\row
\li \image ConicalGradient_maskSource1.png
\li \image ConicalGradient_maskSource2.png
\row
\li \b { source: undefined }
\li \b { source: }
\row
\li \l angle: 0
\li \l angle: 0
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\endtable
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
A gradient is defined by two or more colors, which are blended seamlessly.
The colors are specified as a set of GradientStop child items, each of which
defines a position on the gradient (from 0.0 to 1.0), and a color.
The position of each GradientStop is defined by the position property.
The color is defined by the color property.
\table
\header
\li Output examples with different gradient values
\li
\li
\row
\li \image ConicalGradient_gradient1.png
\li \image ConicalGradient_gradient2.png
\li \image ConicalGradient_gradient3.png
\row
\li \b {gradient:} \code
Gradient {
GradientStop { position: 0.000
color: Qt.rgba(1, 0, 0, 1) }
GradientStop { position: 0.167;
color: Qt.rgba(1, 1, 0, 1) }
GradientStop { position: 0.333;
color: Qt.rgba(0, 1, 0, 1) }
GradientStop { position: 0.500;
color: Qt.rgba(0, 1, 1, 1) }
GradientStop { position: 0.667;
color: Qt.rgba(0, 0, 1, 1) }
GradientStop { position: 0.833;
color: Qt.rgba(1, 0, 1, 1) }
GradientStop { position: 1.000;
color: Qt.rgba(1, 0, 0, 1) }
}
\endcode
\li \b {gradient:} \code
Gradient {
GradientStop { position: 0.0
color: "#F0F0F0"
}
GradientStop { position: 0.5
color: "#000000"
}
GradientStop { position: 1.0
color: "#F0F0F0"
}
}
\endcode
\li \b {gradient:} \code
Gradient {
GradientStop { position: 0.0
color: "#00000000"
}
GradientStop { position: 1.0
color: "#FF000000"
}
}
\endcode
\row
\li \l angle: 0
\li \l angle: 0
\li \l angle: 0
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\endtable
*/
property Gradient gradient: Gradient {
GradientStop { position: 0.0; color: "white" }
GradientStop { position: 1.0; color: "black" }
}
SourceProxy {
id: maskSourceProxy
input: rootItem.source
}
Rectangle {
id: gradientRect
width: 16
height: 256
gradient: rootItem.gradient
smooth: true
}
ShaderEffectSource {
id: cacheItem
anchors.fill: parent
visible: rootItem.cached
smooth: true
rotation: shaderItem.rotation
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant gradientSource: ShaderEffectSource {
sourceItem: gradientRect
smooth: true
hideSource: true
visible: false
}
property variant maskSource: maskSourceProxy.output
property real startAngle: (rootItem.angle - 90) * Math.PI/180
property variant center: Qt.point(0.5 + horizontalOffset / width, 0.5 + verticalOffset / height)
anchors.fill: parent
fragmentShader: maskSource == undefined ? noMaskShader : maskShader
onFragmentShaderChanged: startAngleChanged()
property string noMaskShader: "
varying mediump vec2 qt_TexCoord0;
uniform lowp sampler2D gradientSource;
uniform highp float qt_Opacity;
uniform highp float startAngle;
uniform highp vec2 center;
void main() {
const highp float PI = 3.14159265;
const highp float PIx2inv = 0.1591549;
highp float a = (atan((center.y - qt_TexCoord0.t), (center.x - qt_TexCoord0.s)) + PI - startAngle) * PIx2inv;
gl_FragColor = texture2D(gradientSource, vec2(0.0, fract(a))) * qt_Opacity;
}
"
property string maskShader: "
varying mediump vec2 qt_TexCoord0;
uniform lowp sampler2D gradientSource;
uniform lowp sampler2D maskSource;
uniform highp float qt_Opacity;
uniform highp float startAngle;
uniform highp vec2 center;
void main() {
lowp float maskAlpha = texture2D(maskSource, qt_TexCoord0).a;
const highp float PI = 3.14159265;
const highp float PIx2inv = 0.1591549;
highp float a = (atan((center.y - qt_TexCoord0.t), (center.x - qt_TexCoord0.s)) + PI - startAngle) * PIx2inv;
gl_FragColor = texture2D(gradientSource, vec2(0.0, fract(a))) * maskAlpha * qt_Opacity;
}
"
}
}
@@ -1,155 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype Desaturate
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-color
\brief Reduces the saturation of the colors.
Desaturated pixel values are calculated as averages of the original RGB
component values of the source item.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_bug.png
\li \image Desaturate_bug.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet Desaturate-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that provides the source pixels to
the effect.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines how much the source colors are desaturated.
The value ranges from 0.0 (no change) to 1.0 (desaturated). By default,
the property is set to \c 0.0 (no change).
\table
\header
\li Output examples with different desaturation values
\li
\li
\row
\li \image Desaturate_desaturation1.png
\li \image Desaturate_desaturation2.png
\li \image Desaturate_desaturation3.png
\row
\li \b { desaturation: 0.0 }
\li \b { desaturation: 0.5 }
\li \b { desaturation: 1.0 }
\endtable
*/
property real desaturation: 0.0
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
ShaderEffectSource {
id: cacheItem
anchors.fill: parent
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant source: sourceProxy.output
property real desaturation: rootItem.desaturation
anchors.fill: parent
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform highp float desaturation;
void main(void) {
lowp vec4 textureColor = texture2D(source, qt_TexCoord0.st);
lowp float grayColor = (textureColor.r + textureColor.g + textureColor.b) / 3.0;
gl_FragColor = mix(textureColor, vec4(vec3(grayColor), textureColor.a), desaturation) * qt_Opacity;
}
"
}
}
@@ -1,289 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype DirectionalBlur
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-motion-blur
\brief Applies blur effect to the specified direction.
Effect creates perceived impression that the source item appears to be
moving in the direction of the blur. Blur is applied to both sides of
each pixel, therefore setting the direction to 0 and 180 provides the
same result.
Other available motionblur effects are \l{QtGraphicalEffects1::ZoomBlur}{ZoomBlur} and
\l{QtGraphicalEffects1::RadialBlur}{RadialBlur}.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_bug.png
\li \image DirectionalBlur_bug.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet DirectionalBlur-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that is going to be blurred.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the percieved amount of movement for each pixel.
The movement is divided evenly to both sides of each pixel.
The quality of the blur depends on \l{DirectionalBlur::samples}{samples}
property. If length value is large, more samples are needed to keep the
visual quality at high level.
The value ranges from 0.0 to inf.
By default the property is set to \c 0.0 (no blur).
\table
\header
\li Output examples with different length values
\li
\li
\row
\li \image DirectionalBlur_length1.png
\li \image DirectionalBlur_length2.png
\li \image DirectionalBlur_length3.png
\row
\li \b { length: 0.0 }
\li \b { length: 32.0 }
\li \b { length: 48.0 }
\row
\li \l samples: 24
\li \l samples: 24
\li \l samples: 24
\row
\li \l angle: 0
\li \l angle: 0
\li \l angle: 0
\endtable
*/
property real length: 0.0
/*!
This property defines how many samples are taken per pixel when blur
calculation is done. Larger value produces better quality, but is slower
to render.
This property is not intended to be animated. Changing this property may
cause the underlying OpenGL shaders to be recompiled.
Allowed values are between 0 and inf (practical maximum depends on GPU).
By default the property is set to \c 0 (no samples).
*/
property int samples: 0
/*!
This property defines the direction for the blur. Blur is applied to
both sides of each pixel, therefore setting the direction to 0 and 180
produces the same result.
The value ranges from -180.0 to 180.0.
By default the property is set to \c 0.0.
\table
\header
\li Output examples with different angle values
\li
\li
\row
\li \image DirectionalBlur_angle1.png
\li \image DirectionalBlur_angle2.png
\li \image DirectionalBlur_angle3.png
\row
\li \b { angle: 0.0 }
\li \b { angle: 45.0 }
\li \b { angle: 90.0 }
\row
\li \l samples: 24
\li \l samples: 24
\li \l samples: 24
\row
\li \l length: 32
\li \l length: 32
\li \l length: 32
\endtable
*/
property real angle: 0.0
/*!
This property defines the blur behavior near the edges of the item,
where the pixel blurring is affected by the pixels outside the source
edges.
If the property is set to \c true, the pixels outside the source are
interpreted to be transparent, which is similar to OpenGL
clamp-to-border extension. The blur is expanded slightly outside the
effect item area.
If the property is set to \c false, the pixels outside the source are
interpreted to contain the same color as the pixels at the edge of the
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
not expand outside the effect item area.
By default, the property is set to \c false.
*/
property bool transparentBorder: false
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
}
ShaderEffectSource {
id: cacheItem
anchors.fill: shaderItem
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant source: sourceProxy.output
property real len: rootItem.length
property bool transparentBorder: rootItem.transparentBorder
property real samples: rootItem.samples
property real weight: 1.0 / Math.max(1.0, rootItem.samples)
property variant expandPixels: transparentBorder ? Qt.size(rootItem.samples, rootItem.samples) : Qt.size(0,0)
property variant expand: transparentBorder ? Qt.size(expandPixels.width / width, expandPixels.height / height) : Qt.size(0,0)
property variant delta: Qt.size(1.0 / rootItem.width * Math.cos((rootItem.angle + 90) * Math.PI/180), 1.0 / rootItem.height * Math.sin((rootItem.angle + 90) * Math.PI/180))
x: transparentBorder ? -expandPixels.width - 1: 0
y: transparentBorder ? -expandPixels.height - 1 : 0
width: transparentBorder ? parent.width + 2.0 * expandPixels.width + 2 : parent.width
height: transparentBorder ? parent.height + 2.0 * expandPixels.height + 2 : parent.height
property string fragmentShaderSkeleton: "
varying highp vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform highp float len;
uniform highp float samples;
uniform highp float weight;
uniform highp vec2 expand;
uniform highp vec2 delta;
void main(void) {
highp vec2 shift = delta * len / max(1.0, samples - 1.0);
mediump vec2 texCoord = qt_TexCoord0;
gl_FragColor = vec4(0.0);
PLACEHOLDER_EXPAND_STEPS
texCoord -= shift * max(0.0, samples - 1.0) * 0.5;
PLACEHOLDER_UNROLLED_LOOP
gl_FragColor *= weight * qt_Opacity;
}
"
function buildFragmentShader() {
var shader = fragmentShaderSkeleton
var expandSteps = ""
if (transparentBorder) {
expandSteps += "texCoord = (texCoord - expand) / (1.0 - 2.0 * expand);"
}
var unrolledLoop = "gl_FragColor += texture2D(source, texCoord);\n"
if (rootItem.samples > 1) {
unrolledLoop = ""
for (var i = 0; i < rootItem.samples; i++)
unrolledLoop += "gl_FragColor += texture2D(source, texCoord); texCoord += shift;\n"
}
shader = shader.replace("PLACEHOLDER_EXPAND_STEPS", expandSteps)
fragmentShader = shader.replace("PLACEHOLDER_UNROLLED_LOOP", unrolledLoop)
}
onFragmentShaderChanged: sourceChanged()
onSamplesChanged: buildFragmentShader()
onTransparentBorderChanged: buildFragmentShader()
Component.onCompleted: buildFragmentShader()
}
}
@@ -1,217 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype Displace
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-distortion
\brief Moves the pixels of the source item according to the given
displacement map.
\table
\header
\li Source
\li DisplacementSource
\li Effect applied
\row
\li \image Original_bug.png
\li \image Displace_map.png
\li \image Displace_bug.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet Displace-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item for the pixels that are going to
be displaced according to the data from
\l{Displace::displacementSource}{displacementSource}.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the item that is going to be used as the
displacement map. The displacementSource item gets rendered into the
intermediate pixel buffer. The red and green component values from the
result determine the displacement of the pixels from the source item.
The format for the displacement map is similar to the tangent space
normal maps, which can be created with most 3D-modeling tools. Many
image processing tools include the support for generating normal maps.
Alternatively, the displacement map for this effect can also be a QML
element which is colored appropriately. Like any QML element, it can be
animated. It is recommended that the size of the diplacement map matches
the size of the \l{Displace::source}{source}.
The displace data is interpreted in the RGBA format. For every pixel:
the red channel stores the x-axis displacement, and the green channel
stores the y-axis displacement. Blue and alpha channels are ignored for
this effect.
Assuming that red channel value 1.0 is fully red (0.0 having no red at
all), this effect considers pixel component value 0.5 to cause no
displacement at all. Values above 0.5 shift pixels to the left, values
below 0.5 do the shift to the right. In a similar way, green channel
values above 0.5 displace the pixels upwards, and values below 0.5 shift
the pixels downwards. The actual amount of displacement in pixels
depends on the \l displacement property.
*/
property variant displacementSource
/*!
This property defines the scale for the displacement. The bigger scale,
the bigger the displacement of the pixels. The value set to 0.0 causes
no displacement.
The value ranges from -1.0 (inverted maximum shift, according to
displacementSource) to 1.0 (maximum shift, according to
displacementSource). By default, the property is set to \c 0.0 (no
displacement).
\table
\header
\li Output examples with different displacement values
\li
\li
\row
\li \image Displace_displacement1.png
\li \image Displace_displacement2.png
\li \image Displace_displacement3.png
\row
\li \b { displacement: -0.2 }
\li \b { displacement: 0.0 }
\li \b { displacement: 0.2 }
\endtable
*/
property real displacement: 0.0
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
SourceProxy {
id: displacementSourceProxy
input: rootItem.displacementSource
}
ShaderEffectSource {
id: cacheItem
anchors.fill: parent
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant source: sourceProxy.output
property variant displacementSource: displacementSourceProxy.output
property real displacement: rootItem.displacement
property real xPixel: 1.0/width
property real yPixel: 1.0/height
anchors.fill: parent
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform lowp sampler2D displacementSource;
uniform highp float displacement;
uniform highp float xPixel;
uniform highp float yPixel;
highp float linearstep(highp float e0, highp float e1, highp float x) {
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
}
void main() {
lowp vec4 offset = texture2D(displacementSource, qt_TexCoord0);
offset.xy -= vec2(0.5, 0.5);
offset.xy = offset.xy * step(vec2(1.0/256.0), abs(offset.xy));
highp vec2 tx = qt_TexCoord0 + (vec2(-offset.x, offset.y) * displacement);
lowp float e1 = linearstep(0.0, xPixel, tx.x);
lowp float e2 = linearstep(0.0, yPixel, tx.y);
lowp float e3 = 1.0 - linearstep(1.0, 1.0 + xPixel, tx.x);
lowp float e4 = 1.0 - linearstep(1.0, 1.0 + yPixel, tx.y);
lowp vec4 sample = texture2D(source, tx);
sample.rgb *= e1 * e2 * e3 * e4;
gl_FragColor = sample * qt_Opacity * offset.a;
}
"
}
}
@@ -1,419 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype DropShadow
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-drop-shadow
\brief Generates a colorized and blurred shadow image of the
source and places it behind the original, giving the impression that
source item is raised from the background.
By default the effect produces a high quality shadow image, thus the
rendering speed of the shadow might not be the highest possible. The
rendering speed is reduced especially if the shadow edges are heavily
softened.
For use cases that require faster rendering speed and for which the highest
possible visual quality is not necessary, the
\l{DropShadow::fast}{fast} property can be set to \c true.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_butterfly.png
\li \image DropShadow_butterfly.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet DropShadow-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that is going to be used as the
source for the generated shadow.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
Radius defines the softness of the shadow. A larger radius causes the
edges of the shadow to appear more blurry.
Depending on the radius value, value of the
\l{DropShadow::samples}{samples} should be set to sufficiently large to
ensure the visual quality.
The value ranges from 0.0 (no blur) to inf. By default, the property is
set to \c 0.0 (no blur).
\table
\header
\li Output examples with different radius values
\li
\li
\row
\li \image DropShadow_radius1.png
\li \image DropShadow_radius2.png
\li \image DropShadow_radius3.png
\row
\li \b { radius: 0 }
\li \b { radius: 6 }
\li \b { radius: 12 }
\row
\li \l samples: 24
\li \l samples: 24
\li \l samples: 24
\row
\li \l color: #000000
\li \l color: #000000
\li \l color: #000000
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 20
\li \l verticalOffset: 20
\li \l verticalOffset: 20
\row
\li \l spread: 0
\li \l spread: 0
\li \l spread: 0
\endtable
*/
property real radius: 0.0
/*!
This property defines how many samples are taken per pixel when edge
softening blur calculation is done. Larger value produces better
quality, but is slower to render.
Ideally, this value should be twice as large as the highest required
radius value, for example, if the radius is animated between 0.0 and
4.0, samples should be set to 8.
The value ranges from 0 to 32. By default, the property is set to \c 0.
This property is not intended to be animated. Changing this property may
cause the underlying OpenGL shaders to be recompiled.
When \l{DropShadow::fast}{fast} property is set to true, this property
has no effect.
*/
property int samples: 0
/*!
This property defines the RGBA color value which is used for the shadow.
By default, the property is set to \c "black".
\table
\header
\li Output examples with different color values
\li
\li
\row
\li \image DropShadow_color1.png
\li \image DropShadow_color2.png
\li \image DropShadow_color3.png
\row
\li \b { color: #000000 }
\li \b { color: #0000ff }
\li \b { color: #aa000000 }
\row
\li \l radius: 8
\li \l radius: 8
\li \l radius: 8
\row
\li \l samples: 16
\li \l samples: 16
\li \l samples: 16
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 20
\li \l verticalOffset: 20
\li \l verticalOffset: 20
\row
\li \l spread: 0
\li \l spread: 0
\li \l spread: 0
\endtable
*/
property color color: "black"
/*!
\qmlproperty real QtGraphicalEffects1::DropShadow::horizontalOffset
\qmlproperty real QtGraphicalEffects1::DropShadow::verticalOffset
HorizontalOffset and verticalOffset properties define the offset for the
rendered shadow compared to the DropShadow item position. Often, the
DropShadow item is anchored so that it fills the source element. In this
case, if the HorizontalOffset and verticalOffset properties are set to
0, the shadow is rendered exactly under the source item. By changing the
offset properties, the shadow can be positioned relatively to the source
item.
The values range from -inf to inf. By default, the properties are set to
\c 0.
\table
\header
\li Output examples with different horizontalOffset values
\li
\li
\row
\li \image DropShadow_horizontalOffset1.png
\li \image DropShadow_horizontalOffset2.png
\li \image DropShadow_horizontalOffset3.png
\row
\li \b { horizontalOffset: -20 }
\li \b { horizontalOffset: 0 }
\li \b { horizontalOffset: 20 }
\row
\li \l radius: 4
\li \l radius: 4
\li \l radius: 4
\row
\li \l samples: 8
\li \l samples: 8
\li \l samples: 8
\row
\li \l color: #000000
\li \l color: #000000
\li \l color: #000000
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\row
\li \l spread: 0
\li \l spread: 0
\li \l spread: 0
\endtable
*/
property real horizontalOffset: 0.0
property real verticalOffset: 0.0
/*!
This property defines how large part of the shadow color is strenghtened
near the source edges.
The value ranges from 0.0 to 1.0. By default, the property is set to \c
0.5.
\table
\header
\li Output examples with different spread values
\li
\li
\row
\li \image DropShadow_spread1.png
\li \image DropShadow_spread2.png
\li \image DropShadow_spread3.png
\row
\li \b { spread: 0.0 }
\li \b { spread: 0.5 }
\li \b { spread: 1.0 }
\row
\li \l radius: 8
\li \l radius: 8
\li \l radius: 8
\row
\li \l samples: 16
\li \l samples: 16
\li \l samples: 16
\row
\li \l color: #000000
\li \l color: #000000
\li \l color: #000000
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 20
\li \l verticalOffset: 20
\li \l verticalOffset: 20
\endtable
*/
property real spread: 0.0
/*!
This property selects the blurring algorithm that is used to produce the
softness for the effect. Setting this to true enables fast algorithm,
setting value to false produces higher quality result.
By default, the property is set to \c false.
\table
\header
\li Output examples with different fast values
\li
\li
\row
\li \image DropShadow_fast1.png
\li \image DropShadow_fast2.png
\row
\li \b { fast: false }
\li \b { fast: true }
\row
\li \l radius: 16
\li \l radius: 16
\row
\li \l samples: 24
\li \l samples: 24
\row
\li \l color: #000000
\li \l color: #000000
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 20
\li \l verticalOffset: 20
\row
\li \l spread: 0
\li \l spread: 0
\endtable
*/
property bool fast: false
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance. Every time the source or effect
properties are changed, the pixels in the cache must be updated. Memory
consumption is increased, because an extra buffer of memory is required
for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
/*!
This property determines whether or not the effect has a transparent
border.
When set to \c true, the exterior of the item is padded with a 1 pixel
wide transparent edge, making sampling outside the source texture use
transparency instead of the edge pixels. Without this property, an
image which has opaque edges will not get a blurred edge.
In the image below, the Rectangle on the left has transparent borders
and has blurred edges, whereas the Rectangle on the right does not:
\snippet DropShadow-transparentBorder-example.qml example
\image transparentBorder.png
*/
property bool transparentBorder: false
Loader {
x: rootItem.horizontalOffset
y: rootItem.verticalOffset
width: parent.width
height: parent.height
sourceComponent: rootItem.fast ? fastGlow : gaussianGlow
}
Component {
id: gaussianGlow
GaussianGlow {
anchors.fill: parent
source: sourceProxy.output
radius: rootItem.radius
maximumRadius: rootItem.samples * 0.5
color: rootItem.color
cached: rootItem.cached
spread: rootItem.spread
transparentBorder: rootItem.transparentBorder
}
}
Component {
id: fastGlow
FastGlow {
anchors.fill: parent
source: sourceProxy.output
blur: Math.pow(rootItem.radius / 64.0, 0.4)
color: rootItem.color
cached: rootItem.cached
spread: rootItem.spread
transparentBorder: rootItem.transparentBorder
}
}
SourceProxy {
id: sourceProxy
input: rootItem.source
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
}
ShaderEffect {
anchors.fill: parent
property variant source: sourceProxy.output
}
}
@@ -1,496 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype FastBlur
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-blur
\brief Applies a fast blur effect to one or more source items.
FastBlur offers lower blur quality than
\l{QtGraphicalEffects1::GaussianBlur}{GaussianBlur}, but it is faster to
render. The FastBlur effect softens the source content by blurring it with
algorithm which uses the source content downscaling and bilinear filtering.
Use this effect in situations where the source content is rapidly changing
and the highest possible blur quality is not
needed.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_bug.png
\li \image FastBlur_bug.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet FastBlur-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that is going to be blurred.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the distance of the neighboring pixels which affect
the blurring of an individual pixel. A larger radius increases the blur
effect. FastBlur algorithm may internally reduce the accuracy of the radius in order to
provide good rendering performance.
The value ranges from 0.0 (no blur) to inf. Visual quality of the blur is reduced when
radius exceeds value 64. By default, the property is set to \c 0.0 (no blur).
\table
\header
\li Output examples with different blur values
\li
\li
\row
\li \image FastBlur_radius1.png
\li \image FastBlur_radius2.png
\li \image FastBlur_radius3.png
\row
\li \b { radius: 0 }
\li \b { radius: 32 }
\li \b { radius: 64 }
\endtable
*/
property real radius: 0.0
/*!
This property defines the blur behavior near the edges of the item,
where the pixel blurring is affected by the pixels outside the source
edges.
If the property is set to \c true, the pixels outside the source are
interpreted to be transparent, which is similar to OpenGL
clamp-to-border extension. The blur is expanded slightly outside the
effect item area.
If the property is set to \c false, the pixels outside the source are
interpreted to contain the same color as the pixels at the edge of the
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
not expand outside the effect item area.
By default, the property is set to \c false.
\table
\header
\li Output examples with different transparentBorder values
\li
\li
\row
\li \image FastBlur_transparentBorder1.png
\li \image FastBlur_transparentBorder2.png
\row
\li \b { transparentBorder: false }
\li \b { transparentBorder: true }
\row
\li \l radius: 64
\li \l radius: 64
\endtable
*/
property bool transparentBorder: false
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
ShaderEffectSource {
id: cacheItem
anchors.fill: shaderItem
visible: rootItem.cached
sourceItem: shaderItem
live: true
hideSource: visible
smooth: rootItem.radius > 0
}
/*! \internal */
property string __internalBlurVertexShader: "
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
uniform highp mat4 qt_Matrix;
uniform highp float yStep;
uniform highp float xStep;
varying highp vec2 qt_TexCoord0;
varying highp vec2 qt_TexCoord1;
varying highp vec2 qt_TexCoord2;
varying highp vec2 qt_TexCoord3;
void main() {
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
gl_Position = qt_Matrix * qt_Vertex;
}
"
/*! \internal */
property string __internalBlurFragmentShader: "
uniform lowp sampler2D source;
uniform lowp float qt_Opacity;
varying highp vec2 qt_TexCoord0;
varying highp vec2 qt_TexCoord1;
varying highp vec2 qt_TexCoord2;
varying highp vec2 qt_TexCoord3;
void main() {
highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) +
texture2D(source, qt_TexCoord1) +
texture2D(source, qt_TexCoord2) +
texture2D(source, qt_TexCoord3)) * 0.25;
gl_FragColor = sourceColor * qt_Opacity;
}
"
ShaderEffect {
id: level0
property variant source: sourceProxy.output
anchors.fill: parent
visible: false
smooth: true
}
ShaderEffectSource {
id: level1
width: Math.ceil(shaderItem.width / 32) * 32
height: Math.ceil(shaderItem.height / 32) * 32
sourceItem: level0
hideSource: rootItem.visible
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0, 0, 0, 0)
visible: false
smooth: rootItem.radius > 0
}
ShaderEffect {
id: effect1
property variant source: level1
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level2
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level2
width: level1.width / 2
height: level1.height / 2
sourceItem: effect1
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect2
property variant source: level2
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level3
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level3
width: level2.width / 2
height: level2.height / 2
sourceItem: effect2
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect3
property variant source: level3
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level4
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level4
width: level3.width / 2
height: level3.height / 2
sourceItem: effect3
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect4
property variant source: level4
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level5
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level5
width: level4.width / 2
height: level4.height / 2
sourceItem: effect4
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect5
property variant source: level5
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level6
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level6
width: level5.width / 2
height: level5.height / 2
sourceItem: effect5
hideSource: rootItem.visible
visible: false
smooth: true
}
Item {
id: dummysource
width: 1
height: 1
visible: false
}
ShaderEffectSource {
id: dummy
width: 1
height: 1
sourceItem: dummysource
visible: false
smooth: false
live: false
}
ShaderEffect {
id: shaderItem
property variant source1: level1
property variant source2: level2
property variant source3: level3
property variant source4: level4
property variant source5: level5
property variant source6: level6
property real lod: Math.sqrt(rootItem.radius / 64.0) * 1.2 - 0.2
property real weight1
property real weight2
property real weight3
property real weight4
property real weight5
property real weight6
x: transparentBorder ? -64 : 0
y: transparentBorder ? -64 : 0
width: transparentBorder ? parent.width + 128 : parent.width
height: transparentBorder ? parent.height + 128 : parent.height
function weight(v) {
if (v <= 0.0)
return 1.0
if (v >= 0.5)
return 0.0
return 1.0 - v * 2.0
}
function calculateWeights() {
var w1 = weight(Math.abs(lod - 0.100))
var w2 = weight(Math.abs(lod - 0.300))
var w3 = weight(Math.abs(lod - 0.500))
var w4 = weight(Math.abs(lod - 0.700))
var w5 = weight(Math.abs(lod - 0.900))
var w6 = weight(Math.abs(lod - 1.100))
var sum = w1 + w2 + w3 + w4 + w5 + w6;
weight1 = w1 / sum;
weight2 = w2 / sum;
weight3 = w3 / sum;
weight4 = w4 / sum;
weight5 = w5 / sum;
weight6 = w6 / sum;
upateSources()
}
function upateSources() {
var sources = new Array();
var weights = new Array();
if (weight1 > 0) {
sources.push(level1)
weights.push(weight1)
}
if (weight2 > 0) {
sources.push(level2)
weights.push(weight2)
}
if (weight3 > 0) {
sources.push(level3)
weights.push(weight3)
}
if (weight4 > 0) {
sources.push(level4)
weights.push(weight4)
}
if (weight5 > 0) {
sources.push(level5)
weights.push(weight5)
}
if (weight6 > 0) {
sources.push(level6)
weights.push(weight6)
}
for (var j = sources.length; j < 6; j++) {
sources.push(dummy)
weights.push(0.0)
}
source1 = sources[0]
source2 = sources[1]
source3 = sources[2]
source4 = sources[3]
source5 = sources[4]
source6 = sources[5]
weight1 = weights[0]
weight2 = weights[1]
weight3 = weights[2]
weight4 = weights[3]
weight5 = weights[4]
weight6 = weights[5]
}
Component.onCompleted: calculateWeights()
onLodChanged: calculateWeights()
fragmentShader: "
uniform lowp sampler2D source1;
uniform lowp sampler2D source2;
uniform lowp sampler2D source3;
uniform lowp sampler2D source4;
uniform lowp sampler2D source5;
uniform mediump float weight1;
uniform mediump float weight2;
uniform mediump float weight3;
uniform mediump float weight4;
uniform mediump float weight5;
uniform lowp float qt_Opacity;
varying mediump vec2 qt_TexCoord0;
void main() {
lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1;
sourceColor += texture2D(source2, qt_TexCoord0) * weight2;
sourceColor += texture2D(source3, qt_TexCoord0) * weight3;
sourceColor += texture2D(source4, qt_TexCoord0) * weight4;
sourceColor += texture2D(source5, qt_TexCoord0) * weight5;
gl_FragColor = sourceColor * qt_Opacity;
}
"
}
}
@@ -1,193 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype GammaAdjust
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-color
\brief Alters the luminance of the source item.
GammaAdjust is applied to each pixel according to the curve which is
pre-defined as a power-law expression, where the property gamma is used as the
reciprocal scaling exponent. Refer to the property documentation of \l{GammaAdjust::gamma}{gamma}
for more details.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_bug.png
\li \image GammaAdjust_bug.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet GammaAdjust-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item for which the luminance is going to be
adjusted.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the change factor for how the luminance of each pixel
is altered according to the equation:
\code
luminance = pow(original_luminance, 1.0 / gamma); // The luminance is assumed to be between 0.0 and 1.0
\endcode
Setting the gamma values under 1.0 makes the image darker, the values
above 1.0 lighten it.
The value ranges from 0.0 (darkest) to inf (lightest). By default, the
property is set to \c 1.0 (no change).
\table
\header
\li Output examples with different gamma values
\li
\li
\row
\li \image GammaAdjust_gamma1.png
\li \image GammaAdjust_gamma2.png
\li \image GammaAdjust_gamma3.png
\row
\li \b { gamma: 0.5 }
\li \b { gamma: 1.0 }
\li \b { gamma: 2.0 }
\endtable
\table
\header
\li Pixel luminance curves of the above images.
\li
\li
\row
\li \image GammaAdjust_gamma1_graph.png
\li \image GammaAdjust_gamma2_graph.png
\li \image GammaAdjust_gamma3_graph.png
\row
\li Red curve: default gamma (1.0)
\li
\li
\row
\li Yellow curve: effect applied
\li
\li
\row
\li X-axis: pixel original luminance
\li
\li
\row
\li Y-axis: pixel luminance with effect applied
\li
\li
\endtable
*/
property real gamma: 1.0
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
ShaderEffectSource {
id: cacheItem
anchors.fill: parent
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant source: sourceProxy.output
property real gamma: 1.0 / Math.max(rootItem.gamma, 0.0001)
anchors.fill: parent
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform highp float gamma;
void main(void) {
highp vec4 originalColor = texture2D(source, qt_TexCoord0.st);
originalColor.rgb = originalColor.rgb / max(1.0/256.0, originalColor.a);
highp vec3 adjustedColor = pow(originalColor.rgb, vec3(gamma));
gl_FragColor = vec4(adjustedColor * originalColor.a, originalColor.a) * qt_Opacity;
}
"
}
}
@@ -1,295 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype GaussianBlur
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-blur
\brief Applies a higher quality blur effect.
GaussianBlur effect softens the image by blurring it with an algorithm that
uses the Gaussian function to calculate the effect. The effect produces
higher quality than \l{QtGraphicalEffects1::FastBlur}{FastBlur}, but is
slower to render.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_bug.png
\li \image GaussianBlur_bug.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet GaussianBlur-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that is going to be blurred.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the distance of the neighboring pixels which
affect the blurring of an individual pixel. A larger radius increases
the blur effect.
Depending on the radius value, value of the
\l{GaussianBlur::samples}{samples} should be set to sufficiently large
to ensure the visual quality.
The value ranges from 0.0 (no blur) to inf. By default, the property is
set to \c 0.0 (no blur).
\table
\header
\li Output examples with different radius values
\li
\li
\row
\li \image GaussianBlur_radius1.png
\li \image GaussianBlur_radius2.png
\li \image GaussianBlur_radius3.png
\row
\li \b { radius: 0 }
\li \b { radius: 4 }
\li \b { radius: 8 }
\row
\li \l samples: 16
\li \l samples: 16
\li \l samples: 16
\row
\li \l deviation: 3
\li \l deviation: 3
\li \l deviation: 3
\endtable
*/
property real radius: 0.0
/*!
This property defines how many samples are taken per pixel when blur
calculation is done. Larger value produces better quality, but is slower
to render.
Ideally, this value should be twice as large as the highest required
radius value, for example, if the radius is animated between 0.0 and
4.0, samples should be set to 8.
The value ranges from 0 to 32. By default, the property is set to \c 0.
This property is not intended to be animated. Changing this property may
cause the underlying OpenGL shaders to be recompiled.
*/
property int samples: 0
/*!
This property is a parameter to the gaussian function that is used when
calculating neighboring pixel weights for the blurring. A larger
deviation causes image to appear more blurry, but it also reduces the
quality of the blur. A very large deviation value causes the effect to
look a bit similar to what, for exmple, a box blur algorithm produces. A
too small deviation values makes the effect insignificant for the pixels
near the radius.
\inlineimage GaussianBlur_deviation_graph.png
\caption The image above shows the Gaussian function with two different
deviation values, yellow (1) and cyan (2.7). The y-axis shows the
weights, the x-axis shows the pixel distance.
The value ranges from 0.0 (no deviation) to inf (maximum deviation). By
default, devaition is binded to radius. When radius increases, deviation
is automatically increased linearly. With the radius value of 8, the
deviation default value becomes approximately 2.7034. This value
produces a compromise between the blur quality and overall blurriness.
\table
\header
\li Output examples with different deviation values
\li
\li
\row
\li \image GaussianBlur_deviation1.png
\li \image GaussianBlur_deviation2.png
\li \image GaussianBlur_deviation3.png
\row
\li \b { deviation: 1 }
\li \b { deviation: 2 }
\li \b { deviation: 4 }
\row
\li \l radius: 8
\li \l radius: 8
\li \l radius: 8
\row
\li \l samples: 16
\li \l samples: 16
\li \l samples: 16
\endtable
*/
property real deviation: (radius + 1) / 3.3333
/*!
This property defines the blur behavior near the edges of the item,
where the pixel blurring is affected by the pixels outside the source
edges.
If the property is set to \c true, the pixels outside the source are
interpreted to be transparent, which is similar to OpenGL
clamp-to-border extension. The blur is expanded slightly outside the
effect item area.
If the property is set to \c false, the pixels outside the source are
interpreted to contain the same color as the pixels at the edge of the
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
not expand outside the effect item area.
By default, the property is set to \c false.
\table
\header
\li Output examples with different transparentBorder values
\li
\li
\row
\li \image GaussianBlur_transparentBorder1.png
\li \image GaussianBlur_transparentBorder2.png
\row
\li \b { transparentBorder: false }
\li \b { transparentBorder: true }
\row
\li \l radius: 8
\li \l radius: 8
\row
\li \l samples: 16
\li \l samples: 16
\row
\li \l deviation: 2.7
\li \l deviation: 2.7
\endtable
*/
property bool transparentBorder: false
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
}
ShaderEffectSource {
id: cacheItem
anchors.fill: verticalBlur
visible: rootItem.cached
smooth: true
sourceItem: verticalBlur
live: true
hideSource: visible
}
GaussianDirectionalBlur {
id: verticalBlur
x: transparentBorder ? -maximumRadius - 1 : 0
y: transparentBorder ? -maximumRadius - 1 : 0
width: horizontalBlur.width
height: horizontalBlur.height
horizontalStep: 0.0
verticalStep: 1.0 / parent.height
source: ShaderEffectSource {
id: horizontalBlurSource
sourceItem: horizontalBlur
hideSource: true
visible: false
smooth: true
}
deviation: rootItem.deviation
radius: rootItem.radius
maximumRadius: rootItem.samples * 0.5
transparentBorder: rootItem.transparentBorder
}
GaussianDirectionalBlur {
id: horizontalBlur
width: transparentBorder ? parent.width + 2 * maximumRadius + 2 : parent.width
height: transparentBorder ? parent.height + 2 * maximumRadius + 2 : parent.height
horizontalStep: 1.0 / parent.width
verticalStep: 0.0
source: sourceProxy.output
deviation: rootItem.deviation
radius: rootItem.radius
maximumRadius: rootItem.samples / 2.0
transparentBorder: rootItem.transparentBorder
}
}
@@ -1,324 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype Glow
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-glow
\brief Generates a blurred and colorized image of the source and places it
behind the original, giving impression that the source is glowing.
By default effect produces a high quality glow image, thus the rendering
speed of the effect may not be the highest possible. The rendering speed is
reduced especially if the glow edges are heavily softened. For use cases
that require faster rendering speed and the highest possible visual quality
is not necessary, property \l{Glow::fast}{fast} can be set to true.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_butterfly_black.png
\li \image Glow_butterfly.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet Glow-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that is going to be used as source
for the generated glow.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
Radius defines the softness of the glow. A larger radius causes the
edges of the glow to appear more blurry.
Depending on the radius value, value of the \l{Glow::samples}{samples}
should be set to sufficiently large to ensure the visual quality.
The value ranges from 0.0 (no blur) to inf. By default, the property is
set to \c 0.0 (no blur).
\table
\header
\li Output examples with different radius values
\li
\li
\row
\li \image Glow_radius1.png
\li \image Glow_radius2.png
\li \image Glow_radius3.png
\row
\li \b { radius: 0 }
\li \b { radius: 6 }
\li \b { radius: 12 }
\row
\li \l samples: 24
\li \l samples: 24
\li \l samples: 24
\row
\li \l color: #ffffff
\li \l color: #ffffff
\li \l color: #ffffff
\row
\li \l spread: 0
\li \l spread: 0
\li \l spread: 0
\endtable
*/
property real radius: 0.0
/*!
This property defines how many samples are taken per pixel when edge
softening blur calculation is done. Larger value produces better
quality, but is slower to render.
Ideally, this value should be twice as large as the highest required
radius value, for example, if the radius is animated between 0.0 and
4.0, samples should be set to 8.
The value ranges from 0 to 32. By default, the property is set to \c 0.
This property is not intended to be animated. Changing this property may
cause the underlying OpenGL shaders to be recompiled.
When \l fast property is set to true, this property has no effect.
*/
property int samples: 0
/*!
This property defines how large part of the glow color is strenghtened
near the source edges.
The values range from 0.0 to 1.0. By default, the property is set to \c
0.5.
\table
\header
\li Output examples with different spread values
\li
\li
\row
\li \image Glow_spread1.png
\li \image Glow_spread2.png
\li \image Glow_spread3.png
\row
\li \b { spread: 0.0 }
\li \b { spread: 0.5 }
\li \b { spread: 1.0 }
\row
\li \l radius: 8
\li \l radius: 8
\li \l radius: 8
\row
\li \l samples: 16
\li \l samples: 16
\li \l samples: 16
\row
\li \l color: #ffffff
\li \l color: #ffffff
\li \l color: #ffffff
\endtable
*/
property real spread: 0.0
/*!
This property defines the RGBA color value which is used for the glow.
By default, the property is set to \c "white".
\table
\header
\li Output examples with different color values
\li
\li
\row
\li \image Glow_color1.png
\li \image Glow_color2.png
\li \image Glow_color3.png
\row
\li \b { color: #ffffff }
\li \b { color: #00ff00 }
\li \b { color: #aa00ff00 }
\row
\li \l radius: 8
\li \l radius: 8
\li \l radius: 8
\row
\li \l samples: 16
\li \l samples: 16
\li \l samples: 16
\row
\li \l spread: 0.5
\li \l spread: 0.5
\li \l spread: 0.5
\endtable
*/
property color color: "white"
/*!
This property selects the blurring algorithm that is used to produce the
softness for the effect. Setting this to true enables fast algorithm,
setting value to false produces higher quality result.
By default, the property is set to \c false.
\table
\header
\li Output examples with different fast values
\li
\li
\row
\li \image Glow_fast1.png
\li \image Glow_fast2.png
\row
\li \b { fast: false }
\li \b { fast: true }
\row
\li \l radius: 16
\li \l radius: 16
\row
\li \l samples: 24
\li \l samples: 24
\row
\li \l color: #ffffff
\li \l color: #ffffff
\row
\li \l spread: 0.3
\li \l spread: 0.3
\endtable
*/
property bool fast: false
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
/*!
This property determines whether or not the effect has a transparent
border.
When set to \c true, the exterior of the item is padded with a 1 pixel
wide transparent edge, making sampling outside the source texture use
transparency instead of the edge pixels. Without this property, an
image which has opaque edges will not get a blurred edge.
In the snippet below, the Rectangle on the left has transparent borders
and has blurred edges, whereas the Rectangle on the right does not.
\snippet Glow-transparentBorder-example.qml example
\image transparentBorder.png
*/
property bool transparentBorder: false
Loader {
anchors.fill: parent
sourceComponent: rootItem.fast ? fastGlow : gaussianGlow
}
Component {
id: gaussianGlow
GaussianGlow {
anchors.fill: parent
source: sourceProxy.output
radius: rootItem.radius
maximumRadius: rootItem.samples * 0.5
color: rootItem.color
cached: rootItem.cached
spread: rootItem.spread
transparentBorder: rootItem.transparentBorder
}
}
Component {
id: fastGlow
FastGlow {
anchors.fill: parent
source: sourceProxy.output
blur: Math.pow(rootItem.radius / 64.0, 0.4)
color: rootItem.color
cached: rootItem.cached
spread: rootItem.spread
transparentBorder: rootItem.transparentBorder
}
}
SourceProxy {
id: sourceProxy
input: rootItem.source
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
}
ShaderEffect {
anchors.fill: parent
property variant source: sourceProxy.output
}
}
@@ -1,300 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype HueSaturation
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-color
\brief Alters the source item colors in the HSL color space.
HueSaturation is similar to the \l{QtGraphicalEffects1::Colorize}{Colorize}
effect, but the hue and saturation property values are handled differently.
The HueSaturation effect always shifts the hue, saturation, and lightness
from the original, instead of setting them.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_bug.png
\li \image HueSaturation_bug.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet HueSaturation-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that provides the source pixels
for the effect.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source: 0
/*!
This property defines the hue value which is added to the source hue
value.
The value ranges from -1.0 (decrease) to 1.0 (increase). By default, the
property is set to \c 0.0 (no change).
\table
\header
\li Output examples with different hue values
\li
\li
\row
\li \image HueSaturation_hue1.png
\li \image HueSaturation_hue2.png
\li \image HueSaturation_hue3.png
\row
\li \b { hue: -0.3 }
\li \b { hue: 0.0 }
\li \b { hue: 0.3 }
\row
\li \l saturation: 0
\li \l saturation: 0
\li \l saturation: 0
\row
\li \l lightness: 0
\li \l lightness: 0
\li \l lightness: 0
\endtable
*/
property real hue: 0.0
/*!
This property defines the saturation value value which is added to the
source saturation value.
The value ranges from -1.0 (decrease) to 1.0 (increase). By default, the
property is set to \c 0.0 (no change).
\table
\header
\li Output examples with different saturation values
\li
\li
\row
\li \image HueSaturation_saturation1.png
\li \image HueSaturation_saturation2.png
\li \image HueSaturation_saturation3.png
\row
\li \b { saturation: -0.8 }
\li \b { saturation: 0.0 }
\li \b { saturation: 1.0 }
\row
\li \l hue: 0
\li \l hue: 0
\li \l hue: 0
\row
\li \l lightness: 0
\li \l lightness: 0
\li \l lightness: 0
\endtable
*/
property real saturation: 0.0
/*!
This property defines the lightness value which is added to the source
saturation value.
The value ranges from -1.0 (decrease) to 1.0 (increase). By default, the
property is set to \c 0.0 (no change).
\table
\header
\li Output examples with different lightness values
\li
\li
\row
\li \image HueSaturation_lightness1.png
\li \image HueSaturation_lightness2.png
\li \image HueSaturation_lightness3.png
\row
\li \b { lightness: -0.5 }
\li \b { lightness: 0.0 }
\li \b { lightness: 0.5 }
\row
\li \l hue: 0
\li \l hue: 0
\li \l hue: 0
\row
\li \l saturation: 0
\li \l saturation: 0
\li \l saturation: 0
\endtable
*/
property real lightness: 0.0
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
ShaderEffectSource {
id: cacheItem
anchors.fill: parent
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant source: sourceProxy.output
property variant hsl: Qt.vector3d(rootItem.hue, rootItem.saturation, rootItem.lightness)
anchors.fill: parent
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform highp sampler2D source;
uniform highp vec3 hsl;
highp vec3 RGBtoHSL(highp vec3 color) {
highp float cmin = min(color.r, min(color.g, color.b));
highp float cmax = max(color.r, max(color.g, color.b));
highp float h = 0.0;
highp float s = 0.0;
highp float l = (cmin + cmax) / 2.0;
highp float diff = cmax - cmin;
if (diff > 1.0 / 256.0) {
if (l < 0.5)
s = diff / (cmin + cmax);
else
s = diff / (2.0 - (cmin + cmax));
if (color.r == cmax)
h = (color.g - color.b) / diff;
else if (color.g == cmax)
h = 2.0 + (color.b - color.r) / diff;
else
h = 4.0 + (color.r - color.g) / diff;
h /= 6.0;
}
return vec3(h, s, l);
}
highp float hueToIntensity(highp float v1, highp float v2, highp float h) {
h = fract(h);
if (h < 1.0 / 6.0)
return v1 + (v2 - v1) * 6.0 * h;
else if (h < 1.0 / 2.0)
return v2;
else if (h < 2.0 / 3.0)
return v1 + (v2 - v1) * 6.0 * (2.0 / 3.0 - h);
return v1;
}
highp vec3 HSLtoRGB(highp vec3 color) {
highp float h = color.x;
highp float l = color.z;
highp float s = color.y;
if (s < 1.0 / 256.0)
return vec3(l);
highp float v1;
highp float v2;
if (l < 0.5)
v2 = l * (1.0 + s);
else
v2 = (l + s) - (s * l);
v1 = 2.0 * l - v2;
highp float d = 1.0 / 3.0;
highp float r = hueToIntensity(v1, v2, h + d);
highp float g = hueToIntensity(v1, v2, h);
highp float b = hueToIntensity(v1, v2, h - d);
return vec3(r, g, b);
}
void main() {
lowp vec4 sample = texture2D(source, qt_TexCoord0);
sample = vec4(sample.rgb / max(1.0/256.0, sample.a), sample.a);
sample.rgb = mix(vec3(dot(sample.rgb, vec3(0.2125, 0.7154, 0.0721))), sample.rgb, 1.0 + hsl.y);
sample.xyz = RGBtoHSL(sample.rgb);
sample.rgb = HSLtoRGB(vec3(sample.x + hsl.x, sample.y, sample.z));
highp float c = step(0.0, hsl.z);
sample.rgb = mix(sample.rgb, vec3(c), abs(hsl.z));
gl_FragColor = vec4(sample.rgb * sample.a, sample.a) * qt_Opacity;
}
"
}
}
@@ -1,385 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype InnerShadow
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-drop-shadow
\brief Generates a colorized and blurred shadow inside the
source.
By default the effect produces a high quality shadow image, thus the
rendering speed of the shadow might not be the highest possible. The
rendering speed is reduced especially if the shadow edges are heavily
softened. For use cases that require faster rendering speed and for which
the highest possible visual quality is not necessary, property
\l{InnerShadow::fast}{fast} can be set to true.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_butterfly.png
\li \image InnerShadow_butterfly.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet InnerShadow-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that is going to be used as the
source for the generated shadow.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
Radius defines the softness of the shadow. A larger radius causes the
edges of the shadow to appear more blurry.
Depending on the radius value, value of the
\l{InnerShadow::samples}{samples} should be set to sufficiently large to
ensure the visual quality.
The value ranges from 0.0 (no blur) to inf. By default, the property is
set to \c 0.0 (no blur).
\table
\header
\li Output examples with different radius values
\li
\li
\row
\li \image InnerShadow_radius1.png
\li \image InnerShadow_radius2.png
\li \image InnerShadow_radius3.png
\row
\li \b { radius: 0 }
\li \b { radius: 6 }
\li \b { radius: 12 }
\row
\li \l samples: 24
\li \l samples: 24
\li \l samples: 24
\row
\li \l color: #000000
\li \l color: #000000
\li \l color: #000000
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\row
\li \l spread: 0
\li \l spread: 0
\li \l spread: 0
\endtable
*/
property real radius: 0.0
/*!
This property defines how many samples are taken per pixel when edge
softening blur calculation is done. Larger value produces better
quality, but is slower to render.
Ideally, this value should be twice as large as the highest required
radius value, for example, if the radius is animated between 0.0 and
4.0, samples should be set to 8.
The value ranges from 0 to 32. By default, the property is set to \c 0.
This property is not intended to be animated. Changing this property may
cause the underlying OpenGL shaders to be recompiled.
When \l{InnerShadow::fast}{fast} property is set to true, this property
has no effect.
*/
property int samples: 0
/*!
This property defines how large part of the shadow color is strenghtened
near the source edges.
The value ranges from 0.0 to 1.0. By default, the property is set to \c
0.5.
\table
\header
\li Output examples with different spread values
\li
\li
\row
\li \image InnerShadow_spread1.png
\li \image InnerShadow_spread2.png
\li \image InnerShadow_spread3.png
\row
\li \b { spread: 0.0 }
\li \b { spread: 0.3 }
\li \b { spread: 0.5 }
\row
\li \l radius: 16
\li \l radius: 16
\li \l radius: 16
\row
\li \l samples: 24
\li \l samples: 24
\li \l samples: 24
\row
\li \l color: #000000
\li \l color: #000000
\li \l color: #000000
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\endtable
*/
property real spread: 0.0
/*!
This property defines the RGBA color value which is used for the shadow.
By default, the property is set to \c "black".
\table
\header
\li Output examples with different color values
\li
\li
\row
\li \image InnerShadow_color1.png
\li \image InnerShadow_color2.png
\li \image InnerShadow_color3.png
\row
\li \b { color: #000000 }
\li \b { color: #ffffff }
\li \b { color: #ff0000 }
\row
\li \l radius: 16
\li \l radius: 16
\li \l radius: 16
\row
\li \l samples: 24
\li \l samples: 24
\li \l samples: 24
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\row
\li \l spread: 0.2
\li \l spread: 0.2
\li \l spread: 0.2
\endtable
*/
property color color: "black"
/*!
\qmlproperty real QtGraphicalEffects1::InnerShadow::horizontalOffset
\qmlproperty real QtGraphicalEffects1::InnerShadow::verticalOffset
HorizontalOffset and verticalOffset properties define the offset for the
rendered shadow compared to the InnerShadow item position. Often, the
InnerShadow item is anchored so that it fills the source element. In
this case, if the HorizontalOffset and verticalOffset properties are set
to 0, the shadow is rendered fully inside the source item. By changing
the offset properties, the shadow can be positioned relatively to the
source item.
The values range from -inf to inf. By default, the properties are set to
\c 0.
\table
\header
\li Output examples with different horizontalOffset values
\li
\li
\row
\li \image InnerShadow_horizontalOffset1.png
\li \image InnerShadow_horizontalOffset2.png
\li \image InnerShadow_horizontalOffset3.png
\row
\li \b { horizontalOffset: -20 }
\li \b { horizontalOffset: 0 }
\li \b { horizontalOffset: 20 }
\row
\li \l radius: 16
\li \l radius: 16
\li \l radius: 16
\row
\li \l samples: 24
\li \l samples: 24
\li \l samples: 24
\row
\li \l color: #000000
\li \l color: #000000
\li \l color: #000000
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\row
\li \l spread: 0
\li \l spread: 0
\li \l spread: 0
\endtable
*/
property real horizontalOffset: 0
property real verticalOffset: 0
/*!
This property selects the blurring algorithm that is used to produce the
softness for the effect. Setting this to true enables fast algorithm,
setting value to false produces higher quality result.
By default, the property is set to \c false.
\table
\header
\li Output examples with different fast values
\li
\li
\row
\li \image InnerShadow_fast1.png
\li \image InnerShadow_fast2.png
\row
\li \b { fast: false }
\li \b { fast: true }
\row
\li \l radius: 16
\li \l radius: 16
\row
\li \l samples: 24
\li \l samples: 24
\row
\li \l color: #000000
\li \l color: #000000
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\row
\li \l spread: 0.2
\li \l spread: 0.2
\endtable
*/
property bool fast: false
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance. Every time the source or effect
properties are changed, the pixels in the cache must be updated. Memory
consumption is increased, because an extra buffer of memory is required
for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
Loader {
anchors.fill: parent
sourceComponent: rootItem.fast ? innerShadow : gaussianInnerShadow
}
Component {
id: gaussianInnerShadow
GaussianInnerShadow {
anchors.fill: parent
source: rootItem.source
radius: rootItem.radius
maximumRadius: rootItem.samples * 0.5
color: rootItem.color
cached: rootItem.cached
spread: rootItem.spread
horizontalOffset: rootItem.horizontalOffset
verticalOffset: rootItem.verticalOffset
}
}
Component {
id: innerShadow
FastInnerShadow {
anchors.fill: parent
source: rootItem.source
blur: Math.pow(rootItem.radius / 64.0, 0.4)
color: rootItem.color
cached: rootItem.cached
spread: rootItem.spread
horizontalOffset: rootItem.horizontalOffset
verticalOffset: rootItem.verticalOffset
}
}
}
@@ -1,472 +0,0 @@
/*****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Add-On Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype LevelAdjust
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-color
\brief Adjusts color levels in the RGBA color space.
This effect adjusts the source item colors separately for each color
channel. Source item contrast can be adjusted and color balance altered.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_butterfly.png
\li \image LevelAdjust_butterfly.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet LevelAdjust-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that provides the source pixels
for the effect.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the change factor for how the value of each pixel
color channel is altered according to the equation:
\code result.rgb = pow(original.rgb, 1.0 / gamma.rgb); \endcode
Setting the gamma values under QtVector3d(1.0, 1.0, 1.0) makes the image
darker, the values above QtVector3d(1.0, 1.0, 1.0) lighten it.
The value ranges from QtVector3d(0.0, 0.0, 0.0) (darkest) to inf
(lightest). By default, the property is set to \c QtVector3d(1.0, 1.0,
1.0) (no change).
\table
\header
\li Output examples with different gamma values
\li
\li
\row
\li \image LevelAdjust_gamma1.png
\li \image LevelAdjust_gamma2.png
\li \image LevelAdjust_gamma3.png
\row
\li \b { gamma: Qt.vector3d(1.0, 1.0, 1.0) }
\li \b { gamma: Qt.vector3d(1.0, 0.4, 2.0) }
\li \b { gamma: Qt.vector3d(1.0, 0.1, 4.0) }
\row
\li \l minimumInput: #000000
\li \l minimumInput: #000000
\li \l minimumInput: #000000
\row
\li \l maximumInput: #ffffff
\li \l maximumInput: #ffffff
\li \l maximumInput: #ffffff
\row
\li \l minimumOutput: #000000
\li \l minimumOutput: #000000
\li \l minimumOutput: #000000
\row
\li \l maximumOutput: #ffffff
\li \l maximumOutput: #ffffff
\li \l maximumOutput: #ffffff
\endtable
\table
\header
\li Pixel color channel luminance curves of the above images.
\li
\li
\row
\li \image LevelAdjust_default_curve.png
\li \image LevelAdjust_gamma2_curve.png
\li \image LevelAdjust_gamma3_curve.png
\row
\li X-axis: pixel original luminance
\li
\li
\row
\li Y-axis: color channel luminance with effect applied
\li
\li
\endtable
*/
property variant gamma: Qt.vector3d(1.0, 1.0, 1.0)
/*!
This property defines the minimum input level for each color channel. It
sets the black-point, all pixels having lower value than this property
are rendered as black (per color channel). Increasing the value darkens
the dark areas.
The value ranges from "#00000000" to "#ffffffff". By default, the
property is set to \c "#00000000" (no change).
\table
\header
\li Output examples with different minimumInput values
\li
\li
\row
\li \image LevelAdjust_minimumInput1.png
\li \image LevelAdjust_minimumInput2.png
\li \image LevelAdjust_minimumInput3.png
\row
\li \b { minimumInput: #00000000 }
\li \b { minimumInput: #00000040 }
\li \b { minimumInput: #00000070 }
\row
\li \l maximumInput: #ffffff
\li \l maximumInput: #ffffff
\li \l maximumInput: #ffffff
\row
\li \l minimumOutput: #000000
\li \l minimumOutput: #000000
\li \l minimumOutput: #000000
\row
\li \l maximumOutput: #ffffff
\li \l maximumOutput: #ffffff
\li \l maximumOutput: #ffffff
\row
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
\endtable
\table
\header
\li Pixel color channel luminance curves of the above images.
\li
\li
\row
\li \image LevelAdjust_default_curve.png
\li \image LevelAdjust_minimumInput2_curve.png
\li \image LevelAdjust_minimumInput3_curve.png
\row
\li X-axis: pixel original luminance
\li
\li
\row
\li Y-axis: color channel luminance with effect applied
\li
\li
\endtable
*/
property color minimumInput: Qt.rgba(0.0, 0.0, 0.0, 0.0)
/*!
This property defines the maximum input level for each color channel.
It sets the white-point, all pixels having higher value than this
property are rendered as white (per color channel).
Decreasing the value lightens the light areas.
The value ranges from "#ffffffff" to "#00000000". By default, the
property is set to \c "#ffffffff" (no change).
\table
\header
\li Output examples with different maximumInput values
\li
\li
\row
\li \image LevelAdjust_maximumInput1.png
\li \image LevelAdjust_maximumInput2.png
\li \image LevelAdjust_maximumInput3.png
\row
\li \b { maximumInput: #FFFFFFFF }
\li \b { maximumInput: #FFFFFF80 }
\li \b { maximumInput: #FFFFFF30 }
\row
\li \l minimumInput: #000000
\li \l minimumInput: #000000
\li \l minimumInput: #000000
\row
\li \l minimumOutput: #000000
\li \l minimumOutput: #000000
\li \l minimumOutput: #000000
\row
\li \l maximumOutput: #ffffff
\li \l maximumOutput: #ffffff
\li \l maximumOutput: #ffffff
\row
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
\endtable
\table
\header
\li Pixel color channel luminance curves of the above images.
\li
\li
\row
\li \image LevelAdjust_default_curve.png
\li \image LevelAdjust_maximumInput2_curve.png
\li \image LevelAdjust_maximumInput3_curve.png
\row
\li X-axis: pixel original luminance
\li
\li
\row
\li Y-axis: color channel luminance with effect applied
\li
\li
\endtable
*/
property color maximumInput: Qt.rgba(1.0, 1.0, 1.0, 1.0)
/*!
This property defines the minimum output level for each color channel.
Increasing the value lightens the dark areas, reducing the contrast.
The value ranges from "#00000000" to "#ffffffff". By default, the
property is set to \c "#00000000" (no change).
\table
\header
\li Output examples with different minimumOutput values
\li
\li
\row
\li \image LevelAdjust_minimumOutput1.png
\li \image LevelAdjust_minimumOutput2.png
\li \image LevelAdjust_minimumOutput3.png
\row
\li \b { minimumOutput: #00000000 }
\li \b { minimumOutput: #00000070 }
\li \b { minimumOutput: #000000A0 }
\row
\li \l minimumInput: #000000
\li \l minimumInput: #000000
\li \l minimumInput: #000000
\row
\li \l maximumInput: #ffffff
\li \l maximumInput: #ffffff
\li \l maximumInput: #ffffff
\row
\li \l maximumOutput: #ffffff
\li \l maximumOutput: #ffffff
\li \l maximumOutput: #ffffff
\row
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
\endtable
\table
\header
\li Pixel color channel luminance curves of the above images.
\li
\li
\row
\li \image LevelAdjust_default_curve.png
\li \image LevelAdjust_minimumOutput2_curve.png
\li \image LevelAdjust_minimumOutput3_curve.png
\row
\li X-axis: pixel original luminance
\li
\li
\row
\li Y-axis: color channel luminance with effect applied
\li
\li
\endtable
*/
property color minimumOutput: Qt.rgba(0.0, 0.0, 0.0, 0.0)
/*!
This property defines the maximum output level for each color channel.
Decreasing the value darkens the light areas, reducing the contrast.
The value ranges from "#ffffffff" to "#00000000". By default, the
property is set to \c "#ffffffff" (no change).
\table
\header
\li Output examples with different maximumOutput values
\li
\li
\row
\li \image LevelAdjust_maximumOutput1.png
\li \image LevelAdjust_maximumOutput2.png
\li \image LevelAdjust_maximumOutput3.png
\row
\li \b { maximumOutput: #FFFFFFFF }
\li \b { maximumOutput: #FFFFFF80 }
\li \b { maximumOutput: #FFFFFF30 }
\row
\li \l minimumInput: #000000
\li \l minimumInput: #000000
\li \l minimumInput: #000000
\row
\li \l maximumInput: #ffffff
\li \l maximumInput: #ffffff
\li \l maximumInput: #ffffff
\row
\li \l minimumOutput: #000000
\li \l minimumOutput: #000000
\li \l minimumOutput: #000000
\row
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
\endtable
\table
\header
\li Pixel color channel luminance curves of the above images.
\li
\li
\row
\li \image LevelAdjust_default_curve.png
\li \image LevelAdjust_maximumOutput2_curve.png
\li \image LevelAdjust_maximumOutput3_curve.png
\row
\li X-axis: pixel original luminance
\li
\li
\row
\li Y-axis: color channel luminance with effect applied
\li
\li
\endtable
*/
property color maximumOutput: Qt.rgba(1.0, 1.0, 1.0, 1.0)
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
ShaderEffectSource {
id: cacheItem
anchors.fill: parent
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant source: sourceProxy.output
property variant minimumInputRGB: Qt.vector3d(rootItem.minimumInput.r, rootItem.minimumInput.g, rootItem.minimumInput.b)
property variant maximumInputRGB: Qt.vector3d(rootItem.maximumInput.r, rootItem.maximumInput.g, rootItem.maximumInput.b)
property real minimumInputAlpha: rootItem.minimumInput.a
property real maximumInputAlpha: rootItem.maximumInput.a
property variant minimumOutputRGB: Qt.vector3d(rootItem.minimumOutput.r, rootItem.minimumOutput.g, rootItem.minimumOutput.b)
property variant maximumOutputRGB: Qt.vector3d(rootItem.maximumOutput.r, rootItem.maximumOutput.g, rootItem.maximumOutput.b)
property real minimumOutputAlpha: rootItem.minimumOutput.a
property real maximumOutputAlpha: rootItem.maximumOutput.a
property variant gamma: Qt.vector3d(1.0 / Math.max(rootItem.gamma.x, 0.0001), 1.0 / Math.max(rootItem.gamma.y, 0.0001), 1.0 / Math.max(rootItem.gamma.z, 0.0001))
anchors.fill: parent
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform highp vec3 minimumInputRGB;
uniform highp vec3 maximumInputRGB;
uniform highp float minimumInputAlpha;
uniform highp float maximumInputAlpha;
uniform highp vec3 minimumOutputRGB;
uniform highp vec3 maximumOutputRGB;
uniform highp float minimumOutputAlpha;
uniform highp float maximumOutputAlpha;
uniform highp vec3 gamma;
highp float linearstep(highp float e0, highp float e1, highp float x) {
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
}
void main(void) {
highp vec4 textureColor = texture2D(source, qt_TexCoord0.st);
highp vec4 color = vec4(textureColor.rgb / max(1.0/256.0, textureColor.a), textureColor.a);
color.r = linearstep(minimumInputRGB.r, maximumInputRGB.r, color.r);
color.g = linearstep(minimumInputRGB.g, maximumInputRGB.g, color.g);
color.b = linearstep(minimumInputRGB.b, maximumInputRGB.b, color.b);
color.a = linearstep(minimumInputAlpha, maximumInputAlpha, color.a);
color.rgb = pow(color.rgb, gamma);
color.r = minimumOutputRGB.r + color.r * (maximumOutputRGB.r - minimumOutputRGB.r);
color.g = minimumOutputRGB.g + color.g * (maximumOutputRGB.g - minimumOutputRGB.g);
color.b = minimumOutputRGB.b + color.b * (maximumOutputRGB.b - minimumOutputRGB.b);
color.a = minimumOutputAlpha + color.a * (maximumOutputAlpha - minimumOutputAlpha);
gl_FragColor = vec4(color.rgb * color.a, color.a) * qt_Opacity;
}
"
}
}
@@ -1,346 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype LinearGradient
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-gradient
\brief Draws a linear gradient.
A gradient is defined by two or more colors, which are blended seamlessly.
The colors start from the given start point and end to the given end point.
\table
\header
\li Effect applied
\row
\li \image LinearGradient.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet LinearGradient-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the starting point where the color at gradient
position of 0.0 is rendered. Colors at larger position values are
rendered linearly towards the end point. The point is given in pixels
and the default value is Qt.point(0, 0). Setting the default values for
the start and \l{LinearGradient::end}{end} results in a full height
linear gradient on the y-axis.
\table
\header
\li Output examples with different start values
\li
\li
\row
\li \image LinearGradient_start1.png
\li \image LinearGradient_start2.png
\li \image LinearGradient_start3.png
\row
\li \b { start: QPoint(0, 0) }
\li \b { start: QPoint(150, 150) }
\li \b { start: QPoint(300, 0) }
\row
\li \l end: QPoint(300, 300)
\li \l end: QPoint(300, 300)
\li \l end: QPoint(300, 300)
\endtable
*/
property variant start: Qt.point(0, 0)
/*!
This property defines the ending point where the color at gradient
position of 1.0 is rendered. Colors at smaller position values are
rendered linearly towards the start point. The point is given in pixels
and the default value is Qt.point(0, height). Setting the default values
for the \l{LinearGradient::start}{start} and end results in a full
height linear gradient on the y-axis.
\table
\header
\li Output examples with different end values
\li
\li
\row
\li \image LinearGradient_end1.png
\li \image LinearGradient_end2.png
\li \image LinearGradient_end3.png
\row
\li \b { end: Qt.point(300, 300) }
\li \b { end: Qt.point(150, 150) }
\li \b { end: Qt.point(300, 0) }
\row
\li \l start: Qt.point(0, 0)
\li \l start: Qt.point(0, 0)
\li \l start: Qt.point(0, 0)
\endtable
*/
property variant end: Qt.point(0, height)
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
/*!
This property defines the item that is going to be filled with gradient.
Source item gets rendered into an intermediate pixel buffer and the
alpha values from the result are used to determine the gradient's pixels
visibility in the display. The default value for source is undefined and
in that case whole effect area is filled with gradient.
\table
\header
\li Output examples with different source values
\li
\li
\row
\li \image LinearGradient_maskSource1.png
\li \image LinearGradient_maskSource2.png
\row
\li \b { source: undefined }
\li \b { source: Image { source: images/butterfly.png } }
\row
\li \l start: Qt.point(0, 0)
\li \l start: Qt.point(0, 0)
\row
\li \l end: Qt.point(300, 300)
\li \l end: Qt.point(300, 300)
\endtable
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
A gradient is defined by two or more colors, which are blended
seamlessly. The colors are specified as a set of GradientStop child
items, each of which defines a position on the gradient from 0.0 to 1.0
and a color. The position of each GradientStop is defined by the
position property, and the color is definded by the color property.
\table
\header
\li Output examples with different gradient values
\li
\li
\row
\li \image LinearGradient_gradient1.png
\li \image LinearGradient_gradient2.png
\li \image LinearGradient_gradient3.png
\row
\li \b {gradient:} \code
Gradient {
GradientStop { position: 0.000
color: Qt.rgba(1, 0, 0, 1) }
GradientStop { position: 0.167;
color: Qt.rgba(1, 1, 0, 1) }
GradientStop { position: 0.333;
color: Qt.rgba(0, 1, 0, 1) }
GradientStop { position: 0.500;
color: Qt.rgba(0, 1, 1, 1) }
GradientStop { position: 0.667;
color: Qt.rgba(0, 0, 1, 1) }
GradientStop { position: 0.833;
color: Qt.rgba(1, 0, 1, 1) }
GradientStop { position: 1.000;
color: Qt.rgba(1, 0, 0, 1) }
}
\endcode
\li \b {gradient:} \code
Gradient {
GradientStop { position: 0.0
color: "#F0F0F0"
}
GradientStop { position: 0.5
color: "#000000"
}
GradientStop { position: 1.0
color: "#F0F0F0"
}
}
\endcode
\li \b {gradient:} \code
Gradient {
GradientStop { position: 0.0
color: "#00000000"
}
GradientStop { position: 1.0
color: "#FF000000"
}
}
\endcode
\row
\li \l start: Qt.point(0, 0)
\li \l start: Qt.point(0, 0)
\li \l start: Qt.point(0, 0)
\row
\li \l end: Qt.point(300, 300)
\li \l end: Qt.point(300, 300)
\li \l end: Qt.point(300, 300)
\endtable
*/
property Gradient gradient: Gradient {
GradientStop { position: 0.0; color: "white" }
GradientStop { position: 1.0; color: "black" }
}
SourceProxy {
id: maskSourceProxy
input: rootItem.source
}
ShaderEffectSource {
id: gradientSource
sourceItem: Rectangle {
width: 16
height: 256
gradient: rootItem.gradient
smooth: true
}
smooth: true
hideSource: true
visible: false
}
ShaderEffectSource {
id: cacheItem
anchors.fill: parent
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
anchors.fill: parent
property variant source: gradientSource
property variant maskSource: maskSourceProxy.output
property variant startPoint: Qt.point(start.x / width, start.y / height)
property real dx: end.x - start.x
property real dy: end.y - start.y
property real l: 1.0 / Math.sqrt(Math.pow(dx / width, 2.0) + Math.pow(dy / height, 2.0))
property real angle: Math.atan2(dx, dy)
property variant matrixData: Qt.point(Math.sin(angle), Math.cos(angle))
vertexShader: "
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
uniform highp mat4 qt_Matrix;
varying highp vec2 qt_TexCoord0;
varying highp vec2 qt_TexCoord1;
uniform highp vec2 startPoint;
uniform highp float l;
uniform highp vec2 matrixData;
void main() {
highp mat2 rot = mat2(matrixData.y, -matrixData.x,
matrixData.x, matrixData.y);
qt_TexCoord0 = qt_MultiTexCoord0;
qt_TexCoord1 = qt_MultiTexCoord0 * l;
qt_TexCoord1 -= startPoint * l;
qt_TexCoord1 *= rot;
gl_Position = qt_Matrix * qt_Vertex;
}
"
fragmentShader: maskSource == undefined ? noMaskShader : maskShader
onFragmentShaderChanged: lChanged()
property string maskShader: "
uniform lowp sampler2D source;
uniform lowp sampler2D maskSource;
uniform lowp float qt_Opacity;
varying highp vec2 qt_TexCoord0;
varying highp vec2 qt_TexCoord1;
void main() {
lowp vec4 gradientColor = texture2D(source, qt_TexCoord1);
lowp float maskAlpha = texture2D(maskSource, qt_TexCoord0).a;
gl_FragColor = gradientColor * maskAlpha * qt_Opacity;
}
"
property string noMaskShader: "
uniform lowp sampler2D source;
uniform lowp float qt_Opacity;
varying highp vec2 qt_TexCoord1;
void main() {
gl_FragColor = texture2D(source, qt_TexCoord1) * qt_Opacity;
}
"
}
}
@@ -1,282 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype MaskedBlur
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-blur
\brief Applies a blur effect with a varying intesity.
MaskedBlur effect softens the image by blurring it. The intensity of the
blur can be controlled for each pixel using maskSource so that some parts of
the source are blurred more than others. By default the effect produces a
high quality result, thus the rendering speed may not be the highest
possible. The rendering speed is reduced especially if the
\l{MaskedBlur::samples}{samples} is large. For use cases that require faster
rendering speed and the highest possible visual quality is not necessary,
property \l{MaskedBlur::fast}{fast} can be set to true.
\table
\header
\li Source
\li MaskSource
\li Effect applied
\row
\li \image Original_bug.png
\li \image MaskedBlur_mask.png
\li \image MaskedBlur_bug.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet MaskedBlur-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that is going to be blurred.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the item that is controlling the final intensity
of the blur. The pixel alpha channel value from maskSource defines the
actual blur radius that is going to be used for blurring the
corresponding source pixel.
Opaque maskSource pixels produce blur with specified
\l{MaskedBlur::radius}{radius}, while transparent pixels suppress the
blur completely. Semitransparent maskSource pixels produce blur with a
radius that is interpolated according to the pixel transparency level.
*/
property variant maskSource
/*!
This property defines the distance of the neighboring pixels which
affect the blurring of an individual pixel. A larger radius increases
the blur effect.
Depending on the radius value, value of the
\l{MaskedBlur::samples}{samples} should be set to sufficiently large to
ensure the visual quality.
The value ranges from 0.0 (no blur) to inf. By default, the property is
set to \c 0.0 (no blur).
\table
\header
\li Output examples with different radius values
\li
\li
\row
\li \image MaskedBlur_radius1.png
\li \image MaskedBlur_radius2.png
\li \image MaskedBlur_radius3.png
\row
\li \b { radius: 0 }
\li \b { radius: 8 }
\li \b { radius: 16 }
\row
\li \l samples: 24
\li \l samples: 24
\li \l samples: 24
\row
\li \l transparentBorder: false
\li \l transparentBorder: false
\li \l transparentBorder: false
\row
\li \l fast: false
\li \l fast: false
\li \l fast: false
\endtable
*/
property real radius: 0.0
/*!
This property defines how many samples are taken per pixel when blur
calculation is done. Larger value produces better quality, but is slower
to render.
Ideally, this value should be twice as large as the highest required
radius value, for example, if the radius is animated between 0.0 and
4.0, samples should be set to 8.
The value ranges from 0 to 32. By default, the property is set to \c 0.
This property is not intended to be animated. Changing this property may
cause the underlying OpenGL shaders to be recompiled.
When \l{MaskedBlur::fast}{fast} property is set to true, this property
has no effect.
*/
property int samples: 0
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance. Every time the source or effect
properties are changed, the pixels in the cache must be updated. Memory
consumption is increased, because an extra buffer of memory is required
for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
/*!
This property selects the blurring algorithm that is used to produce the
blur. Setting this to true enables fast algorithm, setting value to
false produces higher quality result.
By default, the property is set to \c false.
\table
\header
\li Output examples with different fast values
\li
\li
\row
\li \image MaskedBlur_fast1.png
\li \image MaskedBlur_fast2.png
\row
\li \b { fast: false }
\li \b { fast: true }
\row
\li \l radius: 16
\li \l radius: 16
\row
\li \l samples: 24
\li \l samples: 24
\row
\li \l transparentBorder: false
\li \l transparentBorder: false
\endtable
*/
property bool fast: false
/*!
This property defines the blur behavior near the edges of the item,
where the pixel blurring is affected by the pixels outside the source
edges.
If the property is set to \c true, the pixels outside the source are
interpreted to be transparent, which is similar to OpenGL
clamp-to-border extension. The blur is expanded slightly outside the
effect item area.
If the property is set to \c false, the pixels outside the source are
interpreted to contain the same color as the pixels at the edge of the
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
not expand outside the effect item area.
By default, the property is set to \c false.
\table
\header
\li Output examples with different transparentBorder values
\li
\li
\row
\li \image MaskedBlur_transparentBorder1.png
\li \image MaskedBlur_transparentBorder2.png
\row
\li \b { transparentBorder: false }
\li \b { transparentBorder: true }
\row
\li \l radius: 64
\li \l radius: 64
\row
\li \l samples: 24
\li \l samples: 24
\row
\li \l fast: true
\li \l fast: true
\endtable
*/
property bool transparentBorder: false
Loader {
id: loaderItem
anchors.fill: parent
sourceComponent: rootItem.fast ? fastBlur : gaussianBlur
}
Component {
id: gaussianBlur
GaussianMaskedBlur {
anchors.fill: parent
source: rootItem.source
maskSource: rootItem.maskSource
radius: rootItem.radius
maximumRadius: rootItem.samples * 0.5
transparentBorder: rootItem.transparentBorder
cached: rootItem.cached
}
}
Component {
id: fastBlur
FastMaskedBlur {
anchors.fill: parent
source:rootItem. source
maskSource: rootItem.maskSource
blur: Math.pow(rootItem.radius / 64.0, 0.4)
transparentBorder: rootItem.transparentBorder
cached: rootItem.cached
}
}
}
@@ -1,154 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype OpacityMask
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-mask
\brief Masks the source item with another item.
\table
\header
\li Source
\li MaskSource
\li Effect applied
\row
\li \image Original_bug.png
\li \image OpacityMask_mask.png
\li \image OpacityMask_bug.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet OpacityMask-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that is going to be masked.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the item that is going to be used as the mask. The
mask item gets rendered into an intermediate pixel buffer and the alpha
values from the result are used to determine the source item's pixels
visibility in the display.
\table
\header
\li Original
\li Mask
\li Effect applied
\row
\li \image Original_bug.png
\li \image OpacityMask_mask.png
\li \image OpacityMask_bug.png
\endtable
*/
property variant maskSource
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
\note It is not supported to let the effect include itself, for
instance by setting maskSource to the effect's parent.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
SourceProxy {
id: maskSourceProxy
input: rootItem.maskSource
}
ShaderEffectSource {
id: cacheItem
anchors.fill: parent
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant source: sourceProxy.output
property variant maskSource: maskSourceProxy.output
anchors.fill: parent
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform lowp sampler2D maskSource;
void main(void) {
gl_FragColor = texture2D(source, qt_TexCoord0.st) * (texture2D(maskSource, qt_TexCoord0.st).a) * qt_Opacity;
}
"
}
}
@@ -1,312 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype RadialBlur
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-motion-blur
\brief Applies directional blur in a circular direction around the items
center point.
Effect creates perceived impression that the source item appears to be
rotating to the direction of the blur.
Other available motionblur effects are
\l{QtGraphicalEffects1::ZoomBlur}{ZoomBlur} and
\l{QtGraphicalEffects1::DirectionalBlur}{DirectionalBlur}.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_bug.png
\li \image RadialBlur_bug.png
\endtable
\section1 Example Usage
The following example shows how to apply the effect.
\snippet RadialBlur-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that is going to be blurred.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the direction for the blur and at the same time
the level of blurring. The larger the angle, the more the result becomes
blurred. The quality of the blur depends on
\l{RadialBlur::samples}{samples} property. If angle value is large, more
samples are needed to keep the visual quality at high level.
Allowed values are between 0.0 and 360.0. By default the property is set
to \c 0.0.
\table
\header
\li Output examples with different angle values
\li
\li
\row
\li \image RadialBlur_angle1.png
\li \image RadialBlur_angle2.png
\li \image RadialBlur_angle3.png
\row
\li \b { angle: 0.0 }
\li \b { angle: 15.0 }
\li \b { angle: 30.0 }
\row
\li \l samples: 24
\li \l samples: 24
\li \l samples: 24
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\endtable
*/
property real angle: 0.0
/*!
This property defines how many samples are taken per pixel when blur
calculation is done. Larger value produces better quality, but is slower
to render.
This property is not intended to be animated. Changing this property may
cause the underlying OpenGL shaders to be recompiled.
Allowed values are between 0 and inf (practical maximum depends on GPU).
By default the property is set to \c 0 (no samples).
*/
property int samples: 0
/*!
\qmlproperty real QtGraphicalEffects1::RadialBlur::horizontalOffset
\qmlproperty real QtGraphicalEffects1::RadialBlur::verticalOffset
These properties define the offset in pixels for the perceived center
point of the rotation.
Allowed values are between -inf and inf.
By default these properties are set to \c 0.
\table
\header
\li Output examples with different horizontalOffset values
\li
\li
\row
\li \image RadialBlur_horizontalOffset1.png
\li \image RadialBlur_horizontalOffset2.png
\li \image RadialBlur_horizontalOffset3.png
\row
\li \b { horizontalOffset: 75.0 }
\li \b { horizontalOffset: 0.0 }
\li \b { horizontalOffset: -75.0 }
\row
\li \l samples: 24
\li \l samples: 24
\li \l samples: 24
\row
\li \l angle: 20
\li \l angle: 20
\li \l angle: 20
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\endtable
*/
property real horizontalOffset: 0.0
property real verticalOffset: 0.0
/*!
This property defines the blur behavior near the edges of the item,
where the pixel blurring is affected by the pixels outside the source
edges.
If the property is set to \c true, the pixels outside the source are
interpreted to be transparent, which is similar to OpenGL
clamp-to-border extension. The blur is expanded slightly outside the
effect item area.
If the property is set to \c false, the pixels outside the source are
interpreted to contain the same color as the pixels at the edge of the
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
not expand outside the effect item area.
By default, the property is set to \c false.
*/
property bool transparentBorder: false
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
sourceRect: shaderItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
}
ShaderEffectSource {
id: cacheItem
anchors.fill: shaderItem
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant source: sourceProxy.output
property variant center: Qt.point(0.5 + rootItem.horizontalOffset / parent.width, 0.5 + rootItem.verticalOffset / parent.height)
property bool transparentBorder: rootItem.transparentBorder && rootItem.samples > 1
property int samples: rootItem.samples
property real weight: 1.0 / Math.max(1.0, rootItem.samples)
property real angleSin: Math.sin(rootItem.angle/2 * Math.PI/180)
property real angleCos: Math.cos(rootItem.angle/2 * Math.PI/180)
property real angleSinStep: Math.sin(-rootItem.angle * Math.PI/180 / Math.max(1.0, rootItem.samples - 1))
property real angleCosStep: Math.cos(-rootItem.angle * Math.PI/180 / Math.max(1.0, rootItem.samples - 1))
property variant expandPixels: transparentBorder ? Qt.size(0.5 * parent.height, 0.5 * parent.width) : Qt.size(0,0)
property variant expand: transparentBorder ? Qt.size(expandPixels.width / width, expandPixels.height / height) : Qt.size(0,0)
property variant delta: Qt.size(1.0 / rootItem.width, 1.0 / rootItem.height)
property real w: parent.width
property real h: parent.height
x: transparentBorder ? -expandPixels.width - 1 : 0
y: transparentBorder ? -expandPixels.height - 1 : 0
width: transparentBorder ? parent.width + expandPixels.width * 2.0 + 2 : parent.width
height: transparentBorder ? parent.height + expandPixels.height * 2.0 + 2 : parent.height
property string fragmentShaderSkeleton: "
varying highp vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform highp float angleSin;
uniform highp float angleCos;
uniform highp float angleSinStep;
uniform highp float angleCosStep;
uniform highp float weight;
uniform highp vec2 expand;
uniform highp vec2 center;
uniform highp vec2 delta;
uniform highp float w;
uniform highp float h;
void main(void) {
highp mat2 m;
gl_FragColor = vec4(0.0);
mediump vec2 texCoord = qt_TexCoord0;
PLACEHOLDER_EXPAND_STEPS
highp vec2 dir = vec2(texCoord.s * w - w * center.x, texCoord.t * h - h * center.y);
m[0] = vec2(angleCos, -angleSin);
m[1] = vec2(angleSin, angleCos);
dir *= m;
m[0] = vec2(angleCosStep, -angleSinStep);
m[1] = vec2(angleSinStep, angleCosStep);
PLACEHOLDER_UNROLLED_LOOP
gl_FragColor *= weight * qt_Opacity;
}
"
function buildFragmentShader() {
var shader = fragmentShaderSkeleton
var expandSteps = ""
if (transparentBorder) {
expandSteps += "texCoord = (texCoord - expand) / (1.0 - 2.0 * expand);"
}
var unrolledLoop = "gl_FragColor += texture2D(source, texCoord);\n"
if (rootItem.samples > 1) {
unrolledLoop = ""
for (var i = 0; i < rootItem.samples; i++)
unrolledLoop += "gl_FragColor += texture2D(source, center + dir * delta); dir *= m;\n"
}
shader = shader.replace("PLACEHOLDER_EXPAND_STEPS", expandSteps)
fragmentShader = shader.replace("PLACEHOLDER_UNROLLED_LOOP", unrolledLoop)
}
onFragmentShaderChanged: sourceChanged()
onSamplesChanged: buildFragmentShader()
onTransparentBorderChanged: buildFragmentShader()
Component.onCompleted: buildFragmentShader()
}
}
@@ -1,439 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype RadialGradient
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-gradient
\brief Draws a radial gradient.
A gradient is defined by two or more colors, which are blended seamlessly.
The colors start from the middle of the item and end at the borders.
\table
\header
\li Effect applied
\row
\li \image RadialGradient.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet RadialGradient-example.qml example
*/
Item {
id: rootItem
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
/*!
The HorizontalOffset and verticalOffset properties define the offset in
pixels for the center point of the gradient compared to the item center.
The values range from -inf to inf. By default, these properties are set
to \c 0.
\table
\header
\li Output examples with different horizontalOffset values
\li
\li
\row
\li \image RadialGradient_horizontalOffset1.png
\li \image RadialGradient_horizontalOffset2.png
\li \image RadialGradient_horizontalOffset3.png
\row
\li \b { horizontalOffset: -150 }
\li \b { horizontalOffset: 0 }
\li \b { horizontalOffset: 150 }
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\row
\li \l horizontalRadius: 300
\li \l horizontalRadius: 300
\li \l horizontalRadius: 300
\row
\li \l verticalRadius: 300
\li \l verticalRadius: 300
\li \l verticalRadius: 300
\row
\li \l angle: 0
\li \l angle: 0
\li \l angle: 0
\endtable
*/
property real horizontalOffset: 0.0
property real verticalOffset: 0.0
/*!
The HorizontalRadius and verticalRadius properties define the shape and
size of the radial gradient. If the radiuses are equal, the shape of the
gradient is a circle. If the horizontal and vertical radiuses differ,
the shape is elliptical. The radiuses are given in pixels.
The value ranges from -inf to inf. By default, horizontalRadius is bound
to width and verticalRadius is bound to height.
\table
\header
\li Output examples with different horizontalRadius values
\li
\li
\row
\li \image RadialGradient_horizontalRadius1.png
\li \image RadialGradient_horizontalRadius2.png
\row
\li \b { horizontalRadius: 300 }
\li \b { horizontalRadius: 100 }
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\row
\li \l verticalRadius: 300
\li \l verticalRadius: 300
\row
\li \l angle: 0
\li \l angle: 0
\row
\li \l gradient: QQuickGradient(0xa05fb10)
\li \l gradient: QQuickGradient(0xa05fb10)
\endtable
*/
property real horizontalRadius: width
property real verticalRadius: height
/*!
This property defines the rotation of the gradient around its center
point. The rotation is only visible when the
\l{RadialGradient::horizontalRadius}{horizontalRadius} and
\l{RadialGradient::verticalRadius}{verticalRadius} properties are not
equal. The angle is given in degrees and the default value is \c 0.
\table
\header
\li Output examples with different angle values
\li
\li
\row
\li \image RadialGradient_angle1.png
\li \image RadialGradient_angle2.png
\li \image RadialGradient_angle3.png
\row
\li \b { angle: 0 }
\li \b { angle: 45 }
\li \b { angle: 90 }
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\row
\li \l horizontalRadius: 100
\li \l horizontalRadius: 100
\li \l horizontalRadius: 100
\row
\li \l verticalRadius: 300
\li \l verticalRadius: 300
\li \l verticalRadius: 300
\endtable
*/
property real angle: 0.0
/*!
This property defines the item that is going to be filled with gradient.
Source item gets rendered into an intermediate pixel buffer and the
alpha values from the result are used to determine the gradient's pixels
visibility in the display. The default value for source is undefined and
in that case whole effect area is filled with gradient.
\table
\header
\li Output examples with different source values
\li
\li
\row
\li \image RadialGradient_maskSource1.png
\li \image RadialGradient_maskSource2.png
\row
\li \b { source: undefined }
\li \b { source: Image { source: images/butterfly.png } }
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\row
\li \l horizontalRadius: 300
\li \l horizontalRadius: 300
\row
\li \l verticalRadius: 300
\li \l verticalRadius: 300
\row
\li \l angle: 0
\li \l angle: 0
\endtable
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
A gradient is defined by two or more colors, which are blended
seamlessly. The colors are specified as a set of GradientStop child
items, each of which defines a position on the gradient from 0.0 to 1.0
and a color. The position of each GradientStop is defined by setting the
position property. The color is defined by setting the color property.
\table
\header
\li Output examples with different gradient values
\li
\li
\row
\li \image RadialGradient_gradient1.png
\li \image RadialGradient_gradient2.png
\li \image RadialGradient_gradient3.png
\row
\li \b {gradient:} \code
Gradient {
GradientStop { position: 0.000
color: Qt.rgba(1, 0, 0, 1) }
GradientStop { position: 0.167;
color: Qt.rgba(1, 1, 0, 1) }
GradientStop { position: 0.333;
color: Qt.rgba(0, 1, 0, 1) }
GradientStop { position: 0.500;
color: Qt.rgba(0, 1, 1, 1) }
GradientStop { position: 0.667;
color: Qt.rgba(0, 0, 1, 1) }
GradientStop { position: 0.833;
color: Qt.rgba(1, 0, 1, 1) }
GradientStop { position: 1.000;
color: Qt.rgba(1, 0, 0, 1) }
}
\endcode
\li \b {gradient:} \code
Gradient {
GradientStop { position: 0.0
color: "#F0F0F0"
}
GradientStop { position: 0.5
color: "#000000"
}
GradientStop { position: 1.0
color: "#F0F0F0"
}
}
\endcode
\li \b {gradient:}
\code
Gradient {
GradientStop { position: 0.0
color: "#00000000"
}
GradientStop { position: 1.0
color: "#FF000000"
}
}
\endcode
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\row
\li \l horizontalRadius: 300
\li \l horizontalRadius: 300
\li \l horizontalRadius: 300
\row
\li \l verticalRadius: 300
\li \l verticalRadius: 300
\li \l verticalRadius: 300
\row
\li \l angle: 0
\li \l angle: 0
\li \l angle: 0
\endtable
*/
property Gradient gradient: Gradient {
GradientStop { position: 0.0; color: "white" }
GradientStop { position: 1.0; color: "black" }
}
SourceProxy {
id: maskSourceProxy
input: rootItem.source
}
ShaderEffectSource {
id: gradientSource
sourceItem: Rectangle {
width: 16
height: 256
gradient: rootItem.gradient
smooth: true
}
smooth: true
hideSource: true
visible: false
}
ShaderEffectSource {
id: cacheItem
anchors.fill: parent
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant gradientImage: gradientSource
property variant maskSource: maskSourceProxy.output
property variant center: Qt.point(0.5 + rootItem.horizontalOffset / width, 0.5 + rootItem.verticalOffset / height)
property real horizontalRatio: rootItem.horizontalRadius > 0 ? width / (2 * rootItem.horizontalRadius) : width * 16384
property real verticalRatio: rootItem.verticalRadius > 0 ? height / (2 * rootItem.verticalRadius) : height * 16384
property real angle: -rootItem.angle / 360 * 2 * Math.PI
property variant matrixData: Qt.point(Math.sin(angle), Math.cos(angle))
anchors.fill: parent
vertexShader: "
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
uniform highp mat4 qt_Matrix;
uniform highp vec2 matrixData;
uniform highp float horizontalRatio;
uniform highp float verticalRatio;
uniform highp vec2 center;
varying highp vec2 qt_TexCoord0;
varying highp vec2 qt_TexCoord1;
varying highp vec2 centerPoint;
void main() {
highp vec2 ratio = vec2(horizontalRatio, verticalRatio);
// Rotation matrix
highp mat2 rot = mat2(matrixData.y, -matrixData.x,
matrixData.x, matrixData.y);
qt_TexCoord0 = qt_MultiTexCoord0;
qt_TexCoord1 = qt_MultiTexCoord0;
qt_TexCoord1 -= center;
qt_TexCoord1 *= rot;
qt_TexCoord1 += center;
qt_TexCoord1 *= ratio;
centerPoint = center * ratio;
gl_Position = qt_Matrix * qt_Vertex;
}
"
fragmentShader: maskSource == undefined ? noMaskShader : maskShader
onFragmentShaderChanged: horizontalRatioChanged()
property string maskShader: "
uniform lowp sampler2D gradientImage;
uniform lowp sampler2D maskSource;
uniform lowp float qt_Opacity;
varying highp vec2 qt_TexCoord0;
varying highp vec2 qt_TexCoord1;
varying highp vec2 centerPoint;
void main() {
lowp vec4 gradientColor = texture2D(gradientImage, vec2(0.0, 2.0 * distance(qt_TexCoord1, centerPoint)));
lowp float maskAlpha = texture2D(maskSource, qt_TexCoord0).a;
gl_FragColor = gradientColor * maskAlpha * qt_Opacity;
}
"
property string noMaskShader: "
uniform lowp sampler2D gradientImage;
uniform lowp float qt_Opacity;
varying highp vec2 qt_TexCoord1;
varying highp vec2 centerPoint;
void main() {
lowp vec4 gradientColor = texture2D(gradientImage, vec2(0.0, 2.0 * distance(qt_TexCoord1, centerPoint)));
gl_FragColor = gradientColor * qt_Opacity;
}
"
}
}
@@ -1,288 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype RectangularGlow
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-glow
\brief Generates a blurred and colorized rectangle, which gives
the impression that the source is glowing.
This effect is intended to have good performance. The shape of the glow is
limited to a rectangle with a custom corner radius. For situations where
custom shapes are required, consider \l {QtGraphicalEffects1::Glow} {Glow}
effect.
\table
\header
\li Effect applied
\row
\li \image RectangularGlow_applied.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet RectangularGlow-example.qml example
*/
Item {
id: rootItem
/*!
This property defines how many pixels outside the item area are reached
by the glow.
The value ranges from 0.0 (no glow) to inf (infinite glow). By default,
the property is set to \c 0.0.
\table
\header
\li Output examples with different glowRadius values
\li
\li
\row
\li \image RectangularGlow_glowRadius1.png
\li \image RectangularGlow_glowRadius2.png
\li \image RectangularGlow_glowRadius3.png
\row
\li \b { glowRadius: 10 }
\li \b { glowRadius: 20 }
\li \b { glowRadius: 40 }
\row
\li \l spread: 0
\li \l spread: 0
\li \l spread: 0
\row
\li \l color: #ffffff
\li \l color: #ffffff
\li \l color: #ffffff
\row
\li \l cornerRadius: 25
\li \l cornerRadius: 25
\li \l cornerRadius: 25
\endtable
*/
property real glowRadius: 0.0
/*!
This property defines how large part of the glow color is strenghtened
near the source edges.
The value ranges from 0.0 (no strenght increase) to 1.0 (maximum
strenght increase). By default, the property is set to \c 0.0.
\table
\header
\li Output examples with different spread values
\li
\li
\row
\li \image RectangularGlow_spread1.png
\li \image RectangularGlow_spread2.png
\li \image RectangularGlow_spread3.png
\row
\li \b { spread: 0.0 }
\li \b { spread: 0.5 }
\li \b { spread: 1.0 }
\row
\li \l glowRadius: 20
\li \l glowRadius: 20
\li \l glowRadius: 20
\row
\li \l color: #ffffff
\li \l color: #ffffff
\li \l color: #ffffff
\row
\li \l cornerRadius: 25
\li \l cornerRadius: 25
\li \l cornerRadius: 25
\endtable
*/
property real spread: 0.0
/*!
This property defines the RGBA color value which is used for the glow.
By default, the property is set to \c "white".
\table
\header
\li Output examples with different color values
\li
\li
\row
\li \image RectangularGlow_color1.png
\li \image RectangularGlow_color2.png
\li \image RectangularGlow_color3.png
\row
\li \b { color: #ffffff }
\li \b { color: #55ff55 }
\li \b { color: #5555ff }
\row
\li \l glowRadius: 20
\li \l glowRadius: 20
\li \l glowRadius: 20
\row
\li \l spread: 0
\li \l spread: 0
\li \l spread: 0
\row
\li \l cornerRadius: 25
\li \l cornerRadius: 25
\li \l cornerRadius: 25
\endtable
*/
property color color: "white"
/*!
This property defines the corner radius that is used to draw a glow with
rounded corners.
The value ranges from 0.0 to half of the effective width or height of
the glow, whichever is smaller. This can be calculated with: \c{
min(width, height) / 2.0 + glowRadius}
By default, the property is bound to glowRadius property. The glow
behaves as if the rectangle was blurred when adjusting the glowRadius
property.
\table
\header
\li Output examples with different cornerRadius values
\li
\li
\row
\li \image RectangularGlow_cornerRadius1.png
\li \image RectangularGlow_cornerRadius2.png
\li \image RectangularGlow_cornerRadius3.png
\row
\li \b { cornerRadius: 0 }
\li \b { cornerRadius: 25 }
\li \b { cornerRadius: 50 }
\row
\li \l glowRadius: 20
\li \l glowRadius: 20
\li \l glowRadius: 20
\row
\li \l spread: 0
\li \l spread: 0
\li \l spread: 0
\row
\li \l color: #ffffff
\li \l color: #ffffff
\li \l color: #ffffff
\endtable
*/
property real cornerRadius: glowRadius
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
ShaderEffectSource {
id: cacheItem
anchors.fill: shaderItem
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
x: (parent.width - width) / 2.0
y: (parent.height - height) / 2.0
width: parent.width + rootItem.glowRadius * 2 + cornerRadius * 2
height: parent.height + rootItem.glowRadius * 2 + cornerRadius * 2
function clampedCornerRadius() {
var maxCornerRadius = Math.min(rootItem.width, rootItem.height) / 2 + glowRadius;
return Math.max(0, Math.min(rootItem.cornerRadius, maxCornerRadius))
}
property color color: rootItem.color
property real inverseSpread: 1.0 - rootItem.spread
property real relativeSizeX: ((inverseSpread * inverseSpread) * rootItem.glowRadius + cornerRadius * 2.0) / width
property real relativeSizeY: relativeSizeX * (width / height)
property real spread: rootItem.spread / 2.0
property real cornerRadius: clampedCornerRadius()
fragmentShader: "
uniform highp float qt_Opacity;
uniform mediump float relativeSizeX;
uniform mediump float relativeSizeY;
uniform mediump float spread;
uniform lowp vec4 color;
varying highp vec2 qt_TexCoord0;
highp float linearstep(highp float e0, highp float e1, highp float x) {
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
}
void main() {
lowp float alpha =
smoothstep(0.0, relativeSizeX, 0.5 - abs(0.5 - qt_TexCoord0.x)) *
smoothstep(0.0, relativeSizeY, 0.5 - abs(0.5 - qt_TexCoord0.y));
highp float spreadMultiplier = linearstep(spread, 1.0 - spread, alpha);
gl_FragColor = color * qt_Opacity * spreadMultiplier * spreadMultiplier;
}
"
}
}
@@ -1,350 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype RecursiveBlur
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-blur
\brief Blurs repeatedly, providing a strong blur effect.
The RecursiveBlur effect softens the image by blurring it with an algorithm
that uses a recursive feedback loop to blur the source multiple times. The
effect may give more blurry results than
\l{QtGraphicalEffects1::GaussianBlur}{GaussianBlur} or
\l{QtGraphicalEffects1::FastBlur}{FastBlur}, but the result is produced
asynchronously and takes more time.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_bug.png
\li \image RecursiveBlur_bug.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet RecursiveBlur-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that is going to be blurred.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the distance of neighboring pixels which influence
the blurring of individual pixels. A larger radius provides better
quality, but is slower to render.
\b Note: The radius value in this effect is not intended to be changed
or animated frequently. The correct way to use it is to set the correct
value and keep it unchanged for the whole duration of the iterative blur
sequence.
The value ranges from (no blur) to 16.0 (maximum blur step). By default,
the property is set to \c 0.0 (no blur).
\table
\header
\li Output examples with different radius values
\li
\li
\row
\li \image RecursiveBlur_radius1.png
\li \image RecursiveBlur_radius2.png
\li \image RecursiveBlur_radius3.png
\row
\li \b { radius: 2.5 }
\li \b { radius: 4.5 }
\li \b { radius: 7.5 }
\row
\li \l loops: 20
\li \l loops: 20
\li \l loops: 20
\endtable
*/
property real radius: 0.0
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
/*!
This property defines the blur behavior near the edges of the item,
where the pixel blurring is affected by the pixels outside the source
edges.
If the property is set to \c true, the pixels outside the source are
interpreted to be transparent, which is similar to OpenGL
clamp-to-border extension. The blur is expanded slightly outside the
effect item area.
If the property is set to \c false, the pixels outside the source are
interpreted to contain the same color as the pixels at the edge of the
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
not expand outside the effect item area.
By default, the property is set to \c false.
\table
\header
\li Output examples with different transparentBorder values
\li
\li
\row
\li \image RecursiveBlur_transparentBorder1.png
\li \image RecursiveBlur_transparentBorder2.png
\row
\li \b { transparentBorder: false }
\li \b { transparentBorder: true }
\row
\li \l loops: 20
\li \l loops: 20
\row
\li \l radius: 7.5
\li \l radius: 7.5
\endtable
*/
property bool transparentBorder: false
/*!
This property defines the amount of blur iterations that are going to be
performed for the source. When the property changes, the iterative
blurring process starts. If the value is decreased or if the value
changes from zero to non-zero, a snapshot is taken from the source. The
snapshot is used as a starting point for the process.
The iteration loop tries to run as fast as possible. The speed might be
limited by the VSYNC or the time needed for one blur step, or both.
Sometimes it may be desirable to perform the blurring with a slower
pace. In that case, it may be convenient to control the property with
Animation which increases the value.
The value ranges from 0 to inf. By default, the property is set to \c 0.
\table
\header
\li Output examples with different loops values
\li
\li
\row
\li \image RecursiveBlur_loops1.png
\li \image RecursiveBlur_loops2.png
\li \image RecursiveBlur_loops3.png
\row
\li \b { loops: 4 }
\li \b { loops: 20 }
\li \b { loops: 70 }
\row
\li \l radius: 7.5
\li \l radius: 7.5
\li \l radius: 7.5
\endtable
*/
property int loops: 0
/*!
This property holds the progress of asynchronous source blurring
process, from 0.0 (nothing blurred) to 1.0 (finished).
*/
property real progress: loops > 0.0 ? Math.min(1.0, recursionTimer.counter / loops) : 0.0
onLoopsChanged: recursiveSource.scheduleUpdate()
onSourceChanged: recursionTimer.reset()
onRadiusChanged: recursionTimer.reset()
onTransparentBorderChanged: recursionTimer.reset()
SourceProxy {
id: sourceProxy
input: rootItem.source
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2, parent.height + 2) : Qt.rect(0, 0, 0, 0)
}
ShaderEffectSource {
id: cacheItem
anchors.fill: verticalBlur
smooth: true
visible: rootItem.cached
hideSource: visible
live: true
sourceItem: inputItem.visible ? inputItem : verticalBlur
}
Item {
id: recursionTimer
property int counter: 0
function reset() {
counter = 0
recursiveSource.scheduleUpdate()
}
function nextFrame() {
if (loops < counter)
recursionTimer.counter = 0
if (counter > 0)
recursiveSource.sourceItem = verticalBlur
else
recursiveSource.sourceItem = inputItem
if (counter < loops) {
recursiveSource.scheduleUpdate()
counter++
}
}
}
ShaderEffect {
id: inputItem
property variant source: sourceProxy.output
property real expandX: rootItem.transparentBorder ? (horizontalBlur.maximumRadius) / horizontalBlur.width : 0.0
property real expandY: rootItem.transparentBorder ? (horizontalBlur.maximumRadius) / horizontalBlur.height : 0.0
anchors.fill: verticalBlur
visible: !verticalBlur.visible
vertexShader: "
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
uniform highp mat4 qt_Matrix;
uniform highp float expandX;
uniform highp float expandY;
varying highp vec2 qt_TexCoord0;
void main() {
mediump vec2 texCoord = qt_MultiTexCoord0;
texCoord.s = (texCoord.s - expandX) / (1.0 - 2.0 * expandX);
texCoord.t = (texCoord.t - expandY) / (1.0 - 2.0 * expandY);
qt_TexCoord0 = texCoord;
gl_Position = qt_Matrix * qt_Vertex;
}
"
fragmentShader: "
varying mediump vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
void main() {
gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;
}
"
}
ShaderEffectSource {
id: recursiveSource
visible: false
smooth: true
hideSource: false
live: false
sourceItem: inputItem
recursive: true
onSourceItemChanged: scheduleUpdate()
onScheduledUpdateCompleted: recursionTimer.nextFrame()
}
GaussianDirectionalBlur {
id: verticalBlur
x: rootItem.transparentBorder ? -horizontalBlur.maximumRadius - 1 : 0
y: rootItem.transparentBorder ? -horizontalBlur.maximumRadius - 1 : 0
width: horizontalBlur.width + 2
height: horizontalBlur.height + 2
horizontalStep: 0.0
verticalStep: 1.0 / parent.height
source: ShaderEffectSource {
sourceItem: horizontalBlur
hideSource: true
visible: false
smooth: true
}
deviation: (radius + 1) / 2.3333
radius: rootItem.radius
maximumRadius: Math.ceil(rootItem.radius)
transparentBorder: false
visible: loops > 0
}
GaussianDirectionalBlur {
id: horizontalBlur
width: rootItem.transparentBorder ? parent.width + 2 * maximumRadius + 2 : parent.width
height: rootItem.transparentBorder ? parent.height + 2 * maximumRadius + 2 : parent.height
horizontalStep: 1.0 / parent.width
verticalStep: 0.0
source: recursiveSource
deviation: (radius + 1) / 2.3333
radius: rootItem.radius
maximumRadius: Math.ceil(rootItem.radius)
transparentBorder: false
visible: false
}
}
@@ -1,226 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype ThresholdMask
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-mask
\brief Masks the source item with another item and applies a threshold
value.
The masking behavior can be controlled with the \l threshold value for the
mask pixels.
\table
\header
\li Source
\li MaskSource
\li Effect applied
\row
\li \image Original_bug.png
\li \image ThresholdMask_mask.png
\li \image ThresholdMask_bug.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet ThresholdMask-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that is going to be masked.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the item that is going to be used as the mask.
Mask item gets rendered into an intermediate pixel buffer and the alpha
values from the result are used to determine the source item's pixels
visibility in the display.
\table
\header
\li Original
\li Mask
\li Effect applied
\row
\li \image Original_bug.png
\li \image ThresholdMask_mask.png
\li \image ThresholdMask_bug.png
\endtable
\note It is not supported to let the effect include itself, for
instance by setting maskSource to the effect's parent.
*/
property variant maskSource
/*!
This property defines a threshold value for the mask pixels. The mask
pixels that have an alpha value below this property are used to
completely mask away the corresponding pixels from the source item. The
mask pixels that have a higher alpha value are used to alphablend the
source item to the display.
The value ranges from 0.0 (alpha value 0) to 1.0 (alpha value 255). By
default, the property is set to \c 0.0.
\table
\header
\li Output examples with different threshold values
\li
\li
\row
\li \image ThresholdMask_threshold1.png
\li \image ThresholdMask_threshold2.png
\li \image ThresholdMask_threshold3.png
\row
\li \b { threshold: 0.0 }
\li \b { threshold: 0.5 }
\li \b { threshold: 0.7 }
\row
\li \l spread: 0.2
\li \l spread: 0.2
\li \l spread: 0.2
\endtable
*/
property real threshold: 0.0
/*!
This property defines the smoothness of the mask edges near the
\l{ThresholdMask::threshold}{threshold} alpha value. Setting spread to
0.0 uses mask normally with the specified threshold. Setting higher
spread values softens the transition from the transparent mask pixels
towards opaque mask pixels by adding interpolated values between them.
The value ranges from 0.0 (sharp mask edge) to 1.0 (smooth mask edge).
By default, the property is set to \c 0.0.
\table
\header
\li Output examples with different spread values
\li
\li
\row
\li \image ThresholdMask_spread1.png
\li \image ThresholdMask_spread2.png
\li \image ThresholdMask_spread3.png
\row
\li \b { spread: 0.0 }
\li \b { spread: 0.2 }
\li \b { spread: 0.8 }
\row
\li \l threshold: 0.4
\li \l threshold: 0.4
\li \l threshold: 0.4
\endtable
*/
property real spread: 0.0
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
SourceProxy {
id: maskSourceProxy
input: rootItem.maskSource
}
ShaderEffectSource {
id: cacheItem
anchors.fill: parent
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant source: sourceProxy.output
property variant maskSource: maskSourceProxy.output
property real threshold: rootItem.threshold
property real spread: rootItem.spread
anchors.fill: parent
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform lowp sampler2D maskSource;
uniform highp float threshold;
uniform highp float spread;
void main(void) {
lowp vec4 colorFragment = texture2D(source, qt_TexCoord0.st);
lowp vec4 maskFragment = texture2D(maskSource, qt_TexCoord0.st);
gl_FragColor = colorFragment * smoothstep(threshold * (1.0 + spread) - spread, threshold * (1.0 + spread), maskFragment.a) * qt_Opacity;
}
"
}
}
@@ -1,302 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
import "private"
/*!
\qmltype ZoomBlur
\inqmlmodule QtGraphicalEffects
\since QtGraphicalEffects 1.0
\inherits QtQuick2::Item
\ingroup qtgraphicaleffects-motion-blur
\brief Applies directional blur effect towards source items center point.
Effect creates perceived impression that the source item appears to be
moving towards the center point in Z-direction or that the camera appears
to be zooming rapidly. Other available motion blur effects are
\l{QtGraphicalEffects1::DirectionalBlur}{DirectionalBlur}
and \l{QtGraphicalEffects1::RadialBlur}{RadialBlur}.
\table
\header
\li Source
\li Effect applied
\row
\li \image Original_bug.png
\li \image ZoomBlur_bug.png
\endtable
\section1 Example
The following example shows how to apply the effect.
\snippet ZoomBlur-example.qml example
*/
Item {
id: rootItem
/*!
This property defines the source item that is going to be blurred.
\note It is not supported to let the effect include itself, for
instance by setting source to the effect's parent.
*/
property variant source
/*!
This property defines the maximum perceived amount of movement for each
pixel. The amount is smaller near the center and reaches the specified
value at the edges.
The quality of the blur depends on \l{ZoomBlur::samples}{samples}
property. If length value is large, more samples are needed to keep the
visual quality at high level.
The value ranges from 0.0 to inf. By default the property is set to \c
0.0 (no blur).
\table
\header
\li Output examples with different length values
\li
\li
\row
\li \image ZoomBlur_length1.png
\li \image ZoomBlur_length2.png
\li \image ZoomBlur_length3.png
\row
\li \b { length: 0.0 }
\li \b { length: 32.0 }
\li \b { length: 48.0 }
\row
\li \l samples: 24
\li \l samples: 24
\li \l samples: 24
\row
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\li \l horizontalOffset: 0
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\endtable
*/
property real length: 0.0
/*!
This property defines how many samples are taken per pixel when blur
calculation is done. Larger value produces better quality, but is slower
to render.
This property is not intended to be animated. Changing this property may
cause the underlying OpenGL shaders to be recompiled.
Allowed values are between 0 and inf (practical maximum depends on GPU).
By default the property is set to \c 0 (no samples).
*/
property int samples: 0
/*!
\qmlproperty real QtGraphicalEffects1::ZoomBlur::horizontalOffset
\qmlproperty real QtGraphicalEffects1::ZoomBlur::verticalOffset
These properties define an offset in pixels for the blur direction
center point.
The values range from -inf to inf. By default these properties are set
to \c 0.
\table
\header
\li Output examples with different horizontalOffset values
\li
\li
\row
\li \image ZoomBlur_horizontalOffset1.png
\li \image ZoomBlur_horizontalOffset2.png
\li \image ZoomBlur_horizontalOffset3.png
\row
\li \b { horizontalOffset: 100.0 }
\li \b { horizontalOffset: 0.0 }
\li \b { horizontalOffset: -100.0 }
\row
\li \l samples: 24
\li \l samples: 24
\li \l samples: 24
\row
\li \l length: 32
\li \l length: 32
\li \l length: 32
\row
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\li \l verticalOffset: 0
\endtable
*/
property real horizontalOffset: 0.0
property real verticalOffset: 0.0
/*!
This property defines the blur behavior near the edges of the item,
where the pixel blurring is affected by the pixels outside the source
edges.
If the property is set to \c true, the pixels outside the source are
interpreted to be transparent, which is similar to OpenGL
clamp-to-border extension. The blur is expanded slightly outside the
effect item area.
If the property is set to \c false, the pixels outside the source are
interpreted to contain the same color as the pixels at the edge of the
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
not expand outside the effect item area.
By default, the property is set to \c false.
*/
property bool transparentBorder: false
/*!
This property allows the effect output pixels to be cached in order to
improve the rendering performance.
Every time the source or effect properties are changed, the pixels in
the cache must be updated. Memory consumption is increased, because an
extra buffer of memory is required for storing the effect output.
It is recommended to disable the cache when the source or the effect
properties are animated.
By default, the property is set to \c false.
*/
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
}
ShaderEffectSource {
id: cacheItem
anchors.fill: shaderItem
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant source: sourceProxy.output
property variant center: Qt.point(0.5 + rootItem.horizontalOffset / width, 0.5 + rootItem.verticalOffset / height)
property real len: rootItem.length
property bool transparentBorder: rootItem.transparentBorder
property real samples: rootItem.samples
property real weight: 1.0 / Math.max(1.0, rootItem.samples)
property variant expandPixels: transparentBorder ? Qt.size(rootItem.samples, rootItem.samples) : Qt.size(0,0)
property variant expand: transparentBorder ? Qt.size(expandPixels.width / width, expandPixels.height / height) : Qt.size(0,0)
property variant delta: Qt.size(1.0 / rootItem.width, 1.0 / rootItem.height)
x: transparentBorder ? -expandPixels.width - 1 : 0
y: transparentBorder ? -expandPixels.height - 1 : 0
width: transparentBorder ? parent.width + 2.0 * expandPixels.width + 2 : parent.width
height: transparentBorder ? parent.height + 2.0 * expandPixels.height + 2 : parent.height
property string fragmentShaderSkeleton: "
varying highp vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform highp float len;
uniform highp float weight;
uniform highp float samples;
uniform highp vec2 center;
uniform highp vec2 expand;
uniform highp vec2 delta;
void main(void) {
mediump vec2 texCoord = qt_TexCoord0;
mediump vec2 centerCoord = center;
PLACEHOLDER_EXPAND_STEPS
highp vec2 dir = vec2(centerCoord.x - texCoord.s, centerCoord.y - texCoord.t);
dir /= max(1.0, length(dir) * 2.0);
highp vec2 shift = delta * len * dir * 2.0 / max(1.0, samples - 1.0);
gl_FragColor = vec4(0.0);
PLACEHOLDER_UNROLLED_LOOP
gl_FragColor *= weight * qt_Opacity;
}
"
function buildFragmentShader() {
var shader = fragmentShaderSkeleton
var expandSteps = ""
if (transparentBorder) {
expandSteps += "centerCoord = (centerCoord - expand) / (1.0 - 2.0 * expand);"
expandSteps += "texCoord = (texCoord - expand) / (1.0 - 2.0 * expand);"
}
var unrolledLoop = "gl_FragColor += texture2D(source, texCoord);\n"
if (rootItem.samples > 1) {
unrolledLoop = ""
for (var i = 0; i < rootItem.samples; i++)
unrolledLoop += "gl_FragColor += texture2D(source, texCoord); texCoord += shift;\n"
}
shader = shader.replace("PLACEHOLDER_EXPAND_STEPS", expandSteps)
fragmentShader = shader.replace("PLACEHOLDER_UNROLLED_LOOP", unrolledLoop)
}
onFragmentShaderChanged: sourceChanged()
onSamplesChanged: buildFragmentShader()
onTransparentBorderChanged: buildFragmentShader()
Component.onCompleted: buildFragmentShader()
}
}
@@ -1,393 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
Item {
id: rootItem
property variant source
property real spread: 0.0
property real blur: 0.0
property color color: "white"
property bool transparentBorder: false
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
ShaderEffectSource {
id: cacheItem
anchors.fill: shaderItem
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
property string __internalBlurVertexShader: "
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
uniform highp mat4 qt_Matrix;
uniform highp float yStep;
uniform highp float xStep;
varying highp vec2 qt_TexCoord0;
varying highp vec2 qt_TexCoord1;
varying highp vec2 qt_TexCoord2;
varying highp vec2 qt_TexCoord3;
void main() {
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
gl_Position = qt_Matrix * qt_Vertex;
}
"
property string __internalBlurFragmentShader: "
uniform lowp sampler2D source;
uniform lowp float qt_Opacity;
varying highp vec2 qt_TexCoord0;
varying highp vec2 qt_TexCoord1;
varying highp vec2 qt_TexCoord2;
varying highp vec2 qt_TexCoord3;
void main() {
highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) +
texture2D(source, qt_TexCoord1) +
texture2D(source, qt_TexCoord2) +
texture2D(source, qt_TexCoord3)) * 0.25;
gl_FragColor = sourceColor * qt_Opacity;
}
"
ShaderEffect {
id: level0
property variant source: sourceProxy.output
anchors.fill: parent
visible: false
smooth: true
}
ShaderEffectSource {
id: level1
width: Math.ceil(shaderItem.width / 32) * 32
height: Math.ceil(shaderItem.height / 32) * 32
sourceItem: level0
hideSource: rootItem.visible
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0,0,0,0)
smooth: true
visible: false
}
ShaderEffect {
id: effect1
property variant source: level1
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level2
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level2
width: level1.width / 2
height: level1.height / 2
sourceItem: effect1
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect2
property variant source: level2
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level3
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level3
width: level2.width / 2
height: level2.height / 2
sourceItem: effect2
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect3
property variant source: level3
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level4
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level4
width: level3.width / 2
height: level3.height / 2
sourceItem: effect3
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect4
property variant source: level4
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level5
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level5
width: level4.width / 2
height: level4.height / 2
sourceItem: effect4
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect5
property variant source: level5
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level6
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level6
width: level5.width / 2
height: level5.height / 2
sourceItem: effect5
hideSource: rootItem.visible
visible: false
smooth: true
}
Item {
id: dummysource
width: 1
height: 1
visible: false
}
ShaderEffectSource {
id: dummy
width: 1
height: 1
sourceItem: dummysource
visible: false
smooth: false
live: false
}
ShaderEffect {
id: shaderItem
x: transparentBorder ? -64 : 0
y: transparentBorder ? -64 : 0
width: transparentBorder ? parent.width + 128 : parent.width
height: transparentBorder ? parent.height + 128 : parent.height
property variant source1: level1
property variant source2: level2
property variant source3: level3
property variant source4: level4
property variant source5: level5
property variant source6: level6
property real lod: rootItem.blur
property real weight1;
property real weight2;
property real weight3;
property real weight4;
property real weight5;
property real weight6;
property real spread: 1.0 - (rootItem.spread * 0.98)
property alias color: rootItem.color
function weight(v) {
if (v <= 0.0)
return 1
if (v >= 0.5)
return 0
return 1.0 - v / 0.5
}
function calculateWeights() {
var w1 = weight(Math.abs(lod - 0.100))
var w2 = weight(Math.abs(lod - 0.300))
var w3 = weight(Math.abs(lod - 0.500))
var w4 = weight(Math.abs(lod - 0.700))
var w5 = weight(Math.abs(lod - 0.900))
var w6 = weight(Math.abs(lod - 1.100))
var sum = w1 + w2 + w3 + w4 + w5 + w6;
weight1 = w1 / sum;
weight2 = w2 / sum;
weight3 = w3 / sum;
weight4 = w4 / sum;
weight5 = w5 / sum;
weight6 = w6 / sum;
upateSources()
}
function upateSources() {
var sources = new Array();
var weights = new Array();
if (weight1 > 0) {
sources.push(level1)
weights.push(weight1)
}
if (weight2 > 0) {
sources.push(level2)
weights.push(weight2)
}
if (weight3 > 0) {
sources.push(level3)
weights.push(weight3)
}
if (weight4 > 0) {
sources.push(level4)
weights.push(weight4)
}
if (weight5 > 0) {
sources.push(level5)
weights.push(weight5)
}
if (weight6 > 0) {
sources.push(level6)
weights.push(weight6)
}
for (var j = sources.length; j < 6; j++) {
sources.push(dummy)
weights.push(0.0)
}
source1 = sources[0]
source2 = sources[1]
source3 = sources[2]
source4 = sources[3]
source5 = sources[4]
source6 = sources[5]
weight1 = weights[0]
weight2 = weights[1]
weight3 = weights[2]
weight4 = weights[3]
weight5 = weights[4]
weight6 = weights[5]
}
Component.onCompleted: calculateWeights()
onLodChanged: calculateWeights()
fragmentShader: "
uniform lowp sampler2D source1;
uniform lowp sampler2D source2;
uniform lowp sampler2D source3;
uniform lowp sampler2D source4;
uniform lowp sampler2D source5;
uniform mediump float weight1;
uniform mediump float weight2;
uniform mediump float weight3;
uniform mediump float weight4;
uniform mediump float weight5;
uniform highp vec4 color;
uniform highp float spread;
uniform lowp float qt_Opacity;
varying mediump vec2 qt_TexCoord0;
highp float linearstep(highp float e0, highp float e1, highp float x) {
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
}
void main() {
lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1;
sourceColor += texture2D(source2, qt_TexCoord0) * weight2;
sourceColor += texture2D(source3, qt_TexCoord0) * weight3;
sourceColor += texture2D(source4, qt_TexCoord0) * weight4;
sourceColor += texture2D(source5, qt_TexCoord0) * weight5;
sourceColor = mix(vec4(0), color, linearstep(0.0, spread, sourceColor.a));
gl_FragColor = sourceColor * qt_Opacity;
}
"
}
}
@@ -1,413 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
Item {
id: rootItem
property variant source
property real blur: 0.0
property real horizontalOffset: 0
property real verticalOffset: 0
property real spread: 0.0
property color color: "black"
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
ShaderEffectSource {
id: cacheItem
anchors.fill: shaderItem
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
property string __internalBlurVertexShader: "
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
uniform highp mat4 qt_Matrix;
uniform highp float yStep;
uniform highp float xStep;
varying highp vec2 qt_TexCoord0;
varying highp vec2 qt_TexCoord1;
varying highp vec2 qt_TexCoord2;
varying highp vec2 qt_TexCoord3;
void main() {
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
gl_Position = qt_Matrix * qt_Vertex;
}
"
property string __internalBlurFragmentShader: "
uniform lowp sampler2D source;
uniform lowp float qt_Opacity;
varying highp vec2 qt_TexCoord0;
varying highp vec2 qt_TexCoord1;
varying highp vec2 qt_TexCoord2;
varying highp vec2 qt_TexCoord3;
void main() {
highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) +
texture2D(source, qt_TexCoord1) +
texture2D(source, qt_TexCoord2) +
texture2D(source, qt_TexCoord3)) * 0.25;
gl_FragColor = sourceColor * qt_Opacity;
}
"
ShaderEffect {
id: level0
property variant source: sourceProxy.output
property real horizontalOffset: rootItem.horizontalOffset / rootItem.width
property real verticalOffset: rootItem.verticalOffset / rootItem.width
property color color: rootItem.color
anchors.fill: parent
visible: false
smooth: true
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform lowp float qt_Opacity;
uniform highp sampler2D source;
uniform lowp vec4 color;
uniform highp float horizontalOffset;
uniform highp float verticalOffset;
void main(void) {
highp vec2 pos = qt_TexCoord0 - vec2(horizontalOffset, verticalOffset);
lowp float ea = step(0.0, pos.x) * step(0.0, pos.y) * step(pos.x, 1.0) * step(pos.y, 1.0);
lowp float eb = 1.0 - ea;
gl_FragColor = (eb * color + ea * color * (1.0 - texture2D(source, pos).a)) * qt_Opacity;
}
"
}
ShaderEffectSource {
id: level1
width: Math.ceil(shaderItem.width / 32) * 32
height: Math.ceil(shaderItem.height / 32) * 32
sourceItem: level0
hideSource: rootItem.visible
smooth: true
visible: false
}
ShaderEffect {
id: effect1
property variant source: level1
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level2
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level2
width: level1.width / 2
height: level1.height / 2
sourceItem: effect1
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect2
property variant source: level2
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level3
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level3
width: level2.width / 2
height: level2.height / 2
sourceItem: effect2
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect3
property variant source: level3
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level4
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level4
width: level3.width / 2
height: level3.height / 2
sourceItem: effect3
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect4
property variant source: level4
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level5
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level5
width: level4.width / 2
height: level4.height / 2
sourceItem: effect4
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect5
property variant source: level5
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level6
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level6
width: level5.width / 2
height: level5.height / 2
sourceItem: effect5
hideSource: rootItem.visible
visible: false
smooth: true
}
Item {
id: dummysource
width: 1
height: 1
visible: false
}
ShaderEffectSource {
id: dummy
width: 1
height: 1
sourceItem: dummysource
visible: false
smooth: false
live: false
}
ShaderEffect {
id: shaderItem
width: parent.width
height: parent.height
property variant original: sourceProxy.output
property variant source1: level1
property variant source2: level2
property variant source3: level3
property variant source4: level4
property variant source5: level5
property variant source6: level6
property real lod: rootItem.blur
property real weight1;
property real weight2;
property real weight3;
property real weight4;
property real weight5;
property real weight6;
property real spread: 1.0 - (rootItem.spread * 0.98)
property color color: rootItem.color
function weight(v) {
if (v <= 0.0)
return 1
if (v >= 0.5)
return 0
return 1.0 - v / 0.5
}
function calculateWeights() {
var w1 = weight(Math.abs(lod - 0.100))
var w2 = weight(Math.abs(lod - 0.300))
var w3 = weight(Math.abs(lod - 0.500))
var w4 = weight(Math.abs(lod - 0.700))
var w5 = weight(Math.abs(lod - 0.900))
var w6 = weight(Math.abs(lod - 1.100))
var sum = w1 + w2 + w3 + w4 + w5 + w6;
weight1 = w1 / sum;
weight2 = w2 / sum;
weight3 = w3 / sum;
weight4 = w4 / sum;
weight5 = w5 / sum;
weight6 = w6 / sum;
upateSources()
}
function upateSources() {
var sources = new Array();
var weights = new Array();
if (weight1 > 0) {
sources.push(level1)
weights.push(weight1)
}
if (weight2 > 0) {
sources.push(level2)
weights.push(weight2)
}
if (weight3 > 0) {
sources.push(level3)
weights.push(weight3)
}
if (weight4 > 0) {
sources.push(level4)
weights.push(weight4)
}
if (weight5 > 0) {
sources.push(level5)
weights.push(weight5)
}
if (weight6 > 0) {
sources.push(level6)
weights.push(weight6)
}
for (var j = sources.length; j < 6; j++) {
sources.push(dummy)
weights.push(0.0)
}
source1 = sources[0]
source2 = sources[1]
source3 = sources[2]
source4 = sources[3]
source5 = sources[4]
source6 = sources[5]
weight1 = weights[0]
weight2 = weights[1]
weight3 = weights[2]
weight4 = weights[3]
weight5 = weights[4]
weight6 = weights[5]
}
Component.onCompleted: calculateWeights()
onLodChanged: calculateWeights()
fragmentShader: "
uniform lowp sampler2D original;
uniform lowp sampler2D source1;
uniform lowp sampler2D source2;
uniform lowp sampler2D source3;
uniform lowp sampler2D source4;
uniform lowp sampler2D source5;
uniform mediump float weight1;
uniform mediump float weight2;
uniform mediump float weight3;
uniform mediump float weight4;
uniform mediump float weight5;
uniform highp vec4 color;
uniform highp float spread;
uniform lowp float qt_Opacity;
varying mediump vec2 qt_TexCoord0;
highp float linearstep(highp float e0, highp float e1, highp float x) {
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
}
void main() {
lowp vec4 shadowColor = texture2D(source1, qt_TexCoord0) * weight1;
shadowColor += texture2D(source2, qt_TexCoord0) * weight2;
shadowColor += texture2D(source3, qt_TexCoord0) * weight3;
shadowColor += texture2D(source4, qt_TexCoord0) * weight4;
shadowColor += texture2D(source5, qt_TexCoord0) * weight5;
lowp vec4 originalColor = texture2D(original, qt_TexCoord0);
shadowColor.rgb = mix(originalColor.rgb, color.rgb * originalColor.a, linearstep(0.0, spread, shadowColor.a));
gl_FragColor = vec4(shadowColor.rgb, originalColor.a) * originalColor.a * qt_Opacity;
}
"
}
}
@@ -1,332 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
Item {
id: rootItem
property variant source
property variant maskSource
property real blur: 0.0
property bool transparentBorder: false
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
SourceProxy {
id: maskSourceProxy
input: rootItem.maskSource
}
ShaderEffectSource {
id: cacheItem
anchors.fill: shaderItem
visible: rootItem.cached
sourceItem: shaderItem
live: true
hideSource: visible
smooth: rootItem.blur > 0
}
property string __internalBlurVertexShader: "
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
uniform highp mat4 qt_Matrix;
uniform highp float yStep;
uniform highp float xStep;
varying highp vec2 qt_TexCoord0;
varying highp vec2 qt_TexCoord1;
varying highp vec2 qt_TexCoord2;
varying highp vec2 qt_TexCoord3;
void main() {
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
gl_Position = qt_Matrix * qt_Vertex;
}
"
property string __internalBlurFragmentShader: "
uniform lowp sampler2D source;
uniform lowp float qt_Opacity;
varying highp vec2 qt_TexCoord0;
varying highp vec2 qt_TexCoord1;
varying highp vec2 qt_TexCoord2;
varying highp vec2 qt_TexCoord3;
void main() {
highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) +
texture2D(source, qt_TexCoord1) +
texture2D(source, qt_TexCoord2) +
texture2D(source, qt_TexCoord3)) * 0.25;
gl_FragColor = sourceColor * qt_Opacity;
}
"
ShaderEffect {
id: mask0
property variant source: maskSourceProxy.output
anchors.fill: parent
visible: false
smooth: true
}
ShaderEffectSource {
id: masklevel1
width: Math.ceil(shaderItem.width / 32) * 32
height: Math.ceil(shaderItem.height / 32) * 32
sourceItem: mask0
hideSource: rootItem.visible
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0, 0, 0, 0)
visible: false
smooth: rootItem.blur > 0
}
ShaderEffect {
id: level0
property variant source: sourceProxy.output
anchors.fill: parent
visible: false
smooth: true
}
ShaderEffectSource {
id: level1
width: Math.ceil(shaderItem.width / 32) * 32
height: Math.ceil(shaderItem.height / 32) * 32
sourceItem: level0
hideSource: rootItem.visible
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0, 0, 0, 0)
visible: false
smooth: rootItem.blur > 0
}
ShaderEffect {
id: effect1
property variant source: level1
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level2
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level2
width: level1.width / 2
height: level1.height / 2
sourceItem: effect1
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect2
property variant source: level2
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level3
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level3
width: level2.width / 2
height: level2.height / 2
sourceItem: effect2
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect3
property variant source: level3
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level4
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level4
width: level3.width / 2
height: level3.height / 2
sourceItem: effect3
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect4
property variant source: level4
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level5
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level5
width: level4.width / 2
height: level4.height / 2
sourceItem: effect4
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect5
property variant source: level5
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level6
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level6
width: level5.width / 2
height: level5.height / 2
sourceItem: effect5
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: shaderItem
property variant mask: masklevel1
property variant source1: level1
property variant source2: level2
property variant source3: level3
property variant source4: level4
property variant source5: level5
property variant source6: level6
property real lod: Math.sqrt(rootItem.blur) * 1.2 - 0.2
property real weight1
property real weight2
property real weight3
property real weight4
property real weight5
property real weight6
x: transparentBorder ? -64 : 0
y: transparentBorder ? -64 : 0
width: transparentBorder ? parent.width + 128 : parent.width
height: transparentBorder ? parent.height + 128 : parent.height
fragmentShader: "
uniform lowp sampler2D mask;
uniform lowp sampler2D source1;
uniform lowp sampler2D source2;
uniform lowp sampler2D source3;
uniform lowp sampler2D source4;
uniform lowp sampler2D source5;
uniform lowp sampler2D source6;
uniform lowp float lod;
uniform lowp float qt_Opacity;
varying mediump vec2 qt_TexCoord0;
mediump float weight(mediump float v) {
if (v <= 0.0)
return 1.0;
if (v >= 0.5)
return 0.0;
return 1.0 - v * 2.0;
}
void main() {
lowp vec4 maskColor = texture2D(mask, qt_TexCoord0);
mediump float l = lod * maskColor.a;
mediump float w1 = weight(abs(l - 0.100));
mediump float w2 = weight(abs(l - 0.300));
mediump float w3 = weight(abs(l - 0.500));
mediump float w4 = weight(abs(l - 0.700));
mediump float w5 = weight(abs(l - 0.900));
mediump float w6 = weight(abs(l - 1.100));
mediump float sum = w1 + w2 + w3 + w4 + w5 + w6;
mediump float weight1 = w1 / sum;
mediump float weight2 = w2 / sum;
mediump float weight3 = w3 / sum;
mediump float weight4 = w4 / sum;
mediump float weight5 = w5 / sum;
mediump float weight6 = w6 / sum;
lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1;
sourceColor += texture2D(source2, qt_TexCoord0) * weight2;
sourceColor += texture2D(source3, qt_TexCoord0) * weight3;
sourceColor += texture2D(source4, qt_TexCoord0) * weight4;
sourceColor += texture2D(source5, qt_TexCoord0) * weight5;
sourceColor += texture2D(source6, qt_TexCoord0) * weight6;
gl_FragColor = sourceColor * qt_Opacity;
}
"
}
}
@@ -1,286 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
Item {
id: rootItem
property variant source
property real deviation: (radius + 1) / 3.3333
property real radius: 0.0
property int maximumRadius: 0
property real horizontalStep: 0.0
property real verticalStep: 0.0
property bool transparentBorder: false
property bool cached: false
property bool enableColor: false
property color color: "white"
property real spread: 0.0
property bool enableMask: false
property variant maskSource
SourceProxy {
id: sourceProxy
input: rootItem.source
}
SourceProxy {
id: maskSourceProxy
input: rootItem.maskSource
}
ShaderEffectSource {
id: cacheItem
anchors.fill: rootItem
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect {
id: shaderItem
property variant source: sourceProxy.output
property real deviation: Math.max(0.1, rootItem.deviation)
property real radius: rootItem.radius
property int maxRadius: rootItem.maximumRadius
property bool transparentBorder: rootItem.transparentBorder
property real gaussianSum: 0.0
property real startIndex: 0.0
property real deltaFactor: (2 * radius - 1) / (maxRadius * 2 - 1)
property real expandX: transparentBorder && rootItem.horizontalStep > 0 ? maxRadius / width : 0.0
property real expandY: transparentBorder && rootItem.verticalStep > 0 ? maxRadius / height : 0.0
property variant gwts: []
property variant delta: Qt.vector3d(rootItem.horizontalStep * deltaFactor, rootItem.verticalStep * deltaFactor, startIndex);
property variant factor_0_2: Qt.vector3d(gwts[0], gwts[1], gwts[2]);
property variant factor_3_5: Qt.vector3d(gwts[3], gwts[4], gwts[5]);
property variant factor_6_8: Qt.vector3d(gwts[6], gwts[7], gwts[8]);
property variant factor_9_11: Qt.vector3d(gwts[9], gwts[10], gwts[11]);
property variant factor_12_14: Qt.vector3d(gwts[12], gwts[13], gwts[14]);
property variant factor_15_17: Qt.vector3d(gwts[15], gwts[16], gwts[17]);
property variant factor_18_20: Qt.vector3d(gwts[18], gwts[19], gwts[20]);
property variant factor_21_23: Qt.vector3d(gwts[21], gwts[22], gwts[23]);
property variant factor_24_26: Qt.vector3d(gwts[24], gwts[25], gwts[26]);
property variant factor_27_29: Qt.vector3d(gwts[27], gwts[28], gwts[29]);
property variant factor_30_31: Qt.point(gwts[30], gwts[31]);
property color color: rootItem.color
property real spread: 1.0 - (rootItem.spread * 0.98)
property variant maskSource: maskSourceProxy.output
anchors.fill: rootItem
function gausFunc(x){
//Gaussian function = h(x):=(1/sqrt(2*3.14159*(D^2))) * %e^(-(x^2)/(2*(D^2)));
return (1.0 / Math.sqrt(2 * Math.PI * (Math.pow(shaderItem.deviation, 2)))) * Math.pow(Math.E, -((Math.pow(x, 2)) / (2 * (Math.pow(shaderItem.deviation, 2)))));
}
function updateGaussianWeights() {
gaussianSum = 0.0;
startIndex = -maxRadius + 0.5
var n = new Array(32);
for (var j = 0; j < 32; j++)
n[j] = 0;
var max = maxRadius * 2
var delta = (2 * radius - 1) / (max - 1);
for (var i = 0; i < max; i++) {
n[i] = gausFunc(-radius + 0.5 + i * delta);
gaussianSum += n[i];
}
gwts = n;
}
function buildFragmentShader() {
var shaderSteps = [
"gl_FragColor += texture2D(source, texCoord) * factor_0_2.x; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_0_2.y; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_0_2.z; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_3_5.x; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_3_5.y; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_3_5.z; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_6_8.x; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_6_8.y; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_6_8.z; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_9_11.x; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_9_11.y; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_9_11.z; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_12_14.x; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_12_14.y; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_12_14.z; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_15_17.x; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_15_17.y; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_15_17.z; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_18_20.x; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_18_20.y; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_18_20.z; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_21_23.x; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_21_23.y; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_21_23.z; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_24_26.x; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_24_26.y; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_24_26.z; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_27_29.x; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_27_29.y; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_27_29.z; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_30_31.x; texCoord += shift;",
"gl_FragColor += texture2D(source, texCoord) * factor_30_31.y; texCoord += shift;"
]
var shader = fragmentShaderBegin
var samples = maxRadius * 2
if (samples > 32) {
console.log("DirectionalGaussianBlur.qml WARNING: Maximum of blur radius (16) exceeded!")
samples = 32
}
for (var i = 0; i < samples; i++) {
shader += shaderSteps[i]
}
shader += fragmentShaderEnd
var colorizeSteps = ""
var colorizeUniforms = ""
var maskSteps = ""
var maskUniforms = ""
if (enableColor) {
colorizeSteps += "gl_FragColor = mix(vec4(0), color, clamp((gl_FragColor.a - 0.0) / (spread - 0.0), 0.0, 1.0));\n"
colorizeUniforms += "uniform highp vec4 color;\n"
colorizeUniforms += "uniform highp float spread;\n"
}
if (enableMask) {
maskSteps += "shift *= texture2D(maskSource, qt_TexCoord0).a;\n"
maskUniforms += "uniform sampler2D maskSource;\n"
}
shader = shader.replace("PLACEHOLDER_COLORIZE_STEPS", colorizeSteps)
shader = shader.replace("PLACEHOLDER_COLORIZE_UNIFORMS", colorizeUniforms)
shader = shader.replace("PLACEHOLDER_MASK_STEPS", maskSteps)
shader = shader.replace("PLACEHOLDER_MASK_UNIFORMS", maskUniforms)
fragmentShader = shader
}
onDeviationChanged: updateGaussianWeights()
onRadiusChanged: updateGaussianWeights()
onTransparentBorderChanged: {
buildFragmentShader()
updateGaussianWeights()
}
onMaxRadiusChanged: {
buildFragmentShader()
updateGaussianWeights()
}
Component.onCompleted: {
buildFragmentShader()
updateGaussianWeights()
}
property string fragmentShaderBegin: "
varying mediump vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform highp vec3 delta;
uniform highp vec3 factor_0_2;
uniform highp vec3 factor_3_5;
uniform highp vec3 factor_6_8;
uniform highp vec3 factor_9_11;
uniform highp vec3 factor_12_14;
uniform highp vec3 factor_15_17;
uniform highp vec3 factor_18_20;
uniform highp vec3 factor_21_23;
uniform highp vec3 factor_24_26;
uniform highp vec3 factor_27_29;
uniform highp vec3 factor_30_31;
uniform highp float gaussianSum;
uniform highp float expandX;
uniform highp float expandY;
PLACEHOLDER_MASK_UNIFORMS
PLACEHOLDER_COLORIZE_UNIFORMS
void main() {
highp vec2 shift = vec2(delta.x, delta.y);
PLACEHOLDER_MASK_STEPS
highp float index = delta.z;
mediump vec2 texCoord = qt_TexCoord0;
texCoord.s = (texCoord.s - expandX) / (1.0 - 2.0 * expandX);
texCoord.t = (texCoord.t - expandY) / (1.0 - 2.0 * expandY);
texCoord += (shift * index);
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
"
property string fragmentShaderEnd: "
gl_FragColor /= gaussianSum;
PLACEHOLDER_COLORIZE_STEPS
gl_FragColor *= qt_Opacity;
}
"
}
}
@@ -1,98 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
Item {
id: rootItem
property variant source
property real radius: 0.0
property int maximumRadius: 0
property real spread: 0.0
property color color: "white"
property bool cached: false
property bool transparentBorder: false
SourceProxy {
id: sourceProxy
input: rootItem.source
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
}
ShaderEffectSource {
id: cacheItem
anchors.fill: shaderItem
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
GaussianDirectionalBlur {
id: shaderItem
x: transparentBorder ? -maximumRadius - 1 : 0
y: transparentBorder ? -maximumRadius - 1 : 0
width: horizontalBlur.width
height: horizontalBlur.height
horizontalStep: 0.0
verticalStep: 1.0 / parent.height
source: horizontalBlur
radius: rootItem.radius
maximumRadius: rootItem.maximumRadius
transparentBorder: rootItem.transparentBorder
enableColor: true
color: rootItem.color
spread: rootItem.spread
}
GaussianDirectionalBlur {
id: horizontalBlur
width: transparentBorder ? parent.width + 2 * maximumRadius + 2 : parent.width
height: transparentBorder ? parent.height + 2 * maximumRadius + 2 : parent.height
horizontalStep: 1.0 / parent.width
verticalStep: 0.0
source: sourceProxy.output
radius: rootItem.radius
maximumRadius: rootItem.maximumRadius
transparentBorder: rootItem.transparentBorder
visible: false
}
}
@@ -1,155 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
Item {
id: rootItem
property variant source
property real radius: 0.0
property int maximumRadius: 0
property real horizontalOffset: 0
property real verticalOffset: 0
property real spread: 0
property color color: "black"
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
ShaderEffectSource {
id: cacheItem
anchors.fill: shaderItem
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
ShaderEffect{
id: shadowItem
anchors.fill: parent
property variant original: sourceProxy.output
property color color: rootItem.color
property real horizontalOffset: rootItem.horizontalOffset / rootItem.width
property real verticalOffset: rootItem.verticalOffset / rootItem.height
visible: false
fragmentShader: "
uniform highp sampler2D original;
uniform lowp float qt_Opacity;
uniform lowp vec4 color;
uniform highp float horizontalOffset;
uniform highp float verticalOffset;
varying highp vec2 qt_TexCoord0;
void main(void) {
highp vec2 pos = qt_TexCoord0 - vec2(horizontalOffset, verticalOffset);
lowp float ea = step(0.0, pos.x) * step(0.0, pos.y) * step(pos.x, 1.0) * step(pos.y, 1.0);
lowp float eb = 1.0 - ea;
gl_FragColor = eb * color + ea * color * (1.0 - texture2D(original, pos).a) * qt_Opacity;
}
"
}
GaussianDirectionalBlur {
id: blurItem
anchors.fill: parent
horizontalStep: 0.0
verticalStep: 1.0 / parent.height
source: horizontalBlur
radius: rootItem.radius
maximumRadius: rootItem.maximumRadius
visible: false
}
GaussianDirectionalBlur {
id: horizontalBlur
width: transparentBorder ? parent.width + 2 * maximumRadius : parent.width
height: parent.height
horizontalStep: 1.0 / parent.width
verticalStep: 0.0
source: shadowItem
radius: rootItem.radius
maximumRadius: rootItem.maximumRadius
visible: false
}
ShaderEffectSource {
id: blurredSource
sourceItem: blurItem
live: true
smooth: true
}
ShaderEffect {
id: shaderItem
anchors.fill: parent
property variant original: sourceProxy.output
property variant shadow: blurredSource
property real spread: 1.0 - (rootItem.spread * 0.98)
property color color: rootItem.color
fragmentShader: "
uniform highp sampler2D original;
uniform highp sampler2D shadow;
uniform lowp float qt_Opacity;
uniform highp float spread;
uniform lowp vec4 color;
varying highp vec2 qt_TexCoord0;
highp float linearstep(highp float e0, highp float e1, highp float x) {
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
}
void main(void) {
lowp vec4 originalColor = texture2D(original, qt_TexCoord0);
lowp vec4 shadowColor = texture2D(shadow, qt_TexCoord0);
shadowColor.rgb = mix(originalColor.rgb, color.rgb * originalColor.a, linearstep(0.0, spread, shadowColor.a));
gl_FragColor = vec4(shadowColor.rgb, originalColor.a) * originalColor.a * qt_Opacity;
}
"
}
}
@@ -1,104 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
Item {
id: rootItem
property variant source
property variant maskSource
property real radius: 0.0
property int maximumRadius: 0
property bool cached: false
property bool transparentBorder: false
SourceProxy {
id: sourceProxy
input: rootItem.source
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
}
SourceProxy {
id: maskSourceProxy
input: rootItem.maskSource
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
}
ShaderEffectSource {
id: cacheItem
anchors.fill: blur
visible: rootItem.cached
smooth: true
sourceItem: blur
live: true
hideSource: visible
}
GaussianDirectionalBlur {
id: blur
x: transparentBorder ? -maximumRadius - 1: 0
y: transparentBorder ? -maximumRadius - 1: 0
width: horizontalBlur.width
height: horizontalBlur.height
horizontalStep: 0.0
verticalStep: 1.0 / parent.height
source: horizontalBlur
enableMask: true
maskSource: maskSourceProxy.output
radius: rootItem.radius
maximumRadius: rootItem.maximumRadius
transparentBorder: rootItem.transparentBorder
}
GaussianDirectionalBlur {
id: horizontalBlur
width: transparentBorder ? parent.width + 2 * maximumRadius + 2 : parent.width
height: transparentBorder ? parent.height + 2 * maximumRadius + 2 : parent.height
horizontalStep: 1.0 / parent.width
verticalStep: 0.0
source: sourceProxy.output
enableMask: true
maskSource: maskSourceProxy.output
radius: rootItem.radius
maximumRadius: rootItem.maximumRadius
transparentBorder: rootItem.transparentBorder
visible: false
}
}
@@ -1,136 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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.0
Item {
id: rootItem
property variant input
property variant output
property variant sourceRect
visible: false
Component.onCompleted: evaluateInput()
onInputChanged: evaluateInput()
onSourceRectChanged: evaluateInput()
function evaluateInput() {
if (input == undefined) {
output = input
}
else if (sourceRect != undefined && sourceRect != Qt.rect(0, 0, 0, 0) && !isQQuickShaderEffectSource(input)) {
proxySource.sourceItem = input
output = proxySource
proxySource.sourceRect = sourceRect
}
else if (isQQuickItemLayerEnabled(input)) {
output = input
}
else if ((isQQuickImage(input) && !hasTileMode(input) && !hasChildren(input))) {
output = input
}
else if (isQQuickShaderEffectSource(input)) {
output = input
}
else {
proxySource.sourceItem = input
output = proxySource
proxySource.sourceRect = Qt.rect(0, 0, 0, 0)
}
}
function isQQuickItemLayerEnabled(item) {
if (item.hasOwnProperty("layer")) {
var l = item["layer"]
if (l.hasOwnProperty("enabled") && l["enabled"].toString() == "true")
return true
}
return false
}
function isQQuickImage(item) {
var imageProperties = [ "fillMode", "progress", "asynchronous", "sourceSize", "status", "smooth" ]
return hasProperties(item, imageProperties)
}
function isQQuickShaderEffectSource(item) {
var shaderEffectSourceProperties = [ "hideSource", "format", "sourceItem", "mipmap", "wrapMode", "live", "recursive", "sourceRect" ]
return hasProperties(item, shaderEffectSourceProperties)
}
function hasProperties(item, properties) {
var counter = 0
for (var j = 0; j < properties.length; j++) {
if (item.hasOwnProperty(properties [j]))
counter++
}
return properties.length == counter
}
function hasChildren(item) {
if (item.hasOwnProperty("childrenRect")) {
if (item["childrenRect"].toString() != "QRectF(0, 0, 0, 0)")
return true
else
return false
}
return false
}
function hasTileMode(item) {
if (item.hasOwnProperty("fillMode")) {
if (item["fillMode"].toString() != "0")
return true
else
return false
}
return false
}
ShaderEffectSource {
id: proxySource
live: rootItem.input != rootItem.output
hideSource: false
smooth: true
visible: false
}
}
@@ -1,26 +0,0 @@
Blend 1.0 Blend.qml
BrightnessContrast 1.0 BrightnessContrast.qml
Colorize 1.0 Colorize.qml
ColorOverlay 1.0 ColorOverlay.qml
ConicalGradient 1.0 ConicalGradient.qml
Desaturate 1.0 Desaturate.qml
DirectionalBlur 1.0 DirectionalBlur.qml
Displace 1.0 Displace.qml
DropShadow 1.0 DropShadow.qml
FastBlur 1.0 FastBlur.qml
GammaAdjust 1.0 GammaAdjust.qml
GaussianBlur 1.0 GaussianBlur.qml
Glow 1.0 Glow.qml
HueSaturation 1.0 HueSaturation.qml
InnerShadow 1.0 InnerShadow.qml
LevelAdjust 1.0 LevelAdjust.qml
LinearGradient 1.0 LinearGradient.qml
MaskedBlur 1.0 MaskedBlur.qml
OpacityMask 1.0 OpacityMask.qml
RadialBlur 1.0 RadialBlur.qml
RadialGradient 1.0 RadialGradient.qml
RecursiveBlur 1.0 RecursiveBlur.qml
RectangularGlow 1.0 RectangularGlow.qml
ThresholdMask 1.0 ThresholdMask.qml
ZoomBlur 1.0 ZoomBlur.qml
designersupported
File diff suppressed because it is too large Load Diff
@@ -1,5 +0,0 @@
module QtQuick
plugin qtquick2plugin
classname QtQuick2Plugin
typeinfo plugins.qmltypes
designersupported
@@ -1,241 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.Window 2.2
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.0
import QtQuick.Controls.Private 1.0
/*!
\qmltype ApplicationWindow
\since 5.1
\inqmlmodule QtQuick.Controls
\ingroup applicationwindow
\brief Provides a top-level application window.
\image applicationwindow.png
ApplicationWindow is a \l Window that adds convenience for positioning items,
such as \l MenuBar, \l ToolBar, and \l StatusBar in a platform independent
manner.
\code
ApplicationWindow {
id: window
visible: true
menuBar: MenuBar {
Menu { MenuItem {...} }
Menu { MenuItem {...} }
}
toolBar: ToolBar {
RowLayout {
anchors.fill: parent
ToolButton {...}
}
}
TabView {
id: myContent
anchors.fill: parent
...
}
}
\endcode
\note By default, an ApplicationWindow is not visible.
The \l{Qt Quick Controls - Gallery} example is a good starting
point to explore this type.
*/
Window {
id: root
/*!
\qmlproperty MenuBar ApplicationWindow::menuBar
This property holds the \l MenuBar.
By default, this value is not set.
*/
property MenuBar menuBar: null
/*!
\qmlproperty Item ApplicationWindow::toolBar
This property holds the toolbar \l Item.
It can be set to any Item type, but is generally used with \l ToolBar.
By default, this value is not set. When you set the toolbar item, it will
be anchored automatically into the application window.
*/
property Item toolBar
/*!
\qmlproperty Item ApplicationWindow::statusBar
This property holds the status bar \l Item.
It can be set to any Item type, but is generally used with \l StatusBar.
By default, this value is not set. When you set the status bar item, it
will be anchored automatically into the application window.
*/
property Item statusBar
// The below documentation was supposed to be written as a grouped property, but qdoc would
// not render it correctly due to a bug (QTBUG-34206)
/*!
\qmlproperty ContentItem ApplicationWindow::contentItem
This group holds the size constraints of the content item. This is the area between the
\l ToolBar and the \l StatusBar.
The \l ApplicationWindow will use this as input when calculating the effective size
constraints of the actual window.
It holds these 6 properties for describing the minimum, implicit and maximum sizes:
\table
\header \li Grouped property \li Description
\row \li contentItem.minimumWidth \li The minimum width of the content item.
\row \li contentItem.minimumHeight \li The minimum height of the content item.
\row \li contentItem.implicitWidth \li The implicit width of the content item.
\row \li contentItem.implicitHeight \li The implicit height of the content item.
\row \li contentItem.maximumWidth \li The maximum width of the content item.
\row \li contentItem.maximumHeight \li The maximum height of the content item.
\endtable
*/
property alias contentItem : contentArea
/*! The style Component for the window.
\sa {Qt Quick Controls Styles QML Types}
*/
property Component style: Qt.createComponent(Settings.style + "/ApplicationWindowStyle.qml", root)
/*! \internal */
property alias __style: styleLoader.item
/*! \internal */
property alias __panel: panelLoader.item
/*! \internal */
property real __topBottomMargins: __panel.contentArea.y + __panel.statusBarArea.height
/*! \internal
There is a similar macro QWINDOWSIZE_MAX in qwindow_p.h that is used to limit the
range of QWindow::maximum{Width,Height}
However, in case we have a very big number (> 2^31) conversion will fail, and it will be
converted to 0, resulting in that we will call setMaximumWidth(0)....
We therefore need to enforce the limit at a level where we are still operating on
floating point values.
*/
readonly property real __qwindowsize_max: (1 << 24) - 1
/*! \internal */
property real __width: 0
Binding {
target: root
property: "__width"
when: root.minimumWidth <= root.maximumWidth
value: Math.max(Math.min(root.maximumWidth, contentArea.implicitWidth), root.minimumWidth)
}
/*! \internal */
property real __height: 0
Binding {
target: root
property: "__height"
when: root.minimumHeight <= root.maximumHeight
value: Math.max(Math.min(root.maximumHeight, contentArea.implicitHeight), root.minimumHeight)
}
width: contentArea.__noImplicitWidthGiven ? 0 : __width
height: contentArea.__noImplicitHeightGiven ? 0 : __height
minimumWidth: contentArea.__noMinimumWidthGiven ? 0 : contentArea.minimumWidth
minimumHeight: contentArea.__noMinimumHeightGiven ? 0 : (contentArea.minimumHeight + __topBottomMargins)
maximumWidth: Math.min(__qwindowsize_max, contentArea.maximumWidth)
maximumHeight: Math.min(__qwindowsize_max, contentArea.maximumHeight + __topBottomMargins)
/*! \internal */
default property alias data: contentArea.data
flags: Qt.Window | Qt.WindowFullscreenButtonHint |
Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.WindowMinMaxButtonsHint |
Qt.WindowCloseButtonHint | Qt.WindowFullscreenButtonHint
// QTBUG-35049: Windows is removing features we didn't ask for, even though Qt::CustomizeWindowHint is not set
// Otherwise Qt.Window | Qt.WindowFullscreenButtonHint would be enough
Loader {
id: panelLoader
anchors.fill: parent
sourceComponent: __style ? __style.panel : null
onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", root)
focus: true
Loader {
id: styleLoader
sourceComponent: style
property var __control: root
property QtObject styleData: QtObject {
readonly property bool hasColor: root.color != "#ffffff"
}
onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", root)
}
Binding { target: toolBar; property: "parent"; value: __panel.toolBarArea }
Binding { target: statusBar; property: "parent"; value: __panel.statusBarArea }
Binding {
property: "parent"
target: menuBar ? menuBar.__contentItem : null
when: menuBar && !menuBar.__isNative
value: __panel.menuBarArea
}
Binding { target: menuBar; property: "__parentWindow"; value: root }
Keys.forwardTo: menuBar ? [menuBar.__contentItem] : []
ContentItem {
id: contentArea
anchors.fill: parent
parent: __panel.contentArea
}
}
}
@@ -1,86 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.2
import QtQuick.Controls.Private 1.0
/*!
\qmltype BusyIndicator
\inqmlmodule QtQuick.Controls
\since 5.2
\ingroup controls
\brief A busy indicator.
\image busyindicator.png
The busy indicator should be used to indicate activity while content is
being loaded or the UI is blocked waiting for a resource to become available.
The following snippet shows how to use the BusyIndicator:
\qml
BusyIndicator {
running: image.status === Image.Loading
}
\endqml
You can create a custom appearance for a Busy Indicator by
assigning a \l {QtQuick.Controls.Styles::BusyIndicatorStyle}{BusyIndicatorStyle}.
*/
Control {
id: indicator
/*! \qmlproperty bool BusyIndicator::running
This property holds whether the busy indicator is currently indicating
activity.
\note The indicator is only visible when this property is set to \c true.
The default value is \c true.
*/
property bool running: true
Accessible.role: Accessible.Indicator
Accessible.name: "busy"
style: Qt.createComponent(Settings.style + "/BusyIndicatorStyle.qml", indicator)
}
@@ -1,132 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.2
import QtQuick.Controls.Private 1.0
/*!
\qmltype Button
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup controls
\brief A push button with a text label.
\image button.png
The push button is perhaps the most commonly used widget in any graphical
user interface. Pushing (or clicking) a button commands the computer to
perform some action or answer a question. Common examples of buttons are
OK, Apply, Cancel, Close, Yes, No, and Help buttons.
\qml
Button {
text: "Button"
}
\endqml
Button is similar to the QPushButton widget.
You can create a custom appearance for a Button by
assigning a \l {QtQuick.Controls.Styles::ButtonStyle}{ButtonStyle}.
*/
BasicButton {
id: button
/*! This property holds whether the push button is the default button.
Default buttons decide what happens when the user presses enter in a
dialog without giving a button explicit focus. \note This property only
changes the appearance of the button. The expected behavior needs to be
implemented by the user.
The default value is \c false.
*/
property bool isDefault: false
/*! Assign a \l Menu to this property to get a pull-down menu button.
The default value is \c null.
*/
property Menu menu: null
__effectivePressed: __behavior.effectivePressed || menu && menu.__popupVisible
activeFocusOnTab: true
Accessible.name: text
style: Qt.createComponent(Settings.style + "/ButtonStyle.qml", button)
Binding {
target: menu
property: "__minimumWidth"
value: button.__panel.width
}
Binding {
target: menu
property: "__visualItem"
value: button
}
Connections {
target: __behavior
onEffectivePressedChanged: {
if (!Settings.hasTouchScreen && __behavior.effectivePressed && menu)
popupMenuTimer.start()
}
onReleased: {
if (Settings.hasTouchScreen && __behavior.containsMouse && menu)
popupMenuTimer.start()
}
}
Timer {
id: popupMenuTimer
interval: 10
onTriggered: {
__behavior.keyPressed = false
if (Qt.application.layoutDirection === Qt.RightToLeft)
menu.__popup(Qt.rect(button.width, button.height, 0, 0), 0)
else
menu.__popup(Qt.rect(0, button.height, 0, 0), 0)
}
}
}
@@ -1,437 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.2
import QtQuick.Controls.Styles 1.1
import QtQuick.Controls.Private 1.0
/*!
\qmltype Calendar
\inqmlmodule QtQuick.Controls
\since 5.3
\ingroup controls
\brief Provides a way to select dates from a calendar
\image calendar.png
Calendar allows selection of dates from a grid of days, similar to
QCalendarWidget.
The dates on the calendar can be selected with the mouse, or navigated
with the keyboard.
The selected date can be set through \l selectedDate.
A minimum and maximum date can be set through \l minimumDate and
\l maximumDate. The earliest minimum date that can be set is 1 January, 1
AD. The latest maximum date that can be set is 25 October, 275759 AD.
The selected date is displayed using the format in the application's
default locale.
Week numbers can be displayed by setting the weekNumbersVisible property to
\c true.
\qml
Calendar {
weekNumbersVisible: true
}
\endqml
You can create a custom appearance for Calendar by assigning a
\l {QtQuick.Controls.Styles::CalendarStyle}{CalendarStyle}.
*/
Control {
id: calendar
/*!
\qmlproperty date Calendar::selectedDate
The date that has been selected by the user.
This property is subject to the following validation:
\list
\li If selectedDate is outside the range of \l minimumDate and
\l maximumDate, it will be clamped to be within that range.
\li selectedDate will not be changed if \c undefined or some other
invalid value is assigned.
\li If there are hours, minutes, seconds or milliseconds set, they
will be removed.
\endlist
The default value is the current date, which is equivalent to:
\code
new Date()
\endcode
*/
property alias selectedDate: rangedDate.date
/*!
\qmlproperty date Calendar::minimumDate
The earliest date that this calendar will accept.
By default, this property is set to the earliest minimum date
(1 January, 1 AD).
*/
property alias minimumDate: rangedDate.minimumDate
/*!
\qmlproperty date Calendar::maximumDate
The latest date that this calendar will accept.
By default, this property is set to the latest maximum date
(25 October, 275759 AD).
*/
property alias maximumDate: rangedDate.maximumDate
/*!
This property determines which month in visibleYear is shown on the
calendar.
The month is from \c 0 to \c 11 to be consistent with the JavaScript
Date object.
\sa visibleYear
*/
property int visibleMonth: selectedDate.getMonth()
/*!
This property determines which year is shown on the
calendar.
\sa visibleMonth
*/
property int visibleYear: selectedDate.getFullYear()
onSelectedDateChanged: {
// When the selected date changes, the view should move back to that date.
visibleMonth = selectedDate.getMonth();
visibleYear = selectedDate.getFullYear();
}
RangedDate {
id: rangedDate
date: new Date()
minimumDate: CalendarUtils.minimumCalendarDate
maximumDate: CalendarUtils.maximumCalendarDate
}
/*!
This property determines the visibility of the frame
surrounding the calendar.
The default value is \c true.
*/
property bool frameVisible: true
/*!
This property determines the visibility of week numbers.
The default value is \c false.
*/
property bool weekNumbersVisible: false
/*!
This property determines the visibility of the navigation bar.
\since QtQuick.Controls 1.3
The default value is \c true.
*/
property bool navigationBarVisible: true
/*!
\qmlproperty enum Calendar::dayOfWeekFormat
The format in which the days of the week (in the header) are displayed.
\c Locale.ShortFormat is the default and recommended format, as
\c Locale.NarrowFormat may not be fully supported by each locale (see
\l {Locale String Format Types}) and
\c Locale.LongFormat may not fit within the header cells.
*/
property int dayOfWeekFormat: Locale.ShortFormat
/*!
The locale that this calendar should use to display itself.
Affects how dates and day names are localized, as well as which
day is considered the first in a week.
To set an Australian locale, for example:
\code
locale: Qt.locale("en_AU")
\endcode
The default locale is \c Qt.locale().
*/
property var __locale: Qt.locale()
/*!
\internal
This property holds the model that will be used by the Calendar to
populate the dates available to the user.
*/
property CalendarModel __model: CalendarModel {
locale: calendar.__locale
visibleDate: new Date(visibleYear, visibleMonth, 1)
}
style: Qt.createComponent(Settings.style + "/CalendarStyle.qml", calendar)
/*!
\qmlsignal Calendar::hovered(date date)
Emitted when the mouse hovers over a valid date in the calendar.
\a date is the date that was hovered over.
The corresponding handler is \c onHovered.
*/
signal hovered(date date)
/*!
\qmlsignal Calendar::pressed(date date)
Emitted when the mouse is pressed on a valid date in the calendar.
This is also emitted when dragging the mouse to another date while it is pressed.
\a date is the date that the mouse was pressed on.
The corresponding handler is \c onPressed.
*/
signal pressed(date date)
/*!
\qmlsignal Calendar::released(date date)
Emitted when the mouse is released over a valid date in the calendar.
\a date is the date that the mouse was released over.
The corresponding handler is \c onReleased.
*/
signal released(date date)
/*!
\qmlsignal Calendar::clicked(date date)
Emitted when the mouse is clicked on a valid date in the calendar.
\a date is the date that the mouse was clicked on.
The corresponding handler is \c onClicked.
*/
signal clicked(date date)
/*!
\qmlsignal Calendar::doubleClicked(date date)
Emitted when the mouse is double-clicked on a valid date in the calendar.
\a date is the date that the mouse was double-clicked on.
The corresponding handler is \c onDoubleClicked.
*/
signal doubleClicked(date date)
/*!
\qmlsignal Calendar::pressAndHold(date date)
\since QtQuick.Controls 1.3
Emitted when the mouse is pressed and held on a valid date in the calendar.
\a date is the date that the mouse was pressed on.
The corresponding handler is \c onPressAndHold.
*/
signal pressAndHold(date date)
/*!
Sets visibleMonth to the previous month.
*/
function showPreviousMonth() {
if (visibleMonth === 0) {
visibleMonth = CalendarUtils.monthsInAYear - 1;
--visibleYear;
} else {
--visibleMonth;
}
}
/*!
Sets visibleMonth to the next month.
*/
function showNextMonth() {
if (visibleMonth === CalendarUtils.monthsInAYear - 1) {
visibleMonth = 0;
++visibleYear;
} else {
++visibleMonth;
}
}
/*!
Sets visibleYear to the previous year.
*/
function showPreviousYear() {
if (visibleYear - 1 >= minimumDate.getFullYear()) {
--visibleYear;
}
}
/*!
Sets visibleYear to the next year.
*/
function showNextYear() {
if (visibleYear + 1 <= maximumDate.getFullYear()) {
++visibleYear;
}
}
/*!
Selects the month before the current month in \l selectedDate.
*/
function __selectPreviousMonth() {
calendar.selectedDate = CalendarUtils.setMonth(calendar.selectedDate, calendar.selectedDate.getMonth() - 1);
}
/*!
Selects the month after the current month in \l selectedDate.
*/
function __selectNextMonth() {
calendar.selectedDate = CalendarUtils.setMonth(calendar.selectedDate, calendar.selectedDate.getMonth() + 1);
}
/*!
Selects the week before the current week in \l selectedDate.
*/
function __selectPreviousWeek() {
var newDate = new Date(calendar.selectedDate);
newDate.setDate(newDate.getDate() - CalendarUtils.daysInAWeek);
calendar.selectedDate = newDate;
}
/*!
Selects the week after the current week in \l selectedDate.
*/
function __selectNextWeek() {
var newDate = new Date(calendar.selectedDate);
newDate.setDate(newDate.getDate() + CalendarUtils.daysInAWeek);
calendar.selectedDate = newDate;
}
/*!
Selects the first day of the current month in \l selectedDate.
*/
function __selectFirstDayOfMonth() {
var newDate = new Date(calendar.selectedDate);
newDate.setDate(1);
calendar.selectedDate = newDate;
}
/*!
Selects the last day of the current month in \l selectedDate.
*/
function __selectLastDayOfMonth() {
var newDate = new Date(calendar.selectedDate);
newDate.setDate(CalendarUtils.daysInMonth(newDate));
calendar.selectedDate = newDate;
}
/*!
Selects the day before the current day in \l selectedDate.
*/
function __selectPreviousDay() {
var newDate = new Date(calendar.selectedDate);
newDate.setDate(newDate.getDate() - 1);
calendar.selectedDate = newDate;
}
/*!
Selects the day after the current day in \l selectedDate.
*/
function __selectNextDay() {
var newDate = new Date(calendar.selectedDate);
newDate.setDate(newDate.getDate() + 1);
calendar.selectedDate = newDate;
}
Keys.onLeftPressed: {
calendar.__selectPreviousDay();
}
Keys.onUpPressed: {
calendar.__selectPreviousWeek();
}
Keys.onDownPressed: {
calendar.__selectNextWeek();
}
Keys.onRightPressed: {
calendar.__selectNextDay();
}
Keys.onPressed: {
if (event.key === Qt.Key_Home) {
calendar.__selectFirstDayOfMonth();
event.accepted = true;
} else if (event.key === Qt.Key_End) {
calendar.__selectLastDayOfMonth();
event.accepted = true;
} else if (event.key === Qt.Key_PageUp) {
calendar.__selectPreviousMonth();
event.accepted = true;
} else if (event.key === Qt.Key_PageDown) {
calendar.__selectNextMonth();
event.accepted = true;
}
}
}
@@ -1,198 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.2
import QtQuick.Controls.Private 1.0
/*!
\qmltype CheckBox
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup controls
\brief A checkbox with a text label.
\image checkbox.png
A CheckBox is an option button that can be toggled on (checked) or off
(unchecked). Checkboxes are typically used to represent features in an
application that can be enabled or disabled without affecting others.
The state of the checkbox can be set with the \l {AbstractCheckable::checked}{checked} property.
In addition to the checked and unchecked states, there is a third state:
partially checked. This state indicates that the
regular checked/unchecked state can not be determined; generally because of
other states that affect the checkbox. This state is useful when several
child nodes are selected in a treeview, for example.
The partially checked state can be made available to the user by setting
\l partiallyCheckedEnabled to \c true, or set directly by setting
\l checkedState to \c Qt.PartiallyChecked. \l checkedState behaves
identically to \l {AbstractCheckable::checked}{checked} when \l partiallyCheckedEnabled
is \c false; setting one will appropriately set the other.
The label is shown next to the checkbox, and you can set the label text using its
\l {AbstractCheckable::text}{text} property.
\qml
Column {
CheckBox {
text: qsTr("Breakfast")
checked: true
}
CheckBox {
text: qsTr("Lunch")
}
CheckBox {
text: qsTr("Dinner")
checked: true
}
}
\endqml
Whenever a CheckBox is clicked, it emits the \l {AbstractCheckable::clicked}{clicked()} signal.
You can create a custom appearance for a CheckBox by
assigning a \l {QtQuick.Controls.Styles::CheckBoxStyle}{CheckBoxStyle}.
*/
AbstractCheckable {
id: checkBox
/*!
\qmlproperty enumeration CheckBox::checkedState
This property indicates the current checked state of the checkbox.
Possible values:
\c Qt.UnChecked - The checkbox is not checked (default).
\c Qt.Checked - The checkbox is checked.
\c Qt.PartiallyChecked - The checkbox is in a partially checked (or
"mixed") state.
The \l {AbstractCheckable::checked}{checked} property also determines whether
this property is \c Qt.Checked or \c Qt.UnChecked, and vice versa.
*/
property int checkedState: checked ? Qt.Checked : Qt.Unchecked
/*!
This property determines whether the \c Qt.PartiallyChecked state is
available.
A checkbox may be in a partially checked state when the regular checked
state can not be determined.
Setting \l checkedState to \c Qt.PartiallyChecked will implicitly set
this property to \c true.
If this property is \c true, \l {AbstractCheckable::checked}{checked} will be \c false.
By default, this property is \c false.
*/
property bool partiallyCheckedEnabled: false
/*!
\internal
True if onCheckedChanged should be ignored because we were reacting
to onCheckedStateChanged.
*/
property bool __ignoreChecked: false
/*!
\internal
True if onCheckedStateChanged should be ignored because we were reacting
to onCheckedChanged.
*/
property bool __ignoreCheckedState: false
style: Qt.createComponent(Settings.style + "/CheckBoxStyle.qml", checkBox)
activeFocusOnTab: true
Accessible.role: Accessible.CheckBox
Accessible.name: text
__cycleStatesHandler: __cycleCheckBoxStates
onCheckedChanged: {
if (!__ignoreChecked) {
__ignoreCheckedState = true;
checkedState = checked ? Qt.Checked : Qt.Unchecked;
__ignoreCheckedState = false;
}
}
onCheckedStateChanged: {
__ignoreChecked = true;
if (checkedState === Qt.PartiallyChecked) {
partiallyCheckedEnabled = true;
checked = false;
} else if (!__ignoreCheckedState) {
checked = checkedState === Qt.Checked;
}
__ignoreChecked = false;
}
onPartiallyCheckedEnabledChanged: {
if (exclusiveGroup && partiallyCheckedEnabled) {
console.warn("Cannot have partially checked boxes in an ExclusiveGroup.");
}
}
onExclusiveGroupChanged: {
if (exclusiveGroup && partiallyCheckedEnabled) {
console.warn("Cannot have partially checked boxes in an ExclusiveGroup.");
}
}
/*! \internal */
function __cycleCheckBoxStates() {
if (!partiallyCheckedEnabled) {
checked = !checked;
} else {
switch (checkedState) {
case Qt.Unchecked: checkedState = Qt.Checked; break;
case Qt.Checked: checkedState = Qt.PartiallyChecked; break;
case Qt.PartiallyChecked: checkedState = Qt.Unchecked; break;
}
}
}
}
@@ -1,665 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.2
import QtQuick.Controls.Private 1.0
/*!
\qmltype ComboBox
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup controls
\brief Provides a drop-down list functionality.
\image combobox.png
Add items to the ComboBox by assigning it a ListModel, or a list of strings
to the \l model property.
\qml
ComboBox {
width: 200
model: [ "Banana", "Apple", "Coconut" ]
}
\endqml
In this example we are demonstrating how to use a ListModel with a combo box.
\qml
ComboBox {
currentIndex: 2
model: ListModel {
id: cbItems
ListElement { text: "Banana"; color: "Yellow" }
ListElement { text: "Apple"; color: "Green" }
ListElement { text: "Coconut"; color: "Brown" }
}
width: 200
onCurrentIndexChanged: console.debug(cbItems.get(currentIndex).text + ", " + cbItems.get(currentIndex).color)
}
\endqml
You can make a combo box editable by setting the \l editable property. An editable combo box will
autocomplete its text based on what is available in the model.
In the next example we demonstrate how you can append content to an editable combo box by
reacting to the \l accepted signal. Note that you have to explicitly prevent duplicates.
\qml
ComboBox {
editable: true
model: ListModel {
id: model
ListElement { text: "Banana"; color: "Yellow" }
ListElement { text: "Apple"; color: "Green" }
ListElement { text: "Coconut"; color: "Brown" }
}
onAccepted: {
if (find(currentText) === -1) {
model.append({text: editText})
currentIndex = find(editText)
}
}
}
\endqml
You can create a custom appearance for a ComboBox by
assigning a \l {QtQuick.Controls.Styles::ComboBoxStyle}{ComboBoxStyle}.
*/
Control {
id: comboBox
/*! \qmlproperty model ComboBox::model
The model to populate the ComboBox from.
Changing the model after initialization will reset \l currentIndex to \c 0.
*/
property alias model: popupItems.model
/*! The model role used for populating the ComboBox. */
property string textRole: ""
/*! \qmlproperty int ComboBox::currentIndex
The index of the currently selected item in the ComboBox.
Setting currentIndex to \c -1 will reset the selection and clear the text
label. If \l editable is \c true, you may also need to manually clear \l editText.
\sa model
*/
property alias currentIndex: popup.__selectedIndex
/*! \qmlproperty string ComboBox::currentText
The text of the currently selected item in the ComboBox.
\note Since \c currentText depends on \c currentIndex, there's no way to ensure \c currentText
will be up to date whenever a \c onCurrentIndexChanged handler is called.
*/
readonly property alias currentText: popup.currentText
/*! This property holds whether the combo box can be edited by the user.
The default value is \c false.
\since QtQuick.Controls 1.1
*/
property bool editable: false
/*! \qmlproperty string ComboBox::editText
\since QtQuick.Controls 1.1
This property specifies text being manipulated by the user for an editable combo box.
*/
property alias editText: input.text
/*! This property specifies whether the combobox should gain active focus when pressed.
The default value is \c false. */
property bool activeFocusOnPress: false
/*! \qmlproperty bool ComboBox::pressed
This property holds whether the button is being pressed. */
readonly property bool pressed: mouseArea.effectivePressed || popup.__popupVisible
/*! \qmlproperty bool ComboBox::hovered
This property indicates whether the control is being hovered.
*/
readonly property bool hovered: mouseArea.containsMouse || input.containsMouse
/*! \qmlproperty int ComboBox::count
\since QtQuick.Controls 1.1
This property holds the number of items in the combo box.
*/
readonly property alias count: popupItems.count
/*! Returns the text for a given \a index.
If an invalid index is provided, \c null is returned
\since QtQuick.Controls 1.1
*/
function textAt (index) {
if (index >= count || index < 0)
return null;
return popupItems.objectAt(index).text;
}
/*! Finds and returns the index of a given \a text
If no match is found, \c -1 is returned. The search is case sensitive.
\since QtQuick.Controls 1.1
*/
function find (text) {
return input.find(text, Qt.MatchExactly)
}
/*!
\qmlproperty Validator ComboBox::validator
\since QtQuick.Controls 1.1
Allows you to set a text validator for an editable ComboBox.
When a validator is set,
the text field will only accept input which leaves the text property in
an intermediate state. The accepted signal will only be sent
if the text is in an acceptable state when enter is pressed.
Currently supported validators are \l{QtQuick::}{IntValidator},
\l{QtQuick::}{DoubleValidator}, and \l{QtQuick::}{RegExpValidator}. An
example of using validators is shown below, which allows input of
integers between 11 and 31 into the text field:
\note This property is only applied when \l editable is \c true
\qml
import QtQuick 2.2
import QtQuick.Controls 1.2
ComboBox {
editable: true
model: 10
validator: IntValidator {bottom: 0; top: 10;}
focus: true
}
\endqml
\sa acceptableInput, accepted, editable
*/
property alias validator: input.validator
/*!
\since QtQuick.Controls 1.3
This property contains the edit \l Menu for working
with text selection. Set it to \c null if no menu
is wanted.
\note The menu is only in use when \l editable is \c true
*/
property Component menu: input.editMenu.defaultMenu
/*!
\qmlproperty bool ComboBox::acceptableInput
\since QtQuick.Controls 1.1
Returns \c true if the combo box contains acceptable
text in the editable text field.
If a validator was set, this property will return \c
true if the current text satisfies the validator or mask as
a final string (not as an intermediate string).
\sa validator, accepted
*/
readonly property alias acceptableInput: input.acceptableInput
/*!
\qmlproperty bool ComboBox::selectByMouse
\since QtQuick.Controls 1.3
This property determines if the user can select the text in
the editable text field with the mouse.
The default value is \c true.
*/
property bool selectByMouse: true
/*!
\qmlproperty bool ComboBox::inputMethodComposing
\since QtQuick.Controls 1.3
This property holds whether an editable ComboBox has partial text input from an input method.
While it is composing an input method may rely on mouse or key events from the ComboBox
to edit or commit the partial text. This property can be used to determine when to disable
events handlers that may interfere with the correct operation of an input method.
*/
readonly property bool inputMethodComposing: !!input.inputMethodComposing
/*!
\qmlsignal ComboBox::accepted()
\since QtQuick.Controls 1.1
This signal is emitted when the Return or Enter key is pressed on an
\l editable combo box. If the confirmed string is not currently in the model,
the currentIndex will be set to -1 and the \l currentText will be updated
accordingly.
\note If there is a \l validator set on the combobox,
the signal will only be emitted if the input is in an acceptable state.
The corresponding handler is \c onAccepted.
*/
signal accepted
/*!
\qmlsignal ComboBox::activated(int index)
\since QtQuick.Controls 1.1
\a index is the triggered model index or -1 if a new string is accepted
This signal is similar to currentIndex changed, but will only
be emitted if the combo box index was changed by the user and not
when set programatically.
The corresponding handler is \c onActivated.
*/
signal activated(int index)
/*!
\qmlmethod ComboBox::selectAll()
\since QtQuick.Controls 1.1
Causes all \l editText to be selected.
*/
function selectAll() {
input.selectAll()
}
/*! \internal */
function __selectPrevItem() {
input.blockUpdate = true
if (currentIndex > 0) {
currentIndex--;
input.text = popup.currentText;
activated(currentIndex);
}
input.blockUpdate = false;
}
/*! \internal */
function __selectNextItem() {
input.blockUpdate = true;
if (currentIndex < popupItems.count - 1) {
currentIndex++;
input.text = popup.currentText;
activated(currentIndex);
}
input.blockUpdate = false;
}
/*! \internal */
property var __popup: popup
style: Qt.createComponent(Settings.style + "/ComboBoxStyle.qml", comboBox)
activeFocusOnTab: true
Accessible.name: editable ? editText : currentText
Accessible.role: Accessible.ComboBox
Accessible.editable: editable
MouseArea {
id: mouseArea
property bool overridePressed: false
readonly property bool effectivePressed: (pressed || overridePressed) && containsMouse
anchors.fill: parent
hoverEnabled: Settings.hoverEnabled
onPressed: {
if (comboBox.activeFocusOnPress)
forceActiveFocus()
if (!Settings.hasTouchScreen)
popup.toggleShow()
else
overridePressed = true
}
onCanceled: overridePressed = false
onClicked: {
if (Settings.hasTouchScreen)
popup.toggleShow()
overridePressed = false
}
onWheel: {
if (wheel.angleDelta.y > 0) {
__selectPrevItem();
} else if (wheel.angleDelta.y < 0){
__selectNextItem();
}
}
}
Component.onCompleted: {
if (currentIndex === -1)
currentIndex = 0
popup.ready = true
popup.resolveTextValue(textRole)
}
Keys.onPressed: {
// Perform one-character based lookup for non-editable combo box
if (!editable && event.text.length > 0) {
var index = input.find(event.text, Qt.MatchStartsWith);
if (index >= 0 && index !== currentIndex) {
currentIndex = index;
activated(currentIndex);
}
}
}
TextInputWithHandles {
id: input
visible: editable
enabled: editable
focus: true
clip: contentWidth > width
control: comboBox
cursorHandle: __style ? __style.__cursorHandle : undefined
selectionHandle: __style ? __style.__selectionHandle : undefined
anchors.fill: parent
anchors.leftMargin: __style ? __style.padding.left : 0
anchors.topMargin: __style ? __style.padding.top : 0
anchors.rightMargin: __style ? __panel.dropDownButtonWidth + __style.padding.right : 0
anchors.bottomMargin: __style ? __style.padding.bottom: 0
verticalAlignment: Text.AlignVCenter
font: __panel && __panel.font !== undefined ? __panel.font : TextSingleton.font
renderType: __style ? __style.renderType : Text.NativeRendering
color: __panel ? __panel.textColor : "black"
selectionColor: __panel ? __panel.selectionColor : "blue"
selectedTextColor: __panel ? __panel.selectedTextColor : "white"
onAccepted: {
var idx = input.find(editText, Qt.MatchFixedString)
if (idx > -1) {
editTextMatches = true;
currentIndex = idx;
editText = textAt(idx);
} else {
editTextMatches = false;
currentIndex = -1;
popup.currentText = editText;
}
comboBox.accepted();
}
property bool blockUpdate: false
property string prevText
property bool editTextMatches: true
function find (text, searchType) {
for (var i = 0 ; i < popupItems.count ; ++i) {
var currentString = popupItems.objectAt(i).text
if (searchType === Qt.MatchExactly) {
if (text === currentString)
return i;
} else if (searchType === Qt.CaseSensitive) {
if (currentString.indexOf(text) === 0)
return i;
} else if (searchType === Qt.MatchFixedString) {
if (currentString.toLowerCase().indexOf(text.toLowerCase()) === 0
&& currentString.length === text.length)
return i;
} else if (currentString.toLowerCase().indexOf(text.toLowerCase()) === 0) {
return i
}
}
return -1;
}
// Finds first entry and shortest entry. Used by editable combo
function tryComplete (inputText) {
var candidate = "";
var shortestString = "";
for (var i = 0 ; i < popupItems.count ; ++i) {
var currentString = popupItems.objectAt(i).text;
if (currentString.toLowerCase().indexOf(inputText.toLowerCase()) === 0) {
if (candidate.length) { // Find smallest possible match
var cmp = 0;
// We try to complete the shortest string that matches our search
if (currentString.length < candidate.length)
candidate = currentString
while (cmp < Math.min(currentString.length, shortestString.length)
&& shortestString[cmp].toLowerCase() === currentString[cmp].toLowerCase())
cmp++;
shortestString = shortestString.substring(0, cmp);
} else { // First match, select as current index and find other matches
candidate = currentString;
shortestString = currentString;
}
}
}
if (candidate.length)
return inputText + candidate.substring(inputText.length, candidate.length);
return inputText;
}
property bool allowComplete: false
Keys.forwardTo: comboBox
Keys.onPressed: allowComplete = (event.key !== Qt.Key_Backspace && event.key !== Qt.Key_Delete);
onTextChanged: {
if (editable && !blockUpdate && allowComplete && text.length > 0) {
var completed = input.tryComplete(text)
if (completed.length > text.length) {
var oldtext = input.text;
input.text = completed;
input.select(text.length, oldtext.length);
}
}
prevText = text
}
}
Binding {
target: input
property: "text"
value: popup.currentText
when: input.editTextMatches
}
onTextRoleChanged: popup.resolveTextValue(textRole)
Menu {
id: popup
objectName: "popup"
style: isPopup ? __style.__popupStyle : __style.__dropDownStyle
property string currentText: selectedText
onSelectedTextChanged: if (selectedText) popup.currentText = selectedText
property string selectedText
on__SelectedIndexChanged: {
if (__selectedIndex === -1)
popup.currentText = ""
else
updateSelectedText()
}
property string textRole: ""
property bool ready: false
property bool isPopup: !editable && !!__panel && __panel.popup
property int y: isPopup ? (comboBox.__panel.height - comboBox.__panel.implicitHeight) / 2.0 : comboBox.__panel.height
__minimumWidth: comboBox.width
__visualItem: comboBox
property ExclusiveGroup eg: ExclusiveGroup { id: eg }
property bool modelIsArray: false
Instantiator {
id: popupItems
active: false
property bool updatingModel: false
onModelChanged: {
popup.modelIsArray = !!model ? model.constructor === Array : false
if (active) {
if (updatingModel && popup.__selectedIndex === 0) {
// We still want to update the currentText
popup.updateSelectedText()
} else {
updatingModel = true
popup.__selectedIndex = 0
}
}
popup.resolveTextValue(comboBox.textRole)
}
MenuItem {
text: popup.textRole === '' ?
modelData :
((popup.modelIsArray ? modelData[popup.textRole] : model[popup.textRole]) || '')
onTriggered: {
if (index !== currentIndex)
activated(index)
comboBox.editText = text
}
checkable: true
exclusiveGroup: eg
}
onObjectAdded: {
popup.insertItem(index, object)
if (!updatingModel && index === popup.__selectedIndex)
popup.selectedText = object["text"]
}
onObjectRemoved: popup.removeItem(object)
}
function resolveTextValue(initialTextRole) {
if (!ready || !model) {
popupItems.active = false
return;
}
var get = model['get'];
if (!get && popup.modelIsArray && !!model[0]) {
if (model[0].constructor !== String && model[0].constructor !== Number)
get = function(i) { return model[i]; }
}
var modelMayHaveRoles = get !== undefined
textRole = initialTextRole
if (textRole === "" && modelMayHaveRoles && get(0)) {
// No text role set, check whether model has a suitable role
// If 'text' is found, or there's only one role, pick that.
var listElement = get(0)
var roleName = ""
var roleCount = 0
for (var role in listElement) {
if (listElement[role].constructor === Function)
continue;
if (role === "text") {
roleName = role
break
} else if (!roleName) {
roleName = role
}
++roleCount
}
if (roleCount > 1 && roleName !== "text") {
console.warn("No suitable 'textRole' found for ComboBox.")
} else {
textRole = roleName
}
}
if (!popupItems.active)
popupItems.active = true
else
updateSelectedText()
}
function toggleShow() {
if (popup.__popupVisible) {
popup.__dismissMenu()
popup.__destroyAllMenuPopups()
} else {
if (items[__selectedIndex])
items[__selectedIndex].checked = true
__currentIndex = comboBox.currentIndex
if (Qt.application.layoutDirection === Qt.RightToLeft)
__popup(Qt.rect(comboBox.width, y, 0, 0), isPopup ? __selectedIndex : 0)
else
__popup(Qt.rect(0, y, 0, 0), isPopup ? __selectedIndex : 0)
}
}
function updateSelectedText() {
var selectedItem;
if (__selectedIndex !== -1 && (selectedItem = items[__selectedIndex])) {
input.editTextMatches = true
selectedText = selectedItem.text
if (currentText !== selectedText) // __selectedIndex went form -1 to 0
selectedTextChanged()
}
}
}
// The key bindings below will only be in use when popup is
// not visible. Otherwise, native popup key handling will take place:
Keys.onSpacePressed: {
if (!editable)
popup.toggleShow()
else
event.accepted = false
}
Keys.onUpPressed: __selectPrevItem()
Keys.onDownPressed: __selectNextItem()
}
@@ -1,233 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.2
import QtQuick.Controls.Private 1.0
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.0
/*!
\qmltype GroupBox
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup controls
\brief GroupBox provides a group box frame with a title.
\image groupbox.png
A group box provides a frame, a title on top and displays various other controls inside itself. Group boxes can also be checkable.
Child controls in checkable group boxes are enabled or disabled depending on whether or not the group box is checked.
You can minimize the space consumption of a group box by enabling the flat property.
In most styles, enabling this property results in the removal of the left, right and bottom edges of the frame.
To add content to a group box, you can reparent it to its contentItem property.
The implicit size of the GroupBox is calculated based on the size of its content. If you want to anchor
items inside the group box, you must specify an explicit width and height on the GroupBox itself.
The following example shows how we use a GroupBox:
\qml
GroupBox {
title: "Joining for?"
Column {
spacing: 10
CheckBox {
text: "Breakfast"
checked: true
}
CheckBox {
text: "Lunch"
checked: false
}
CheckBox {
text: "Dinner"
checked: true
}
}
}
\endqml
\sa CheckBox, RadioButton, Layout
*/
FocusScope {
id: groupbox
/*!
This property holds the group box title text.
There is no default title text.
*/
property string title
/*!
This property holds whether the group box is painted flat or has a frame.
A group box usually consists of a surrounding frame with a title at the top.
If this property is enabled, only the top part of the frame is drawn in most styles;
otherwise, the whole frame is drawn.
By default, this property is disabled, so group boxes are not flat unless explicitly specified.
\note In some styles, flat and non-flat group boxes have similar representations and may not be as
distinguishable as they are in other styles.
*/
property bool flat: false
/*!
This property holds whether the group box has a checkbox in its title.
If this property is true, the group box displays its title using a checkbox in place of an ordinary label.
If the checkbox is checked, the group box's children are enabled; otherwise, they are disabled and inaccessible.
By default, group boxes are not checkable.
*/
property bool checkable: false
/*!
\qmlproperty bool GroupBox::checked
This property holds whether the group box is checked.
If the group box is checkable, it is displayed with a check box. If the check box is checked, the group
box's children are enabled; otherwise, the children are disabled and are inaccessible to the user.
By default, checkable group boxes are also checked.
*/
property alias checked: check.checked
/*! \internal */
default property alias __content: container.data
/*!
\qmlproperty Item GroupBox::contentItem
This property holds the content Item of the group box.
Items declared as children of a GroupBox are automatically parented to the GroupBox's contentItem.
Items created dynamically need to be explicitly parented to the contentItem:
\note The implicit size of the GroupBox is calculated based on the size of its content. If you want to anchor
items inside the group box, you must specify an explicit width and height on the GroupBox itself.
*/
readonly property alias contentItem: container
/*! \internal */
property Component style: Qt.createComponent(Settings.style + "/GroupBoxStyle.qml", groupbox)
/*! \internal */
property alias __checkbox: check
/*! \internal */
property alias __style: styleLoader.item
implicitWidth: Math.max((!anchors.fill ? container.calcWidth() : 0) + loader.leftMargin + loader.rightMargin,
sizeHint.implicitWidth + (checkable ? 24 : 6))
implicitHeight: (!anchors.fill ? container.calcHeight() : 0) + loader.topMargin + loader.bottomMargin
Layout.minimumWidth: implicitWidth
Layout.minimumHeight: implicitHeight
Accessible.role: Accessible.Grouping
Accessible.name: title
activeFocusOnTab: false
data: [
Loader {
id: loader
anchors.fill: parent
property int topMargin: __style ? __style.padding.top : 0
property int bottomMargin: __style ? __style.padding.bottom : 0
property int leftMargin: __style ? __style.padding.left : 0
property int rightMargin: __style ? __style.padding.right : 0
sourceComponent: styleLoader.item ? styleLoader.item.panel : null
onLoaded: item.z = -1
Text { id: sizeHint ; visible: false ; text: title }
Loader {
id: styleLoader
property alias __control: groupbox
sourceComponent: groupbox.style
}
},
CheckBox {
id: check
objectName: "check"
checked: true
text: groupbox.title
visible: checkable
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: loader.topMargin
activeFocusOnTab: groupbox.checkable
style: CheckBoxStyle { panel: Item{} }
},
Item {
id: container
objectName: "container"
z: 1
focus: true
anchors.fill: parent
anchors.topMargin: loader.topMargin
anchors.leftMargin: loader.leftMargin
anchors.rightMargin: loader.rightMargin
anchors.bottomMargin: loader.bottomMargin
enabled: (!groupbox.checkable || groupbox.checked)
property Item layoutItem: container.children.length === 1 ? container.children[0] : null
function calcWidth () { return (layoutItem ? (layoutItem.implicitWidth || layoutItem.width) +
(layoutItem.anchors.fill ? layoutItem.anchors.leftMargin +
layoutItem.anchors.rightMargin : 0) : container.childrenRect.width) }
function calcHeight () { return (layoutItem ? (layoutItem.implicitHeight || layoutItem.height) +
(layoutItem.anchors.fill ? layoutItem.anchors.topMargin +
layoutItem.anchors.bottomMargin : 0) : container.childrenRect.height) }
}]
}
@@ -1,97 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.2
import QtQuick.Controls.Private 1.0
/*!
\qmltype Label
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup controls
\brief A text label.
\image label.png
In addition to the normal \l Text type, Label follows the font and
color scheme of the system.
Use the \c text property to assign a text to the label. For other properties
check \l Text.
A simple label looks like this:
\qml
Label {
text: "Hello world"
}
\endqml
You can use the properties of \l Text to change the appearance
of the text as desired:
\qml
Label {
text: "Hello world"
font.pixelSize: 22
font.italic: true
color: "steelblue"
}
\endqml
\sa Text, TextField, TextEdit
*/
Text {
/*!
\qmlproperty string Label::text
The text to display. Use this property to get and set it.
*/
id: label
color: pal.windowText
activeFocusOnTab: false
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
SystemPalette {
id: pal
colorGroup: enabled ? SystemPalette.Active : SystemPalette.Disabled
}
Accessible.name: text
Accessible.role: Accessible.StaticText
}
@@ -1,173 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.2
import QtQuick.Controls.Styles 1.1
import QtQuick.Controls.Private 1.0
/*!
\qmltype Menu
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup menus
\brief Provides a menu component for use as a context menu, popup menu, or
as part of a menu bar.
\image menu.png
\code
Menu {
title: "Edit"
MenuItem {
text: "Cut"
shortcut: "Ctrl+X"
onTriggered: ...
}
MenuItem {
text: "Copy"
shortcut: "Ctrl+C"
onTriggered: ...
}
MenuItem {
text: "Paste"
shortcut: "Ctrl+V"
onTriggered: ...
}
MenuSeparator { }
Menu {
title: "More Stuff"
MenuItem {
text: "Do Nothing"
}
}
}
\endcode
The main uses for menus:
\list
\li
as a \e top-level menu in a \l MenuBar
\li
as a \e submenu inside another menu
\li
as a standalone or \e context menu
\endlist
Note that some properties, such as \c enabled, \c text, or \c iconSource,
only make sense in a particular use case of the menu.
\sa MenuBar, MenuItem, MenuSeparator
*/
MenuPrivate {
id: root
/*! \internal
\omit
Documented in qqquickmenu.cpp.
\endomit
*/
function addMenu(title) {
return root.insertMenu(items.length, title)
}
/*! \internal
\omit
Documented in qquickmenu.cpp.
\endomit
*/
function insertMenu(index, title) {
if (!__selfComponent)
__selfComponent = Qt.createComponent("Menu.qml", root)
var submenu = __selfComponent.createObject(__selfComponent, { "title": title })
root.insertItem(index, submenu)
return submenu
}
/*! \internal */
property Component __selfComponent: null
property Component style
Component.onCompleted: {
if (!style) {
__usingDefaultStyle = true
style = Qt.binding(function() { return Qt.createComponent(Settings.style + "/MenuStyle.qml", root) })
}
}
/*! \internal */
property bool __usingDefaultStyle: false
/*! \internal */
property var __parentContentItem: __parentMenu.__contentItem
/*! \internal */
property int __currentIndex: -1
/*! \internal */
on__MenuClosed: __currentIndex = -1
on__MenuPopupDestroyed: contentLoader.active = false
onPopupVisibleChanged: {
if (__popupVisible)
contentLoader.active = true
}
/*! \internal */
__contentItem: Loader {
id: contentLoader
Component {
id: menuContent
MenuContentItem {
__menu: root
}
}
sourceComponent: root.__isNative ? null : menuContent
active: false
focus: true
Keys.forwardTo: item ? [item, root.__parentContentItem] : []
property bool altPressed: root.__parentContentItem ? root.__parentContentItem.altPressed : false
}
}
@@ -1,323 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.2
import QtQuick.Controls.Styles 1.1
import QtQuick.Controls.Private 1.0
/*!
\qmltype MenuBar
\inqmlmodule QtQuick.Controls
\since 5.1
\ingroup applicationwindow
\brief Provides a horizontal menu bar.
\image menubar.png
MenuBar can be added to an \l ApplicationWindow, providing menu options
to access additional functionality of the application.
\code
ApplicationWindow {
...
menuBar: MenuBar {
Menu {
title: "File"
MenuItem { text: "Open..." }
MenuItem { text: "Close" }
}
Menu {
title: "Edit"
MenuItem { text: "Cut" }
MenuItem { text: "Copy" }
MenuItem { text: "Paste" }
}
}
}
\endcode
\sa ApplicationWindow::menuBar
*/
MenuBarPrivate {
id: root
property Component style: Qt.createComponent(Settings.style + "/MenuBarStyle.qml", root)
/*! \internal */
property QtObject __style: styleLoader.item
__isNative: !__style.hasOwnProperty("__isNative") || __style.__isNative
/*! \internal */
__contentItem: Loader {
id: topLoader
sourceComponent: __menuBarComponent
active: !root.__isNative
focus: true
Keys.forwardTo: [item]
property real preferredWidth: parent && active ? parent.width : 0
property bool altPressed: item ? item.__altPressed : false
Loader {
id: styleLoader
property alias __control: topLoader.item
sourceComponent: root.style
onStatusChanged: {
if (status === Loader.Error)
console.error("Failed to load Style for", root)
}
}
}
/*! \internal */
property Component __menuBarComponent: Loader {
id: menuBarLoader
onStatusChanged: if (status === Loader.Error) console.error("Failed to load panel for", root)
visible: status === Loader.Ready
sourceComponent: d.style ? d.style.background : undefined
width: implicitWidth || root.__contentItem.preferredWidth
height: Math.max(row.height + d.heightPadding, item ? item.implicitHeight : 0)
Binding {
// Make sure the styled menu bar is in the background
target: menuBarLoader.item
property: "z"
value: menuMouseArea.z - 1
}
QtObject {
id: d
property Style style: __style
property int openedMenuIndex: -1
property bool preselectMenuItem: false
property real heightPadding: style ? style.padding.top + style.padding.bottom : 0
property bool altPressed: false
property bool altPressedAgain: false
property var mnemonicsMap: ({})
function dismissActiveFocus(event, reason) {
if (reason) {
altPressedAgain = false
altPressed = false
openedMenuIndex = -1
root.__contentItem.parent.forceActiveFocus()
} else {
event.accepted = false
}
}
function maybeOpenFirstMenu(event) {
if (altPressed && openedMenuIndex === -1) {
preselectMenuItem = true
openedMenuIndex = 0
} else {
event.accepted = false
}
}
}
property alias __altPressed: d.altPressed // Needed for the menu contents
focus: true
Keys.onPressed: {
var action = null
if (event.key === Qt.Key_Alt) {
if (!d.altPressed)
d.altPressed = true
else
d.altPressedAgain = true
} else if (d.altPressed && (action = d.mnemonicsMap[event.text.toUpperCase()])) {
d.preselectMenuItem = true
action.trigger()
event.accepted = true
}
}
Keys.onReleased: d.dismissActiveFocus(event, d.altPressedAgain && d.openedMenuIndex === -1)
Keys.onEscapePressed: d.dismissActiveFocus(event, d.openedMenuIndex === -1)
Keys.onUpPressed: d.maybeOpenFirstMenu(event)
Keys.onDownPressed: d.maybeOpenFirstMenu(event)
Keys.onLeftPressed: {
if (d.openedMenuIndex > 0) {
var idx = d.openedMenuIndex - 1
while (idx >= 0 && !(root.menus[idx].enabled && root.menus[idx].visible))
idx--
if (idx >= 0) {
d.preselectMenuItem = true
d.openedMenuIndex = idx
}
} else {
event.accepted = false;
}
}
Keys.onRightPressed: {
if (d.openedMenuIndex !== -1 && d.openedMenuIndex < root.menus.length - 1) {
var idx = d.openedMenuIndex + 1
while (idx < root.menus.length && !(root.menus[idx].enabled && root.menus[idx].visible))
idx++
if (idx < root.menus.length) {
d.preselectMenuItem = true
d.openedMenuIndex = idx
}
} else {
event.accepted = false;
}
}
Row {
id: row
x: d.style ? d.style.padding.left : 0
y: d.style ? d.style.padding.top : 0
width: parent.width - (d.style ? d.style.padding.left + d.style.padding.right : 0)
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
Repeater {
id: itemsRepeater
model: root.menus
Loader {
id: menuItemLoader
property var styleData: QtObject {
readonly property int index: __menuItemIndex
readonly property string text: !!__menuItem && __menuItem.title
readonly property bool enabled: !!__menuItem && __menuItem.enabled
readonly property bool selected: menuMouseArea.hoveredItem === menuItemLoader
readonly property bool open: !!__menuItem && __menuItem.__popupVisible || d.openedMenuIndex === index
readonly property bool underlineMnemonic: d.altPressed
}
height: Math.max(menuBarLoader.height - d.heightPadding,
menuItemLoader.item ? menuItemLoader.item.implicitHeight : 0)
readonly property var __menuItem: modelData
readonly property int __menuItemIndex: index
sourceComponent: d.style ? d.style.itemDelegate : null
visible: __menuItem.visible
Connections {
target: d
onOpenedMenuIndexChanged: {
if (!__menuItem.enabled)
return;
if (d.openedMenuIndex === index) {
if (__menuItem.__usingDefaultStyle)
__menuItem.style = d.style.menuStyle
__menuItem.__popup(Qt.rect(row.LayoutMirroring.enabled ? menuItemLoader.width : 0,
menuBarLoader.height - d.heightPadding, 0, 0), 0)
if (d.preselectMenuItem)
__menuItem.__currentIndex = 0
} else if (__menuItem.__popupVisible) {
__menuItem.__dismissMenu()
__menuItem.__destroyAllMenuPopups()
}
}
}
Connections {
target: __menuItem
onPopupVisibleChanged: {
if (!__menuItem.__popupVisible && d.openedMenuIndex === index)
d.openedMenuIndex = -1
}
}
Connections {
target: __menuItem.__action
onTriggered: d.openedMenuIndex = __menuItemIndex
}
Component.onCompleted: {
__menuItem.__visualItem = menuItemLoader
var title = __menuItem.title
var ampersandPos = title.indexOf("&")
if (ampersandPos !== -1)
d.mnemonicsMap[title[ampersandPos + 1].toUpperCase()] = __menuItem.__action
}
}
}
}
MouseArea {
id: menuMouseArea
anchors.fill: parent
hoverEnabled: Settings.hoverEnabled
onPositionChanged: updateCurrentItem(mouse, false)
onPressed: {
if (updateCurrentItem(mouse)) {
d.preselectMenuItem = false
d.openedMenuIndex = currentItem.__menuItemIndex
}
}
onExited: hoveredItem = null
property Item currentItem: null
property Item hoveredItem: null
function updateCurrentItem(mouse) {
var pos = mapToItem(row, mouse.x, mouse.y)
if (!hoveredItem || !hoveredItem.contains(Qt.point(pos.x - currentItem.x, pos.y - currentItem.y))) {
hoveredItem = row.childAt(pos.x, pos.y)
if (!hoveredItem)
return false;
currentItem = hoveredItem
if (d.openedMenuIndex !== -1) {
d.preselectMenuItem = false
d.openedMenuIndex = currentItem.__menuItemIndex
}
}
return true;
}
}
}
}
@@ -1,162 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.2
import QtQuick.Controls.Private 1.0
/*!
\qmltype AbstractCheckable
\inqmlmodule QtQuick.Controls
\ingroup controls
\brief An abstract representation of a checkable control with a label
\qmlabstract
\internal
A checkable control is one that has two states: checked (on) and
unchecked (off). AbstractCheckable encapsulates the basic behavior and
states that are required by checkable controls.
Examples of checkable controls are RadioButton and
CheckBox. CheckBox extends AbstractCheckable's behavior by adding a third
state: partially checked.
*/
Control {
id: abstractCheckable
/*!
Emitted whenever the control is clicked.
*/
signal clicked
/*!
\qmlproperty bool AbstractCheckable::pressed
This property is \c true if the control is being pressed.
Set this property to manually invoke a mouse click.
*/
property alias pressed: mouseArea.effectivePressed
/*! \qmlproperty bool AbstractCheckcable::hovered
This property indicates whether the control is being hovered.
*/
readonly property alias hovered: mouseArea.containsMouse
/*!
This property is \c true if the control is checked.
*/
property bool checked: false
Accessible.checked: checked
Accessible.checkable: true
/*!
This property is \c true if the control takes the focus when it is
pressed; \l{QQuickItem::forceActiveFocus()}{forceActiveFocus()} will be
called on the control.
*/
property bool activeFocusOnPress: false
/*!
This property stores the ExclusiveGroup that the control belongs to.
*/
property ExclusiveGroup exclusiveGroup: null
/*!
This property holds the text that the label should display.
*/
property string text
/*! \internal */
property var __cycleStatesHandler: cycleRadioButtonStates
activeFocusOnTab: true
MouseArea {
id: mouseArea
focus: true
anchors.fill: parent
hoverEnabled: Settings.hoverEnabled
enabled: !keyPressed
property bool keyPressed: false
property bool effectivePressed: pressed && containsMouse || keyPressed
onClicked: abstractCheckable.clicked();
onPressed: if (activeFocusOnPress) forceActiveFocus();
onReleased: {
if (containsMouse && (!exclusiveGroup || !checked))
__cycleStatesHandler();
}
}
/*! \internal */
onExclusiveGroupChanged: {
if (exclusiveGroup)
exclusiveGroup.bindCheckable(abstractCheckable)
}
Keys.onPressed: {
if (event.key === Qt.Key_Space && !event.isAutoRepeat && !mouseArea.pressed)
mouseArea.keyPressed = true;
}
Keys.onReleased: {
if (event.key === Qt.Key_Space && !event.isAutoRepeat && mouseArea.keyPressed) {
mouseArea.keyPressed = false;
if (!exclusiveGroup || !checked)
__cycleStatesHandler();
clicked();
}
}
Action {
// handle mnemonic
text: abstractCheckable.text
onTriggered: {
if (!abstractCheckable.exclusiveGroup || !abstractCheckable.checked)
abstractCheckable.__cycleStatesHandler();
abstractCheckable.clicked();
}
}
}
@@ -1,235 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.2
import QtQuick.Controls.Private 1.0
import QtQuick.Controls.Styles 1.1
/*!
\qmltype BasicButton
\internal
\qmlabstract
\inqmlmodule QtQuick.Controls.Private
*/
Control {
id: button
/*! This signal is emitted when the button is clicked. */
signal clicked
/*! \qmlproperty bool BasicButton::pressed
This property holds whether the button is being pressed. */
readonly property alias pressed: button.__effectivePressed
/*! \qmlproperty bool BasicButton::hovered
This property indicates whether the control is being hovered.
*/
readonly property alias hovered: behavior.containsMouse
/*! This property holds whether the button is checkable.
The default value is \c false. */
property bool checkable: false
Accessible.checkable: checkable
/*! This property holds whether the button is checked.
Only checkable buttons can be checked.
The default value is \c false. */
property bool checked: false
Accessible.checked: checked
/*! This property holds the ExclusiveGroup that the button belongs to.
The default value is \c null. */
property ExclusiveGroup exclusiveGroup: null
/*! This property holds the associated button action.
If a button has an action associated, the action defines the
button's properties like checked, text, tooltip etc.
When an action is set, it's still possible to override the \l text,
\l tooltip, \l iconSource, and \l iconName properties.
The default value is \c null. */
property Action action: null
/*! This property specifies whether the button should gain active focus when pressed.
The default value is \c false. */
property bool activeFocusOnPress: false
/*! This property holds the text shown on the button. If the button has no
text, the \l text property will be an empty string.
The default value is the empty string.
*/
property string text: action ? action.text : ""
/*! This property holds the button tooltip. */
property string tooltip: action ? (action.tooltip || StyleHelpers.removeMnemonics(action.text)) : ""
/*! This property holds the icon shown on the button. If the button has no
icon, the iconSource property will be an empty string.
The default value is the empty string.
*/
property url iconSource: action ? action.iconSource : ""
/*! The image label source as theme name.
When an icon from the platform icon theme is found, this takes
precedence over iconSource.
*/
property string iconName: action ? action.iconName : ""
/*! \internal */
property string __position: "only"
/*! \internal */
readonly property bool __iconOverriden: button.action && (button.action.iconSource !== button.iconSource || button.action.iconName !== button.iconName)
/*! \internal */
property Action __action: action || ownAction
/*! \internal */
readonly property Action __iconAction: __iconOverriden ? ownAction : __action
/*! \internal */
onExclusiveGroupChanged: {
if (exclusiveGroup)
exclusiveGroup.bindCheckable(button)
}
Accessible.role: Accessible.Button
Accessible.description: tooltip
/*! \internal */
function accessiblePressAction() {
__action.trigger(button)
}
Action {
id: ownAction
iconSource: !button.action || __iconOverriden ? button.iconSource : ""
iconName: !button.action || __iconOverriden ? button.iconName : ""
// let ownAction handle mnemonic if and only if the button does
// not already have an action assigned to avoid ambiguous shortcuts
text: button.action ? "" : button.text
}
Connections {
target: __action
onTriggered: button.clicked()
}
activeFocusOnTab: true
Keys.onPressed: {
if (event.key === Qt.Key_Space && !event.isAutoRepeat && !behavior.pressed)
behavior.keyPressed = true;
}
onFocusChanged: if (!focus) behavior.keyPressed = false
Keys.onReleased: {
if (event.key === Qt.Key_Space && !event.isAutoRepeat && behavior.keyPressed) {
behavior.keyPressed = false;
__action.trigger(button)
behavior.toggle()
}
}
MouseArea {
id: behavior
property bool keyPressed: false
property bool effectivePressed: pressed && containsMouse || keyPressed
anchors.fill: parent
hoverEnabled: Settings.hoverEnabled
enabled: !keyPressed
function toggle() {
if (button.checkable && !button.action && !(button.checked && button.exclusiveGroup))
button.checked = !button.checked
}
onReleased: {
if (containsMouse) {
toggle()
__action.trigger(button)
}
}
onExited: Tooltip.hideText()
onCanceled: Tooltip.hideText()
onPressed: {
if (activeFocusOnPress)
button.forceActiveFocus()
}
Timer {
interval: 1000
running: behavior.containsMouse && !pressed && tooltip.length
onTriggered: Tooltip.showText(behavior, Qt.point(behavior.mouseX, behavior.mouseY), tooltip)
}
}
/*! \internal */
property var __behavior: behavior
/*! \internal */
property bool __effectivePressed: behavior.effectivePressed
states: [
State {
name: "boundAction"
when: action !== null
PropertyChanges {
target: button
enabled: action.enabled
checkable: action.checkable
checked: action.checked
}
}
]
}
@@ -1,107 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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
/*
CalendarHeaderModel contains a list of the days of a week,
according to a \l locale. The \l locale affects which day of the week
is first in the model.
The only role provided by the model is \c dayOfWeek, which is one of the
following JavaScript values:
\list
\li \c Locale.Sunday
\li \c Locale.Monday
\li \c Locale.Tuesday
\li \c Locale.Wednesday
\li \c Locale.Thursday
\li \c Locale.Friday
\li \c Locale.Saturday
\endlist
*/
ListModel {
id: root
/*
The locale that this model should be based on.
This affects which day of the week is first in the model.
*/
property var locale
ListElement {
dayOfWeek: Locale.Sunday
}
ListElement {
dayOfWeek: Locale.Monday
}
ListElement {
dayOfWeek: Locale.Tuesday
}
ListElement {
dayOfWeek: Locale.Wednesday
}
ListElement {
dayOfWeek: Locale.Thursday
}
ListElement {
dayOfWeek: Locale.Friday
}
ListElement {
dayOfWeek: Locale.Saturday
}
Component.onCompleted: {
var daysOfWeek = [Locale.Sunday, Locale.Monday, Locale.Tuesday,
Locale.Wednesday, Locale.Thursday, Locale.Friday, Locale.Saturday];
var firstDayOfWeek = root.locale.firstDayOfWeek;
var shifted = daysOfWeek.splice(firstDayOfWeek, daysOfWeek.length - firstDayOfWeek);
daysOfWeek = shifted.concat(daysOfWeek)
if (firstDayOfWeek !== Locale.Sunday) {
for (var i = 0; i < daysOfWeek.length; ++i) {
root.setProperty(i, "dayOfWeek", daysOfWeek[i]);
}
}
}
}
@@ -1,138 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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$
**
****************************************************************************/
.pragma library
var daysInAWeek = 7;
var monthsInAYear = 12;
// Not the number of weeks per month, but the number of weeks that are
// shown on a typical calendar.
var weeksOnACalendarMonth = 6;
// Can't create year 1 directly...
var minimumCalendarDate = new Date(-1, 0, 1);
minimumCalendarDate.setFullYear(minimumCalendarDate.getFullYear() + 2);
var maximumCalendarDate = new Date(275759, 9, 25);
function daysInMonth(date) {
// Passing 0 as the day will give us the previous month, which will be
// date.getMonth() since we added 1 to it.
return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
}
/*!
Returns a copy of \a date with its month set to \a month, keeping the same
day if possible. Does not modify \a date.
*/
function setMonth(date, month) {
var oldDay = date.getDate();
var newDate = new Date(date);
// Set the day first, because setting the month could cause it to skip ahead
// a month if the day is larger than the latest day in that month.
newDate.setDate(1);
newDate.setMonth(month);
// We'd like to have the previous day still selected when we change
// months, but it might not be possible, so use the smallest of the two.
newDate.setDate(Math.min(oldDay, daysInMonth(newDate)));
return newDate;
}
/*!
Returns the cell rectangle for the cell at the given \a index, assuming
that the grid has a number of columns equal to \a columns and rows
equal to \a rows, with an available width of \a availableWidth and height
of \a availableHeight.
If \a gridLineWidth is greater than \c 0, the cell rectangle will be
calculated under the assumption that there is a grid between the cells:
31 | 1 | 2 | 3 | 4 | 5 | 6
--------------------------------
7 | 8 | 9 | 10 | 11 | 12 | 13
--------------------------------
14 | 15 | 16 | 17 | 18 | 19 | 20
--------------------------------
21 | 22 | 23 | 24 | 25 | 26 | 27
--------------------------------
28 | 29 | 30 | 31 | 1 | 2 | 3
--------------------------------
4 | 5 | 6 | 7 | 8 | 9 | 10
*/
function cellRectAt(index, columns, rows, availableWidth, availableHeight, gridLineWidth) {
var col = Math.floor(index % columns);
var row = Math.floor(index / columns);
var availableWidthMinusGridLines = availableWidth - ((columns - 1) * gridLineWidth);
var availableHeightMinusGridLines = availableHeight - ((rows - 1) * gridLineWidth);
var remainingHorizontalSpace = Math.floor(availableWidthMinusGridLines % columns);
var remainingVerticalSpace = Math.floor(availableHeightMinusGridLines % rows);
var baseCellWidth = Math.floor(availableWidthMinusGridLines / columns);
var baseCellHeight = Math.floor(availableHeightMinusGridLines / rows);
var rect = Qt.rect(0, 0, 0, 0);
rect.x = baseCellWidth * col;
rect.width = baseCellWidth;
if (remainingHorizontalSpace > 0) {
if (col < remainingHorizontalSpace) {
++rect.width;
}
// This cell's x position should be increased by 1 for every column above it.
rect.x += Math.min(remainingHorizontalSpace, col);
}
rect.y = baseCellHeight * row;
rect.height = baseCellHeight;
if (remainingVerticalSpace > 0) {
if (row < remainingVerticalSpace) {
++rect.height;
}
// This cell's y position should be increased by 1 for every row above it.
rect.y += Math.min(remainingVerticalSpace, row);
}
rect.x += col * gridLineWidth;
rect.y += row * gridLineWidth;
return rect;
}
@@ -1,238 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.2
import QtQuick.Controls.Private 1.0
Item {
id: content
property Component menuItemDelegate
property Component scrollIndicatorStyle
property Component scrollerStyle
property var itemsModel
property int minWidth: 100
property real maxHeight: 800
readonly property bool mousePressed: hoverArea.pressed
signal triggered(var item)
function menuItemAt(index) {
list.currentIndex = index
return list.currentItem
}
width: Math.max(list.contentWidth, minWidth)
height: Math.min(list.contentHeight, fittedMaxHeight)
readonly property int currentIndex: __menu.__currentIndex
property Item currentItem: null
property int itemHeight: 23
Component.onCompleted: {
var children = list.contentItem.children
for (var i = 0; i < list.count; i++) {
var child = children[i]
if (child.visible && child.styleData.type === MenuItemType.Item) {
itemHeight = children[i].height
break
}
}
}
readonly property int fittingItems: Math.floor((maxHeight - downScroller.height) / itemHeight)
readonly property real fittedMaxHeight: itemHeight * fittingItems + downScroller.height
readonly property bool shouldUseScrollers: scrollView.style === emptyScrollerStyle && itemsModel.length > fittingItems
readonly property real upScrollerHeight: upScroller.visible ? upScroller.height : 0
readonly property real downScrollerHeight: downScroller.visible ? downScroller.height : 0
property var oldMousePos: undefined
property var openedSubmenu: null
function updateCurrentItem(mouse) {
var pos = mapToItem(list.contentItem, mouse.x, mouse.y)
var dx = 0
var dy = 0
var dist = 0
if (openedSubmenu && oldMousePos !== undefined) {
dx = mouse.x - oldMousePos.x
dy = mouse.y - oldMousePos.y
dist = Math.sqrt(dx * dx + dy * dy)
}
oldMousePos = mouse
if (openedSubmenu && dist > 5) {
var menuRect = __menu.__popupGeometry
var submenuRect = openedSubmenu.__popupGeometry
var angle = Math.atan2(dy, dx)
var ds = 0
if (submenuRect.x > menuRect.x) {
ds = menuRect.width - oldMousePos.x
} else {
angle = Math.PI - angle
ds = oldMousePos.x
}
var above = submenuRect.y - menuRect.y - oldMousePos.y
var below = submenuRect.height - above
var minAngle = Math.atan2(above, ds)
var maxAngle = Math.atan2(below, ds)
// This tests that the current mouse position is in
// the triangle defined by the previous mouse position
// and the submenu's top-left and bottom-left corners.
if (minAngle < angle && angle < maxAngle) {
sloppyTimer.start()
return
}
}
if (!currentItem || !currentItem.contains(Qt.point(pos.x - currentItem.x, pos.y - currentItem.y))) {
if (currentItem && !hoverArea.pressed
&& currentItem.styleData.type === MenuItemType.Menu) {
currentItem.__closeSubMenu()
openedSubmenu = null
}
currentItem = list.itemAt(pos.x, pos.y)
if (currentItem) {
__menu.__currentIndex = currentItem.__menuItemIndex
if (currentItem.styleData.type === MenuItemType.Menu
&& !currentItem.__menuItem.__popupVisible) {
currentItem.__showSubMenu(false)
openedSubmenu = currentItem.__menuItem
}
} else {
__menu.__currentIndex = -1
}
}
}
Timer {
id: sloppyTimer
interval: 1000
// Stop timer as soon as we hover one of the submenu items
property int currentIndex: openedSubmenu ? openedSubmenu.__currentIndex : -1
onCurrentIndexChanged: if (currentIndex !== -1) stop()
onTriggered: {
if (openedSubmenu && openedSubmenu.__currentIndex === -1)
updateCurrentItem(oldMousePos)
}
}
Component {
id: emptyScrollerStyle
Style {
padding { left: 0; right: 0; top: 0; bottom: 0 }
property bool scrollToClickedPosition: false
property Component frame: Item { visible: false }
property Component corner: Item { visible: false }
property Component __scrollbar: Item { visible: false }
}
}
ScrollView {
id: scrollView
anchors {
fill: parent
topMargin: upScrollerHeight
bottomMargin: downScrollerHeight
}
style: scrollerStyle || emptyScrollerStyle
__wheelAreaScrollSpeed: itemHeight
ListView {
id: list
model: itemsModel
delegate: menuItemDelegate
snapMode: ListView.SnapToItem
boundsBehavior: Flickable.StopAtBounds
highlightFollowsCurrentItem: true
highlightMoveDuration: 0
}
}
MouseArea {
id: hoverArea
anchors.left: scrollView.left
width: scrollView.width - scrollView.__verticalScrollBar.width
height: parent.height
hoverEnabled: Settings.hoverEnabled
acceptedButtons: Qt.AllButtons
onPositionChanged: updateCurrentItem({ "x": mouse.x, "y": mouse.y })
onPressed: updateCurrentItem({ "x": mouse.x, "y": mouse.y })
onReleased: content.triggered(currentItem)
onExited: {
if (currentItem && !currentItem.__menuItem.__popupVisible) {
currentItem = null
__menu.__currentIndex = -1
}
}
MenuContentScroller {
id: upScroller
direction: Qt.UpArrow
visible: shouldUseScrollers && !list.atYBeginning
function scrollABit() { list.contentY -= itemHeight }
}
MenuContentScroller {
id: downScroller
direction: Qt.DownArrow
visible: shouldUseScrollers && !list.atYEnd
function scrollABit() { list.contentY += itemHeight }
}
}
Timer {
interval: 1
running: true
repeat: false
onTriggered: list.positionViewAtIndex(currentIndex, !scrollView.__style
? ListView.Center : ListView.Beginning)
}
Binding {
target: scrollView.__verticalScrollBar
property: "singleStep"
value: itemHeight
}
}
@@ -1,109 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.Layouts 1.1
Item {
id: contentItem
property real minimumWidth: __calcMinimum('Width')
property real minimumHeight: __calcMinimum('Height')
property real maximumWidth: Number.POSITIVE_INFINITY
property real maximumHeight: Number.POSITIVE_INFINITY
implicitWidth: __calcImplicitWidth()
implicitHeight: __calcImplicitHeight()
/*! \internal */
property Item __layoutItem: contentItem.children.length === 1 ? contentItem.children[0] : null
/*! \internal */
property real __marginsWidth: __layoutItem ? __layoutItem.anchors.leftMargin + __layoutItem.anchors.rightMargin : 0
/*! \internal */
property real __marginsHeight: __layoutItem ? __layoutItem.anchors.topMargin + __layoutItem.anchors.bottomMargin : 0
/*! \internal */
property bool __noMinimumWidthGiven : false
/*! \internal */
property bool __noMinimumHeightGiven : false
/*! \internal */
property bool __noImplicitWidthGiven : false
/*! \internal */
property bool __noImplicitHeightGiven : false
function __calcImplicitWidth() {
if (__layoutItem && __layoutItem.anchors.fill)
return __calcImplicit('Width')
return contentItem.childrenRect.x + contentItem.childrenRect.width
}
function __calcImplicitHeight() {
if (__layoutItem && __layoutItem.anchors.fill)
return __calcImplicit('Height')
return contentItem.childrenRect.y + contentItem.childrenRect.height
}
function __calcImplicit(hw) {
var pref = __layoutItem.Layout['preferred' + hw]
if (pref < 0) {
pref = __layoutItem['implicit' + hw]
}
contentItem['__noImplicit' + hw + 'Given'] = (pref === 0 ? true : false)
pref += contentItem['__margins' + hw]
return pref
}
function __calcMinimum(hw) { // hw is 'Width' or 'Height'
return (__layoutItem && __layoutItem.anchors.fill) ? __calcMinMax('minimum', hw) : 0
}
function __calcMaximum(hw) { // hw is 'Width' or 'Height'
return (__layoutItem && __layoutItem.anchors.fill) ? __calcMinMax('maximum', hw) : Number.POSITIVE_INFINITY
}
function __calcMinMax(minMaxConstraint, hw) {
var attachedPropName = minMaxConstraint + hw
var extent = __layoutItem.Layout[attachedPropName]
if (minMaxConstraint === 'minimum')
contentItem['__noMinimum' + hw + 'Given'] = (extent === 0 ? true : false)
extent += contentItem['__margins' + hw]
return extent
}
}
@@ -1,93 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.Styles 1.1
/*!
\qmltype Control
\internal
\qmlabstract
\inqmlmodule QtQuick.Controls.Private
*/
FocusScope {
id: root
/*! \qmlproperty Component Control::style
The style Component for this control.
\sa {Qt Quick Controls Styles QML Types}
*/
property Component style
/*! \internal */
property QtObject __style: styleLoader.item
/*! \internal */
property Item __panel: panelLoader.item
/*! \internal */
property var styleHints
implicitWidth: __panel ? __panel.implicitWidth: 0
implicitHeight: __panel ? __panel.implicitHeight: 0
baselineOffset: __panel ? __panel.baselineOffset: 0
activeFocusOnTab: false
/*! \internal */
property alias __styleData: styleLoader.styleData
Loader {
id: panelLoader
anchors.fill: parent
sourceComponent: __style ? __style.panel : null
onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", root)
Loader {
id: styleLoader
sourceComponent: style
property Item __control: root
property QtObject styleData: null
onStatusChanged: {
if (status === Loader.Error)
console.error("Failed to load Style for", root)
}
}
}
}
@@ -1,75 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick Controls module 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 Digia Plc 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.2
import QtQuick.Controls.Private 1.0
Loader {
property Item control
property Item input
property Item cursorHandle
property Item selectionHandle
property Flickable flickable
property Component defaultMenu: item && item.defaultMenu ? item.defaultMenu : null
property Menu menuInstance: null
property MouseArea mouseArea
Connections {
target: control
onMenuChanged: {
if (menuInstance !== null) {
menuInstance.destroy()
menuInstance = null
}
}
}
function getMenuInstance()
{
// Lazy load menu when first requested
if (!menuInstance && control.menu) {
menuInstance = control.menu.createObject(input);
}
return menuInstance;
}
source: Qt.resolvedUrl(Qt.platform.os === "ios" ? "EditMenu_ios.qml"
: Qt.platform.os === "android" ? "" : "EditMenu_base.qml")
}
@@ -1,113 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick controls module 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 Digia Plc 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.2
import QtQuick.Controls.Private 1.0
Item {
id: editMenuBase
anchors.fill: parent
Component {
id: cutAction
Action {
text: qsTr("Cu&t")
shortcut: StandardKey.Cut
iconName: "edit-cut"
enabled: !input.readOnly && selectionStart !== selectionEnd
onTriggered: {
input.cut();
input.select(input.cursorPosition, input.cursorPosition);
}
}
}
Component {
id: copyAction
Action {
text: qsTr("&Copy")
shortcut: StandardKey.Copy
iconName: "edit-copy"
enabled: input.selectionStart !== input.selectionEnd
onTriggered: {
input.copy();
input.select(input.cursorPosition, input.cursorPosition);
}
}
}
Component {
id: pasteAction
Action {
text: qsTr("&Paste")
shortcut: StandardKey.Paste
iconName: "edit-paste"
enabled: input.canPaste
onTriggered: input.paste()
}
}
property Component defaultMenu: Menu {
MenuItem { action: cutAction.createObject(editMenuBase) }
MenuItem { action: copyAction.createObject(editMenuBase) }
MenuItem { action: pasteAction.createObject(editMenuBase) }
}
Connections {
target: mouseArea
onClicked: {
if (input.selectionStart === input.selectionEnd) {
var cursorPos = input.positionAt(mouse.x, mouse.y)
input.moveHandles(cursorPos, cursorPos)
}
input.activate()
if (control.menu) {
var menu = getMenuInstance();
menu.__dismissMenu();
menu.__destroyAllMenuPopups();
var menuPos = mapToItem(null, mouse.x, mouse.y)
menu.__popup(Qt.rect(menuPos.x, menuPos.y, 0, 0), -1, MenuPrivate.EditMenu);
}
}
}
}
@@ -1,189 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Quick controls module 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 Digia Plc 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
import QtQuick.Controls.Private 1.0
Item {
anchors.fill: parent
property bool __showMenuFromTouchAndHold: false
property Component defaultMenu: Menu {
MenuItem {
text: "cut"
visible: !input.readOnly && selectionStart !== selectionEnd
onTriggered: {
cut();
select(input.cursorPosition, input.cursorPosition);
}
}
MenuItem {
text: "copy"
visible: selectionStart !== selectionEnd
onTriggered: {
copy();
select(input.cursorPosition, input.cursorPosition);
}
}
MenuItem {
text: "paste"
visible: input.canPaste
onTriggered: paste();
}
MenuItem {
text: "delete"
visible: !input.readOnly && selectionStart !== selectionEnd
onTriggered: remove(selectionStart, selectionEnd)
}
MenuItem {
text: "select"
visible: selectionStart === selectionEnd && input.length > 0
onTriggered: selectWord();
}
MenuItem {
text: "select all"
visible: !(selectionStart === 0 && selectionEnd === length)
onTriggered: selectAll();
}
}
Connections {
target: mouseArea
function clearFocusFromOtherItems()
{
var selectionItem = TextSingleton.selectionItem;
if (!selectionItem)
return;
var otherPos = selectionItem.cursorPosition;
selectionItem.select(otherPos, otherPos)
}
onClicked: {
if (control.menu && getMenuInstance().__popupVisible) {
select(input.cursorPosition, input.cursorPosition);
} else {
input.activate();
clearFocusFromOtherItems();
}
if (input.activeFocus) {
var pos = input.positionAt(mouse.x, mouse.y)
input.moveHandles(pos, pos)
}
}
onPressAndHold: {
var pos = input.positionAt(mouseArea.mouseX, mouseArea.mouseY);
input.select(pos, pos);
var hasSelection = selectionStart != selectionEnd;
if (!control.menu || (input.length > 0 && (!input.activeFocus || hasSelection))) {
selectWord();
} else {
// We don't select anything at this point, the
// menu will instead offer to select a word.
__showMenuFromTouchAndHold = true;
menuTimer.start();
clearFocusFromOtherItems();
}
}
onReleased: __showMenuFromTouchAndHold = false
onCanceled: __showMenuFromTouchAndHold = false
}
Connections {
target: cursorHandle ? cursorHandle : null
ignoreUnknownSignals: true
onPressedChanged: menuTimer.start()
}
Connections {
target: selectionHandle ? selectionHandle : null
ignoreUnknownSignals: true
onPressedChanged: menuTimer.start()
}
Connections {
target: flickable
ignoreUnknownSignals: true
onMovingChanged: menuTimer.start()
}
Connections {
id: selectionConnections
target: input
ignoreUnknownSignals: true
onSelectionStartChanged: menuTimer.start()
onSelectionEndChanged: menuTimer.start()
onActiveFocusChanged: menuTimer.start()
}
Timer {
// We use a timer so that we end up with one update when multiple connections fire at the same time.
// Basically we wan't the menu to be open if the user does a press and hold, or if we have a selection.
// The exceptions are if the user is moving selection handles or otherwise touching the screen (e.g flicking).
// What is currently missing are showing a magnifyer to place the cursor, and to reshow the edit menu when
// flicking stops.
id: menuTimer
interval: 1
onTriggered: {
if (!control.menu)
return;
if ((__showMenuFromTouchAndHold || selectionStart !== selectionEnd)
&& control.activeFocus
&& (!cursorHandle.pressed && !selectionHandle.pressed)
&& (!flickable || !flickable.moving)
&& (cursorHandle.delegate)) {
var p1 = input.positionToRectangle(input.selectionStart);
var p2 = input.positionToRectangle(input.selectionEnd);
var topLeft = input.mapToItem(null, p1.x, p1.y);
var size = Qt.size(p2.x - p1.x + p1.width, p2.y - p1.y + p1.height)
var targetRect = Qt.rect(topLeft.x, topLeft.y, size.width, size.height);
getMenuInstance().__dismissMenu();
getMenuInstance().__popup(targetRect, -1, MenuPrivate.EditMenu);
} else {
getMenuInstance().__dismissMenu();
}
}
}
}
@@ -1,456 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Graphical Effects module.
**
** $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 Digia Plc 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
Item {
id: rootItem
property variant source
property real spread: 0.0
property real blur: 0.0
property color color: "white"
property bool transparentBorder: false
property bool cached: false
SourceProxy {
id: sourceProxy
input: rootItem.source
}
ShaderEffectSource {
id: cacheItem
anchors.fill: shaderItem
visible: rootItem.cached
smooth: true
sourceItem: shaderItem
live: true
hideSource: visible
}
property string __internalBlurVertexShader: OpenGLInfo.profile === OpenGLInfo.CoreProfile ? "#version 150
in vec4 qt_Vertex;
in vec2 qt_MultiTexCoord0;
uniform mat4 qt_Matrix;
uniform float yStep;
uniform float xStep;
out vec2 qt_TexCoord0;
out vec2 qt_TexCoord1;
out vec2 qt_TexCoord2;
out vec2 qt_TexCoord3;
void main() {
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
gl_Position = qt_Matrix * qt_Vertex;
}
" : "
attribute highp vec4 qt_Vertex;
attribute highp vec2 qt_MultiTexCoord0;
uniform highp mat4 qt_Matrix;
uniform highp float yStep;
uniform highp float xStep;
varying highp vec2 qt_TexCoord0;
varying highp vec2 qt_TexCoord1;
varying highp vec2 qt_TexCoord2;
varying highp vec2 qt_TexCoord3;
void main() {
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
gl_Position = qt_Matrix * qt_Vertex;
}
"
property string __internalBlurFragmentShader: OpenGLInfo.profile === OpenGLInfo.CoreProfile ? "#version 150
uniform sampler2D source;
uniform float qt_Opacity;
in vec2 qt_TexCoord0;
in vec2 qt_TexCoord1;
in vec2 qt_TexCoord2;
in vec2 qt_TexCoord3;
out vec4 fragColor;
void main() {
vec4 sourceColor = (texture(source, qt_TexCoord0) +
texture(source, qt_TexCoord1) +
texture(source, qt_TexCoord2) +
texture(source, qt_TexCoord3)) * 0.25;
fragColor = sourceColor * qt_Opacity;
}
" : "
uniform lowp sampler2D source;
uniform lowp float qt_Opacity;
varying highp vec2 qt_TexCoord0;
varying highp vec2 qt_TexCoord1;
varying highp vec2 qt_TexCoord2;
varying highp vec2 qt_TexCoord3;
void main() {
highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) +
texture2D(source, qt_TexCoord1) +
texture2D(source, qt_TexCoord2) +
texture2D(source, qt_TexCoord3)) * 0.25;
gl_FragColor = sourceColor * qt_Opacity;
}
"
ShaderEffect {
id: level0
property variant source: sourceProxy.output
anchors.fill: parent
visible: false
smooth: true
}
ShaderEffectSource {
id: level1
width: Math.ceil(shaderItem.width / 32) * 32
height: Math.ceil(shaderItem.height / 32) * 32
sourceItem: level0
hideSource: rootItem.visible
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0,0,0,0)
smooth: true
visible: false
}
ShaderEffect {
id: effect1
property variant source: level1
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level2
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level2
width: level1.width / 2
height: level1.height / 2
sourceItem: effect1
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect2
property variant source: level2
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level3
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level3
width: level2.width / 2
height: level2.height / 2
sourceItem: effect2
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect3
property variant source: level3
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level4
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level4
width: level3.width / 2
height: level3.height / 2
sourceItem: effect3
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect4
property variant source: level4
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level5
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level5
width: level4.width / 2
height: level4.height / 2
sourceItem: effect4
hideSource: rootItem.visible
visible: false
smooth: true
}
ShaderEffect {
id: effect5
property variant source: level5
property real yStep: 1/height
property real xStep: 1/width
anchors.fill: level6
visible: false
smooth: true
vertexShader: __internalBlurVertexShader
fragmentShader: __internalBlurFragmentShader
}
ShaderEffectSource {
id: level6
width: level5.width / 2
height: level5.height / 2
sourceItem: effect5
hideSource: rootItem.visible
visible: false
smooth: true
}
Item {
id: dummysource
width: 1
height: 1
visible: false
}
ShaderEffectSource {
id: dummy
width: 1
height: 1
sourceItem: dummysource
visible: false
smooth: false
live: false
}
ShaderEffect {
id: shaderItem
x: transparentBorder ? -64 : 0
y: transparentBorder ? -64 : 0
width: transparentBorder ? parent.width + 128 : parent.width
height: transparentBorder ? parent.height + 128 : parent.height
property variant source1: level1
property variant source2: level2
property variant source3: level3
property variant source4: level4
property variant source5: level5
property variant source6: level6
property real lod: rootItem.blur
property real weight1;
property real weight2;
property real weight3;
property real weight4;
property real weight5;
property real weight6;
property real spread: 1.0 - (rootItem.spread * 0.98)
property alias color: rootItem.color
function weight(v) {
if (v <= 0.0)
return 1
if (v >= 0.5)
return 0
return 1.0 - v / 0.5
}
function calculateWeights() {
var w1 = weight(Math.abs(lod - 0.100))
var w2 = weight(Math.abs(lod - 0.300))
var w3 = weight(Math.abs(lod - 0.500))
var w4 = weight(Math.abs(lod - 0.700))
var w5 = weight(Math.abs(lod - 0.900))
var w6 = weight(Math.abs(lod - 1.100))
var sum = w1 + w2 + w3 + w4 + w5 + w6;
weight1 = w1 / sum;
weight2 = w2 / sum;
weight3 = w3 / sum;
weight4 = w4 / sum;
weight5 = w5 / sum;
weight6 = w6 / sum;
upateSources()
}
function upateSources() {
var sources = new Array();
var weights = new Array();
if (weight1 > 0) {
sources.push(level1)
weights.push(weight1)
}
if (weight2 > 0) {
sources.push(level2)
weights.push(weight2)
}
if (weight3 > 0) {
sources.push(level3)
weights.push(weight3)
}
if (weight4 > 0) {
sources.push(level4)
weights.push(weight4)
}
if (weight5 > 0) {
sources.push(level5)
weights.push(weight5)
}
if (weight6 > 0) {
sources.push(level6)
weights.push(weight6)
}
for (var j = sources.length; j < 6; j++) {
sources.push(dummy)
weights.push(0.0)
}
source1 = sources[0]
source2 = sources[1]
source3 = sources[2]
source4 = sources[3]
source5 = sources[4]
source6 = sources[5]
weight1 = weights[0]
weight2 = weights[1]
weight3 = weights[2]
weight4 = weights[3]
weight5 = weights[4]
weight6 = weights[5]
}
Component.onCompleted: calculateWeights()
onLodChanged: calculateWeights()
fragmentShader: rootItem.OpenGLInfo.profile === OpenGLInfo.CoreProfile ? "#version 150
uniform sampler2D source1;
uniform sampler2D source2;
uniform sampler2D source3;
uniform sampler2D source4;
uniform sampler2D source5;
uniform float weight1;
uniform float weight2;
uniform float weight3;
uniform float weight4;
uniform float weight5;
uniform vec4 color;
uniform float spread;
uniform float qt_Opacity;
in vec2 qt_TexCoord0;
out vec4 fragColor;
float linearstep(float e0, float e1, float x) {
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
}
void main() {
vec4 sourceColor = texture(source1, qt_TexCoord0) * weight1;
sourceColor += texture(source2, qt_TexCoord0) * weight2;
sourceColor += texture(source3, qt_TexCoord0) * weight3;
sourceColor += texture(source4, qt_TexCoord0) * weight4;
sourceColor += texture(source5, qt_TexCoord0) * weight5;
sourceColor = mix(vec4(0), color, linearstep(0.0, spread, sourceColor.a));
fragColor = sourceColor * qt_Opacity;
}
" : "
uniform lowp sampler2D source1;
uniform lowp sampler2D source2;
uniform lowp sampler2D source3;
uniform lowp sampler2D source4;
uniform lowp sampler2D source5;
uniform mediump float weight1;
uniform mediump float weight2;
uniform mediump float weight3;
uniform mediump float weight4;
uniform mediump float weight5;
uniform highp vec4 color;
uniform highp float spread;
uniform lowp float qt_Opacity;
varying mediump vec2 qt_TexCoord0;
highp float linearstep(highp float e0, highp float e1, highp float x) {
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
}
void main() {
lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1;
sourceColor += texture2D(source2, qt_TexCoord0) * weight2;
sourceColor += texture2D(source3, qt_TexCoord0) * weight3;
sourceColor += texture2D(source4, qt_TexCoord0) * weight4;
sourceColor += texture2D(source5, qt_TexCoord0) * weight5;
sourceColor = mix(vec4(0), color, linearstep(0.0, spread, sourceColor.a));
gl_FragColor = sourceColor * qt_Opacity;
}
"
}
}

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