mirror of
https://github.com/budtmo/docker-android.git
synced 2026-07-31 04:07:25 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69154410f2 | ||
|
|
4975ebcc47 | ||
|
|
e4180a6e65 | ||
|
|
e22b8f141e | ||
|
|
7d29525b48 | ||
|
|
f47cc495b0 | ||
|
|
bc516d5a8e | ||
|
|
b54fcd2087 | ||
|
|
7e7d12e4e8 | ||
|
|
8d9fc61158 | ||
|
|
bc5635ed0a | ||
|
|
0b7ca97939 | ||
|
|
7e0a2e4770 | ||
|
|
c82443e221 | ||
|
|
1d7b7c2ac7 | ||
|
|
59f792f7c0 | ||
|
|
84ac59f66a | ||
|
|
d176e69cc1 | ||
|
|
59f61e057e | ||
|
|
601d58c51f | ||
|
|
ac33a1f687 | ||
|
|
91ebdbf5ab | ||
|
|
c8fb92e400 | ||
|
|
80a64e82dd | ||
|
|
780278b519 | ||
|
|
b4544ae90f | ||
|
|
0af1143e72 | ||
|
|
9d0c66fb2b | ||
|
|
2b02843cfd |
@@ -16,6 +16,8 @@ env:
|
||||
- ANDROID_VERSION=6.0
|
||||
- ANDROID_VERSION=7.0
|
||||
- ANDROID_VERSION=7.1.1
|
||||
- ANDROID_VERSION=8.0
|
||||
- ANDROID_VERSION=8.1
|
||||
- REAL_DEVICE=True
|
||||
|
||||
script: bash travis.sh
|
||||
|
||||
@@ -48,11 +48,6 @@ List of Docker images
|
||||
|Linux|6.0|23|butomo1989/docker-android-x86-6.0|[](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://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://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://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://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://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://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://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://microbadger.com/images/butomo1989/docker-android-real-device "Get your own image badge on microbadger.com")|
|
||||
|Linux|All|All|butomo1989/docker-android-genymotion|[](https://microbadger.com/images/butomo1989/docker-android-genymotion "Get your own image badge on microbadger.com")|
|
||||
|
||||
@@ -81,14 +76,11 @@ Quick Start
|
||||
- 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 butomo1989/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
|
||||
|
||||
```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.
|
||||
|
||||
@@ -108,7 +100,7 @@ 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 butomo1989/docker-android-x86-7.1.1
|
||||
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-8.1
|
||||
```
|
||||
|
||||
### Connect to Selenium Grid
|
||||
@@ -126,7 +118,7 @@ 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
|
||||
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-8.1
|
||||
```
|
||||
|
||||
### Share Volume
|
||||
@@ -134,7 +126,7 @@ docker run --privileged -d -p 6080:6080 -p 4723:4723 -p 5554:5554 -p 5555:5555 -
|
||||
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
|
||||
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-8.1
|
||||
```
|
||||
|
||||
### Video Recording
|
||||
@@ -165,7 +157,7 @@ docker-android can be used for building Android project and executing its unit t
|
||||
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
|
||||
docker run -it --rm -v $PWD/android-testing/ui/espresso/BasicSample:/root/tmp butomo1989/docker-android-x86-8.1 tmp/gradlew build
|
||||
```
|
||||
|
||||
Proxy
|
||||
@@ -187,7 +179,10 @@ Genymotion
|
||||
|
||||

|
||||
|
||||
Docker-Android supports [Genymotion Cloud]. What you need is [device.json] and run following command
|
||||
Docker-Android supports [Genymotion Cloud].
|
||||
|
||||
You can easily scale your Appium tests on Genymotion Android virtual devices in the cloud.
|
||||
Use [device.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"
|
||||
@@ -199,6 +194,10 @@ docker run -it --rm -p 4723:4723 -v $PWD/genymotion/example/sample_devices:/root
|
||||
|
||||
You can also use [this docker-compose file].
|
||||
|
||||
<p align="center">
|
||||
<a href="https://youtu.be/jXhUEyaVeMY"><img src="./images/Genymotion_cloud.png" alt="Docker-Android supports Genymotion Cloud" width="600"></a>
|
||||
</p>
|
||||
|
||||
|
||||
Control android emulator outside container
|
||||
------------------------------------------
|
||||
@@ -315,7 +314,7 @@ The following instructions are used for OS X. You'll need [docker-machine-parall
|
||||
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
|
||||
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-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.
|
||||
@@ -343,7 +342,7 @@ Special Thanks
|
||||
[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>
|
||||
[Genymotion Cloud]: <https://www.genymotion.com/cloud/>
|
||||
[device.json]: <genymotion/example/sample_devices/devices.json>
|
||||
[this docker-compose file]: <genymotion/example/geny.yml>
|
||||
[adb_connection]: <images/adb_connection.png>
|
||||
|
||||
+2
-2
@@ -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: butomo1989/docker-android-x86-8.1
|
||||
privileged: true
|
||||
# Increase scale number if needed
|
||||
scale: 1
|
||||
|
||||
@@ -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
|
||||
+9
-13
@@ -86,30 +86,26 @@ 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=24
|
||||
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=2.40
|
||||
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 latest 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
|
||||
|
||||
|
||||
+18
-14
@@ -17,6 +17,11 @@ WORKDIR /root
|
||||
# socat
|
||||
# Port forwarder
|
||||
#------------------
|
||||
# Genymotion spec
|
||||
#------------------
|
||||
# bzip2
|
||||
# File compression
|
||||
#------------------
|
||||
# NoVNC Packages
|
||||
#------------------
|
||||
# x11vnc
|
||||
@@ -41,6 +46,7 @@ RUN apt-get -qqy update && apt-get -qqy install --no-install-recommends \
|
||||
xterm \
|
||||
supervisor \
|
||||
socat \
|
||||
bzip2 \
|
||||
x11vnc \
|
||||
openbox \
|
||||
menu \
|
||||
@@ -85,17 +91,17 @@ ENV DISPLAY=:0 \
|
||||
#====================
|
||||
# Install genymotion
|
||||
#====================
|
||||
ENV GENYMOTION_VERSION=2.12.1 \
|
||||
PATH="${PATH}:/root/genymotion"
|
||||
COPY genymotion/${GENYMOTION_VERSION}/genymotion /root/genymotion
|
||||
ARG GENYMOTION_VERSION=2.12.1
|
||||
|
||||
#=======================
|
||||
# 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
|
||||
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 /root/
|
||||
|
||||
#===============
|
||||
# Expose Ports
|
||||
@@ -114,8 +120,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"]
|
||||
|
||||
@@ -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
|
||||
Binary file not shown.
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;
|
||||
}
|
||||
"
|
||||
}
|
||||
}
|
||||
@@ -1,68 +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 FocusFrame
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
Item {
|
||||
id: root
|
||||
activeFocusOnTab: false
|
||||
Accessible.role: Accessible.StatusBar
|
||||
|
||||
anchors.topMargin: focusMargin
|
||||
anchors.leftMargin: focusMargin
|
||||
anchors.rightMargin: focusMargin
|
||||
anchors.bottomMargin: focusMargin
|
||||
|
||||
property int focusMargin: loader.item ? loader.item.margin : -3
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
z: 2
|
||||
anchors.fill: parent
|
||||
sourceComponent: Qt.createComponent(Settings.style + "/FocusFrameStyle.qml", root)
|
||||
}
|
||||
}
|
||||
@@ -1,80 +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: button
|
||||
property alias source: image.source
|
||||
signal clicked
|
||||
|
||||
Rectangle {
|
||||
id: fillRect
|
||||
anchors.fill: parent
|
||||
color: "black"
|
||||
opacity: mouse.pressed ? 0.07 : mouse.containsMouse ? 0.02 : 0.0
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
border.color: gridColor
|
||||
anchors.fill: parent
|
||||
anchors.margins: -1
|
||||
color: "transparent"
|
||||
opacity: fillRect.opacity * 10
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image
|
||||
width: Math.min(implicitWidth, parent.width * 0.4)
|
||||
height: Math.min(implicitHeight, parent.height * 0.4)
|
||||
anchors.centerIn: parent
|
||||
fillMode: Image.PreserveAspectFit
|
||||
opacity: 0.6
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouse
|
||||
anchors.fill: parent
|
||||
onClicked: button.clicked()
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
}
|
||||
}
|
||||
@@ -1,264 +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
|
||||
|
||||
Loader {
|
||||
id: menuFrameLoader
|
||||
|
||||
property var __menu
|
||||
|
||||
visible: status === Loader.Ready
|
||||
width: content.width + (d.style ? d.style.padding.left + d.style.padding.right : 0)
|
||||
height: content.height + (d.style ? d.style.padding.top + d.style.padding.bottom : 0)
|
||||
|
||||
Loader {
|
||||
id: styleLoader
|
||||
active: !__menu.isNative
|
||||
sourceComponent: __menu.style
|
||||
property alias __control: menuFrameLoader
|
||||
onStatusChanged: {
|
||||
if (status === Loader.Error)
|
||||
console.error("Failed to load Style for", __menu)
|
||||
}
|
||||
}
|
||||
sourceComponent: d.style ? d.style.frame : undefined
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property var mnemonicsMap: ({})
|
||||
readonly property Style style: styleLoader.item
|
||||
readonly property Component menuItemPanel: style ? style.menuItemPanel : null
|
||||
|
||||
function canBeHovered(index) {
|
||||
var item = content.menuItemAt(index)
|
||||
if (item && item.visible && item.styleData.type !== MenuItemType.Separator && item.styleData.enabled) {
|
||||
__menu.__currentIndex = index
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function triggerCurrent() {
|
||||
var item = content.menuItemAt(__menu.__currentIndex)
|
||||
if (item)
|
||||
content.triggered(item)
|
||||
}
|
||||
|
||||
function triggerAndDismiss(item) {
|
||||
if (item && item.styleData.type !== MenuItemType.Separator) {
|
||||
__menu.__dismissMenu()
|
||||
if (item.styleData.type !== MenuItemType.Menu)
|
||||
item.__menuItem.trigger()
|
||||
__menu.__destroyAllMenuPopups()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
focus: true
|
||||
|
||||
Keys.onPressed: {
|
||||
var item = null
|
||||
if (!(event.modifiers & Qt.AltModifier)
|
||||
&& (item = d.mnemonicsMap[event.text.toUpperCase()])) {
|
||||
if (item.styleData.type === MenuItemType.Menu) {
|
||||
__menu.__currentIndex = item.__menuItemIndex
|
||||
item.__showSubMenu(true)
|
||||
item.__menuItem.__currentIndex = 0
|
||||
} else {
|
||||
d.triggerAndDismiss(item)
|
||||
}
|
||||
event.accepted = true
|
||||
} else {
|
||||
event.accepted = false
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onEscapePressed: __menu.__dismissMenu()
|
||||
|
||||
Keys.onDownPressed: {
|
||||
if (__menu.__currentIndex < 0)
|
||||
__menu.__currentIndex = -1
|
||||
|
||||
for (var i = __menu.__currentIndex + 1;
|
||||
i < __menu.items.length && !d.canBeHovered(i); i++)
|
||||
;
|
||||
event.accepted = true
|
||||
}
|
||||
|
||||
Keys.onUpPressed: {
|
||||
for (var i = __menu.__currentIndex - 1;
|
||||
i >= 0 && !d.canBeHovered(i); i--)
|
||||
;
|
||||
event.accepted = true
|
||||
}
|
||||
|
||||
Keys.onLeftPressed: {
|
||||
if ((event.accepted = __menu.__parentMenu.hasOwnProperty("title"))) {
|
||||
__menu.__closeMenu()
|
||||
__menu.__destroyMenuPopup()
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onRightPressed: {
|
||||
var item = content.menuItemAt(__menu.__currentIndex)
|
||||
if ((event.accepted = (item && item.styleData.type === MenuItemType.Menu))) {
|
||||
item.__showSubMenu(true)
|
||||
item.__menuItem.__currentIndex = 0
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onSpacePressed: d.triggerCurrent()
|
||||
Keys.onReturnPressed: d.triggerCurrent()
|
||||
Keys.onEnterPressed: d.triggerCurrent()
|
||||
|
||||
Binding {
|
||||
// Make sure the styled frame is in the background
|
||||
target: item
|
||||
property: "z"
|
||||
value: content.z - 1
|
||||
}
|
||||
|
||||
ColumnMenuContent {
|
||||
id: content
|
||||
x: d.style ? d.style.padding.left : 0
|
||||
y: d.style ? d.style.padding.top : 0
|
||||
menuItemDelegate: menuItemComponent
|
||||
scrollIndicatorStyle: d.style && d.style.scrollIndicator || null
|
||||
scrollerStyle: d.style && d.style.__scrollerStyle
|
||||
itemsModel: __menu.items
|
||||
minWidth: __menu.__minimumWidth
|
||||
maxHeight: d.style ? d.style.__maxPopupHeight : 0
|
||||
onTriggered: if (item.__menuItem.enabled) d.triggerAndDismiss(item)
|
||||
}
|
||||
|
||||
Component {
|
||||
id: menuItemComponent
|
||||
Loader {
|
||||
id: menuItemLoader
|
||||
|
||||
property QtObject styleData: QtObject {
|
||||
id: opts
|
||||
readonly property int index: __menuItemIndex
|
||||
readonly property int type: __menuItem ? __menuItem.type : -1
|
||||
readonly property bool selected: type !== MenuItemType.Separator && __menu.__currentIndex === index
|
||||
readonly property bool pressed: type !== MenuItemType.Separator && __menu.__currentIndex === index
|
||||
&& content.mousePressed // TODO Add key pressed condition once we get delayed menu closing
|
||||
readonly property string text: type === MenuItemType.Menu ? __menuItem.title :
|
||||
type !== MenuItemType.Separator ? __menuItem.text : ""
|
||||
readonly property bool underlineMnemonic: __menu.__contentItem.altPressed
|
||||
readonly property string shortcut: !!__menuItem && __menuItem["shortcut"] || ""
|
||||
readonly property var iconSource: !!__menuItem && __menuItem["iconSource"] || undefined
|
||||
readonly property bool enabled: type !== MenuItemType.Separator && !!__menuItem && __menuItem.enabled
|
||||
readonly property bool checked: !!__menuItem && !!__menuItem["checked"]
|
||||
readonly property bool checkable: !!__menuItem && !!__menuItem["checkable"]
|
||||
readonly property bool exclusive: !!__menuItem && !!__menuItem["exclusiveGroup"]
|
||||
readonly property int scrollerDirection: Qt.NoArrow
|
||||
}
|
||||
|
||||
readonly property var __menuItem: modelData
|
||||
readonly property int __menuItemIndex: index
|
||||
|
||||
sourceComponent: d.menuItemPanel
|
||||
enabled: visible && opts.enabled
|
||||
visible: !!__menuItem && __menuItem.visible
|
||||
active: visible
|
||||
|
||||
function __showSubMenu(immediately) {
|
||||
if (!__menuItem.enabled)
|
||||
return;
|
||||
if (immediately) {
|
||||
if (__menu.__currentIndex === __menuItemIndex) {
|
||||
if (__menuItem.__usingDefaultStyle)
|
||||
__menuItem.style = __menu.style
|
||||
__menuItem.__popup(Qt.rect(menuFrameLoader.width - (d.style.submenuOverlap + d.style.padding.right), -d.style.padding.top, 0, 0), -1)
|
||||
}
|
||||
} else {
|
||||
openMenuTimer.start()
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: openMenuTimer
|
||||
interval: d.style.submenuPopupDelay
|
||||
onTriggered: menuItemLoader.__showSubMenu(true)
|
||||
}
|
||||
|
||||
function __closeSubMenu() {
|
||||
if (openMenuTimer.running)
|
||||
openMenuTimer.stop()
|
||||
else if (__menuItem.__popupVisible)
|
||||
closeMenuTimer.start()
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: closeMenuTimer
|
||||
interval: 1
|
||||
onTriggered: {
|
||||
if (__menu.__currentIndex !== __menuItemIndex) {
|
||||
__menuItem.__closeMenu()
|
||||
__menuItem.__destroyMenuPopup()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onLoaded: {
|
||||
__menuItem.__visualItem = menuItemLoader
|
||||
|
||||
if (content.width < item.implicitWidth)
|
||||
content.width = item.implicitWidth
|
||||
|
||||
var title = opts.text
|
||||
var ampersandPos = title.indexOf("&")
|
||||
if (ampersandPos !== -1)
|
||||
d.mnemonicsMap[title[ampersandPos + 1].toUpperCase()] = menuItemLoader
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: menuItemLoader.item
|
||||
property: "width"
|
||||
property alias menuItem: menuItemLoader.item
|
||||
value: menuItem ? Math.max(__menu.__minimumWidth, content.width) - 2 * menuItem.x : 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +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
|
||||
|
||||
MouseArea {
|
||||
id: scrollIndicator
|
||||
property int direction: 0
|
||||
|
||||
anchors {
|
||||
top: direction === Qt.UpArrow ? parent.top : undefined
|
||||
bottom: direction === Qt.DownArrow ? parent.bottom : undefined
|
||||
}
|
||||
|
||||
hoverEnabled: visible && Settings.hoverEnabled
|
||||
height: scrollerLoader.height
|
||||
width: parent.width
|
||||
|
||||
Loader {
|
||||
id: scrollerLoader
|
||||
|
||||
width: parent.width
|
||||
sourceComponent: scrollIndicatorStyle
|
||||
// Extra property values for desktop style
|
||||
property var __menuItem: null
|
||||
property var styleData: {
|
||||
"index": -1,
|
||||
"type": MenuItemType.ScrollIndicator,
|
||||
"text": "",
|
||||
"selected": scrollIndicator.containsMouse,
|
||||
"scrollerDirection": scrollIndicator.direction,
|
||||
"checkable": false,
|
||||
"checked": false,
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 100
|
||||
repeat: true
|
||||
triggeredOnStart: true
|
||||
running: parent.containsMouse
|
||||
onTriggered: scrollABit()
|
||||
}
|
||||
}
|
||||
@@ -1,49 +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
|
||||
|
||||
QtObject {
|
||||
property Component background: null
|
||||
property Component label: null
|
||||
property Component submenuIndicator: null
|
||||
property Component shortcut: null
|
||||
property Component checkmarkIndicator: null
|
||||
}
|
||||
@@ -1,135 +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
|
||||
|
||||
// KNOWN ISSUES
|
||||
// none
|
||||
|
||||
/*!
|
||||
\qmltype ModalPopupBehavior
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
Item {
|
||||
id: popupBehavior
|
||||
|
||||
property bool showing: false
|
||||
property bool whenAlso: true // modifier to the "showing" property
|
||||
property bool consumeCancelClick: true
|
||||
property int delay: 0 // delay before popout becomes visible
|
||||
property int deallocationDelay: 3000 // 3 seconds
|
||||
|
||||
property Component popupComponent
|
||||
|
||||
property alias popup: popupLoader.item // read-only
|
||||
property alias window: popupBehavior.root // read-only
|
||||
|
||||
signal prepareToShow
|
||||
signal prepareToHide
|
||||
signal cancelledByClick
|
||||
|
||||
// implementation
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
onShowingChanged: notifyChange()
|
||||
onWhenAlsoChanged: notifyChange()
|
||||
function notifyChange() {
|
||||
if(showing && whenAlso) {
|
||||
if(popupLoader.sourceComponent == undefined) {
|
||||
popupLoader.sourceComponent = popupComponent;
|
||||
}
|
||||
} else {
|
||||
mouseArea.enabled = false; // disable before opacity is changed in case it has fading behavior
|
||||
if(Qt.isQtObject(popupLoader.item)) {
|
||||
popupBehavior.prepareToHide();
|
||||
popupLoader.item.opacity = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property Item root: findRoot()
|
||||
function findRoot() {
|
||||
var p = parent;
|
||||
while(p.parent != undefined)
|
||||
p = p.parent;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
enabled: false // enabled only when popout is showing
|
||||
onPressed: {
|
||||
popupBehavior.showing = false;
|
||||
mouse.accepted = consumeCancelClick;
|
||||
cancelledByClick();
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: popupLoader
|
||||
}
|
||||
|
||||
Timer { // visibility timer
|
||||
running: Qt.isQtObject(popupLoader.item) && showing && whenAlso
|
||||
interval: delay
|
||||
onTriggered: {
|
||||
popupBehavior.prepareToShow();
|
||||
mouseArea.enabled = true;
|
||||
popup.opacity = 1;
|
||||
}
|
||||
}
|
||||
|
||||
Timer { // deallocation timer
|
||||
running: Qt.isQtObject(popupLoader.item) && popupLoader.item.opacity == 0
|
||||
interval: deallocationDelay
|
||||
onTriggered: popupLoader.sourceComponent = undefined
|
||||
}
|
||||
|
||||
states: State {
|
||||
name: "active"
|
||||
when: Qt.isQtObject(popupLoader.item) && popupLoader.item.opacity > 0
|
||||
ParentChange { target: popupBehavior; parent: root }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
/*!
|
||||
\qmltype ScrollBar
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
Item {
|
||||
id: scrollbar
|
||||
|
||||
property bool isTransient: false
|
||||
property bool active: false
|
||||
property int orientation: Qt.Horizontal
|
||||
property alias minimumValue: slider.minimumValue
|
||||
property alias maximumValue: slider.maximumValue
|
||||
property alias value: slider.value
|
||||
property int singleStep: 20
|
||||
|
||||
activeFocusOnTab: false
|
||||
|
||||
Accessible.role: Accessible.ScrollBar
|
||||
implicitWidth: panelLoader.implicitWidth
|
||||
implicitHeight: panelLoader.implicitHeight
|
||||
|
||||
property bool upPressed
|
||||
property bool downPressed
|
||||
property bool pageUpPressed
|
||||
property bool pageDownPressed
|
||||
property bool handlePressed
|
||||
|
||||
|
||||
property Item __panel: panelLoader.item
|
||||
Loader {
|
||||
id: panelLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: __style ? __style.__scrollbar : null
|
||||
onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", root)
|
||||
property alias __control: scrollbar
|
||||
property QtObject __styleData: QtObject {
|
||||
readonly property alias horizontal: internal.horizontal
|
||||
readonly property alias upPressed: scrollbar.upPressed
|
||||
readonly property alias downPressed: scrollbar.downPressed
|
||||
readonly property alias handlePressed: scrollbar.handlePressed
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: internal
|
||||
property bool horizontal: orientation === Qt.Horizontal
|
||||
property int pageStep: internal.horizontal ? width : height
|
||||
property bool scrollToClickposition: internal.scrollToClickPosition
|
||||
anchors.fill: parent
|
||||
cursorShape: __panel.visible ? Qt.ArrowCursor : Qt.IBeamCursor // forces a cursor change
|
||||
|
||||
property bool autoincrement: false
|
||||
property bool scrollToClickPosition: __style ? __style.scrollToClickedPosition : 0
|
||||
|
||||
// Update hover item
|
||||
onEntered: if (!pressed) __panel.activeControl = __panel.hitTest(mouseX, mouseY)
|
||||
onExited: if (!pressed) __panel.activeControl = "none"
|
||||
onMouseXChanged: if (!pressed) __panel.activeControl = __panel.hitTest(mouseX, mouseY)
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
enabled: !Settings.isMobile || !Settings.hasTouchScreen // ### Not ideal, but will usually behave as expected...
|
||||
preventStealing: true
|
||||
property var pressedX
|
||||
property var pressedY
|
||||
property int oldPosition
|
||||
property int grooveSize
|
||||
|
||||
Timer {
|
||||
running: upPressed || downPressed || pageUpPressed || pageDownPressed
|
||||
interval: 350
|
||||
onTriggered: internal.autoincrement = true
|
||||
}
|
||||
|
||||
Timer {
|
||||
running: internal.autoincrement
|
||||
interval: 60
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
if (upPressed && internal.containsMouse)
|
||||
internal.decrement();
|
||||
else if (downPressed && internal.containsMouse)
|
||||
internal.increment();
|
||||
else if (pageUpPressed)
|
||||
internal.decrementPage();
|
||||
else if (pageDownPressed)
|
||||
internal.incrementPage();
|
||||
}
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
if (handlePressed) {
|
||||
if (!horizontal)
|
||||
slider.position = oldPosition + (mouseY - pressedY)
|
||||
else
|
||||
slider.position = oldPosition + (mouseX - pressedX)
|
||||
}
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
__panel.activeControl = __panel.hitTest(mouseX, mouseY)
|
||||
scrollToClickposition = scrollToClickPosition
|
||||
var handleRect = __panel.subControlRect("handle")
|
||||
var grooveRect = __panel.subControlRect("groove")
|
||||
grooveSize = horizontal ? grooveRect.width - handleRect.width:
|
||||
grooveRect.height - handleRect.height;
|
||||
if (__panel.activeControl === "handle") {
|
||||
pressedX = mouseX;
|
||||
pressedY = mouseY;
|
||||
handlePressed = true;
|
||||
oldPosition = slider.position;
|
||||
} else if (__panel.activeControl === "up") {
|
||||
decrement();
|
||||
upPressed = Qt.binding(function() {return containsMouse});
|
||||
} else if (__panel.activeControl === "down") {
|
||||
increment();
|
||||
downPressed = Qt.binding(function() {return containsMouse});
|
||||
} else if (!scrollToClickposition){
|
||||
if (__panel.activeControl === "upPage") {
|
||||
decrementPage();
|
||||
pageUpPressed = true;
|
||||
} else if (__panel.activeControl === "downPage") {
|
||||
incrementPage();
|
||||
pageDownPressed = true;
|
||||
}
|
||||
} else { // scroll to click position
|
||||
slider.position = horizontal ? mouseX - handleRect.width/2 - grooveRect.x
|
||||
: mouseY - handleRect.height/2 - grooveRect.y
|
||||
pressedX = mouseX;
|
||||
pressedY = mouseY;
|
||||
handlePressed = true;
|
||||
oldPosition = slider.position;
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
__panel.activeControl = __panel.hitTest(mouseX, mouseY);
|
||||
autoincrement = false;
|
||||
upPressed = false;
|
||||
downPressed = false;
|
||||
handlePressed = false;
|
||||
pageUpPressed = false;
|
||||
pageDownPressed = false;
|
||||
}
|
||||
|
||||
onWheel: {
|
||||
var stepCount = -(wheel.angleDelta.x ? wheel.angleDelta.x : wheel.angleDelta.y) / 120
|
||||
if (stepCount != 0) {
|
||||
if (wheel.modifiers & Qt.ControlModifier || wheel.modifiers & Qt.ShiftModifier)
|
||||
incrementPage(stepCount)
|
||||
else
|
||||
increment(stepCount)
|
||||
}
|
||||
}
|
||||
|
||||
function incrementPage(stepCount) {
|
||||
value = boundValue(value + getSteps(pageStep, stepCount))
|
||||
}
|
||||
|
||||
function decrementPage(stepCount) {
|
||||
value = boundValue(value - getSteps(pageStep, stepCount))
|
||||
}
|
||||
|
||||
function increment(stepCount) {
|
||||
value = boundValue(value + getSteps(singleStep, stepCount))
|
||||
}
|
||||
|
||||
function decrement(stepCount) {
|
||||
value = boundValue(value - getSteps(singleStep, stepCount))
|
||||
}
|
||||
|
||||
function boundValue(val) {
|
||||
return Math.min(Math.max(val, minimumValue), maximumValue)
|
||||
}
|
||||
|
||||
function getSteps(step, count) {
|
||||
if (count)
|
||||
step *= count
|
||||
return step
|
||||
}
|
||||
|
||||
RangeModel {
|
||||
id: slider
|
||||
minimumValue: 0.0
|
||||
maximumValue: 1.0
|
||||
value: 0
|
||||
stepSize: 0.0
|
||||
inverted: false
|
||||
positionAtMaximum: internal.grooveSize
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,219 +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 ScrollViewHeader
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
Item {
|
||||
id: wheelarea
|
||||
|
||||
property alias horizontalScrollBar: hscrollbar
|
||||
property alias verticalScrollBar: vscrollbar
|
||||
property bool blockUpdates: false
|
||||
property int availableHeight
|
||||
property int availableWidth
|
||||
property int contentHeight
|
||||
property int contentWidth
|
||||
property real originX
|
||||
property real originY
|
||||
property bool active
|
||||
property int horizontalScrollBarPolicy: Qt.ScrollBarAsNeeded
|
||||
property int verticalScrollBarPolicy: Qt.ScrollBarAsNeeded
|
||||
|
||||
|
||||
property int leftMargin: outerFrame ? root.__style.padding.left : 0
|
||||
property int rightMargin: outerFrame ? root.__style.padding.right : 0
|
||||
property int topMargin: outerFrame ? root.__style.padding.top : 0
|
||||
property int bottomMargin: outerFrame ? root.__style.padding.bottom : 0
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
property bool recursionGuard: false
|
||||
|
||||
function doLayout() {
|
||||
if (!recursionGuard) {
|
||||
recursionGuard = true
|
||||
wheelarea.availableWidth = viewport.width
|
||||
wheelarea.availableHeight = viewport.height
|
||||
wheelarea.contentWidth = flickableItem !== null ? flickableItem.contentWidth : 0
|
||||
wheelarea.contentHeight = flickableItem !== null ? flickableItem.contentHeight : 0
|
||||
wheelarea.originX = flickableItem !== null ? flickableItem.originX : 0
|
||||
wheelarea.originY = flickableItem !== null ? flickableItem.originY : 0
|
||||
recursionGuard = false
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: viewport
|
||||
onWidthChanged: doLayout()
|
||||
onHeightChanged: doLayout()
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: flickableItem
|
||||
onContentWidthChanged: doLayout()
|
||||
onContentHeightChanged: doLayout()
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: flickableItem
|
||||
onContentXChanged: {
|
||||
hscrollbar.flash()
|
||||
vscrollbar.flash()
|
||||
}
|
||||
onContentYChanged: {
|
||||
hscrollbar.flash()
|
||||
vscrollbar.flash()
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: cornerFill
|
||||
z: 1
|
||||
sourceComponent: __style.corner
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: bottomMargin
|
||||
anchors.rightMargin: rightMargin
|
||||
width: visible ? vscrollbar.width : 0
|
||||
height: visible ? hscrollbar.height : 0
|
||||
visible: hscrollbar.visible && !hscrollbar.isTransient && vscrollbar.visible && !vscrollbar.isTransient
|
||||
}
|
||||
|
||||
ScrollBar {
|
||||
id: hscrollbar
|
||||
isTransient: !!__panel && !!__panel.isTransient
|
||||
active: !!__panel && (__panel.sunken || __panel.activeControl !== "none")
|
||||
enabled: !isTransient || __panel.visible
|
||||
orientation: Qt.Horizontal
|
||||
visible: horizontalScrollBarPolicy == Qt.ScrollBarAsNeeded ? (contentWidth > availableWidth) : horizontalScrollBarPolicy == Qt.ScrollBarAlwaysOn
|
||||
height: visible ? implicitHeight : 0
|
||||
z: 1
|
||||
maximumValue: contentWidth > availableWidth ? originX + contentWidth - availableWidth : 0
|
||||
minimumValue: originX
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: cornerFill.left
|
||||
anchors.leftMargin: leftMargin
|
||||
anchors.bottomMargin: bottomMargin
|
||||
onValueChanged: {
|
||||
if (!blockUpdates) {
|
||||
flickableItem.contentX = value
|
||||
}
|
||||
}
|
||||
Binding {
|
||||
target: hscrollbar.__panel
|
||||
property: "raised"
|
||||
value: vscrollbar.active || wheelarea.active
|
||||
when: hscrollbar.isTransient
|
||||
}
|
||||
Binding {
|
||||
target: hscrollbar.__panel
|
||||
property: "visible"
|
||||
value: true
|
||||
when: !hscrollbar.isTransient || wheelarea.active
|
||||
}
|
||||
function flash() {
|
||||
if (hscrollbar.isTransient) {
|
||||
hscrollbar.__panel.on = true
|
||||
hscrollbar.__panel.visible = true
|
||||
hFlasher.start()
|
||||
}
|
||||
}
|
||||
Timer {
|
||||
id: hFlasher
|
||||
interval: 10
|
||||
onTriggered: hscrollbar.__panel.on = false
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar {
|
||||
id: vscrollbar
|
||||
isTransient: !!__panel && !!__panel.isTransient
|
||||
active: !!__panel && (__panel.sunken || __panel.activeControl !== "none")
|
||||
enabled: !isTransient || __panel.visible
|
||||
orientation: Qt.Vertical
|
||||
visible: verticalScrollBarPolicy == Qt.ScrollBarAsNeeded ? (contentHeight > availableHeight) : verticalScrollBarPolicy == Qt.ScrollBarAlwaysOn
|
||||
width: visible ? implicitWidth : 0
|
||||
z: 1
|
||||
anchors.bottom: cornerFill.top
|
||||
maximumValue: contentHeight > availableHeight ? originY + contentHeight - availableHeight + __viewTopMargin : 0
|
||||
minimumValue: originY
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: __scrollBarTopMargin + topMargin
|
||||
anchors.rightMargin: rightMargin
|
||||
onValueChanged: {
|
||||
if (flickableItem && !blockUpdates && enabled) {
|
||||
flickableItem.contentY = value
|
||||
}
|
||||
}
|
||||
Binding {
|
||||
target: vscrollbar.__panel
|
||||
property: "raised"
|
||||
value: hscrollbar.active || wheelarea.active
|
||||
when: vscrollbar.isTransient
|
||||
}
|
||||
Binding {
|
||||
target: vscrollbar.__panel
|
||||
property: "visible"
|
||||
value: true
|
||||
when: !vscrollbar.isTransient || wheelarea.active
|
||||
}
|
||||
function flash() {
|
||||
if (vscrollbar.isTransient) {
|
||||
vscrollbar.__panel.on = true
|
||||
vscrollbar.__panel.visible = true
|
||||
vFlasher.start()
|
||||
}
|
||||
}
|
||||
Timer {
|
||||
id: vFlasher
|
||||
interval: 10
|
||||
onTriggered: vscrollbar.__panel.on = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,137 +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.2
|
||||
|
||||
Item {
|
||||
id: rootItem
|
||||
property variant input
|
||||
property variant output
|
||||
property variant sourceRect
|
||||
visible: false
|
||||
|
||||
Component.onCompleted: evaluateInput()
|
||||
|
||||
onInputChanged: evaluateInput()
|
||||
|
||||
onSourceRectChanged: evaluateInput()
|
||||
|
||||
function evaluateInput() {
|
||||
if (input == undefined) {
|
||||
output = input
|
||||
}
|
||||
else if (sourceRect != undefined && sourceRect != Qt.rect(0, 0, 0, 0) && !isQQuickShaderEffectSource(input)) {
|
||||
proxySource.sourceItem = input
|
||||
output = proxySource
|
||||
proxySource.sourceRect = sourceRect
|
||||
}
|
||||
else if (isQQuickItemLayerEnabled(input)) {
|
||||
output = input
|
||||
}
|
||||
else if ((isQQuickImage(input) && !hasTileMode(input) && !hasChildren(input))) {
|
||||
output = input
|
||||
}
|
||||
else if (isQQuickShaderEffectSource(input)) {
|
||||
output = input
|
||||
}
|
||||
else {
|
||||
proxySource.sourceItem = input
|
||||
output = proxySource
|
||||
proxySource.sourceRect = Qt.rect(0, 0, 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
function isQQuickItemLayerEnabled(item) {
|
||||
if (item.hasOwnProperty("layer")) {
|
||||
var l = item["layer"]
|
||||
if (l.hasOwnProperty("enabled") && l["enabled"].toString() == "true")
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function isQQuickImage(item) {
|
||||
var imageProperties = [ "fillMode", "progress", "asynchronous", "sourceSize", "status", "smooth" ]
|
||||
return hasProperties(item, imageProperties)
|
||||
}
|
||||
|
||||
function isQQuickShaderEffectSource(item) {
|
||||
var shaderEffectSourceProperties = [ "hideSource", "format", "sourceItem", "mipmap", "wrapMode", "live", "recursive", "sourceRect" ]
|
||||
return hasProperties(item, shaderEffectSourceProperties)
|
||||
}
|
||||
|
||||
function hasProperties(item, properties) {
|
||||
var counter = 0
|
||||
for (var j = 0; j < properties.length; j++) {
|
||||
if (item.hasOwnProperty(properties [j]))
|
||||
counter++
|
||||
}
|
||||
return properties.length == counter
|
||||
}
|
||||
|
||||
function hasChildren(item) {
|
||||
if (item.hasOwnProperty("childrenRect")) {
|
||||
if (item["childrenRect"].toString() != "QRectF(0, 0, 0, 0)")
|
||||
return true
|
||||
else
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function hasTileMode(item) {
|
||||
if (item.hasOwnProperty("fillMode")) {
|
||||
if (item["fillMode"].toString() != "0")
|
||||
return true
|
||||
else
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
ShaderEffectSource {
|
||||
id: proxySource
|
||||
live: rootItem.input != rootItem.output
|
||||
hideSource: false
|
||||
smooth: true
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +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:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
var stackView = [];
|
||||
|
||||
function push(p)
|
||||
{
|
||||
if (!p)
|
||||
return
|
||||
stackView.push(p)
|
||||
__depth++
|
||||
return p
|
||||
}
|
||||
|
||||
function pop()
|
||||
{
|
||||
if (stackView.length === 0)
|
||||
return null
|
||||
var p = stackView.pop()
|
||||
__depth--
|
||||
return p
|
||||
}
|
||||
|
||||
function current()
|
||||
{
|
||||
if (stackView.length === 0)
|
||||
return null
|
||||
return stackView[stackView.length-1]
|
||||
}
|
||||
|
||||
@@ -1,142 +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
|
||||
|
||||
/*!
|
||||
\qmltype StackViewSlideTransition
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
StackViewDelegate {
|
||||
id: root
|
||||
|
||||
property bool horizontal: true
|
||||
|
||||
function getTransition(properties)
|
||||
{
|
||||
return root[horizontal ? "horizontalSlide" : "verticalSlide"][properties.name]
|
||||
}
|
||||
|
||||
function transitionFinished(properties)
|
||||
{
|
||||
properties.exitItem.x = 0
|
||||
properties.exitItem.y = 0
|
||||
}
|
||||
|
||||
property QtObject horizontalSlide: QtObject {
|
||||
property Component pushTransition: StackViewTransition {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "x"
|
||||
from: target.width
|
||||
to: 0
|
||||
duration: 400
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "x"
|
||||
from: 0
|
||||
to: -target.width
|
||||
duration: 400
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
property Component popTransition: StackViewTransition {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "x"
|
||||
from: -target.width
|
||||
to: 0
|
||||
duration: 400
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "x"
|
||||
from: 0
|
||||
to: target.width
|
||||
duration: 400
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
property Component replaceTransition: pushTransition
|
||||
}
|
||||
|
||||
property QtObject verticalSlide: QtObject {
|
||||
property Component pushTransition: StackViewTransition {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "y"
|
||||
from: target.height
|
||||
to: 0
|
||||
duration: 300
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "y"
|
||||
from: 0
|
||||
to: -target.height
|
||||
duration: 300
|
||||
}
|
||||
}
|
||||
|
||||
property Component popTransition: StackViewTransition {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "y"
|
||||
from: -target.height
|
||||
to: 0
|
||||
duration: 300
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "y"
|
||||
from: 0
|
||||
to: target.height
|
||||
duration: 300
|
||||
}
|
||||
property Component replaceTransition: pushTransition
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,53 +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 Style
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
|
||||
AbstractStyle {
|
||||
/*! The control this style is attached to. */
|
||||
readonly property Item control: __control
|
||||
}
|
||||
@@ -1,55 +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:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
pragma Singleton
|
||||
import QtQuick 2.2
|
||||
|
||||
QtObject {
|
||||
property SystemPalette active: SystemPalette { colorGroup: SystemPalette.Active }
|
||||
property SystemPalette disabled: SystemPalette { colorGroup: SystemPalette.Disabled }
|
||||
|
||||
function alternateBase(enabled) { return enabled ? active.alternateBase : disabled.alternateBase }
|
||||
function base(enabled) { return enabled ? active.base : disabled.base }
|
||||
function button(enabled) { return enabled ? active.button : disabled.button }
|
||||
function buttonText(enabled) { return enabled ? active.buttonText : disabled.buttonText }
|
||||
function dark(enabled) { return enabled ? active.dark : disabled.dark }
|
||||
function highlight(enabled) { return enabled ? active.highlight : disabled.highlight }
|
||||
function highlightedText(enabled) { return enabled ? active.highlightedText : disabled.highlightedText }
|
||||
function light(enabled) { return enabled ? active.light : disabled.light }
|
||||
function mid(enabled) { return enabled ? active.mid : disabled.mid }
|
||||
function midlight(enabled) { return enabled ? active.midlight : disabled.midlight }
|
||||
function shadow(enabled) { return enabled ? active.shadow : disabled.shadow }
|
||||
function text(enabled) { return enabled ? active.text : disabled.text }
|
||||
function window(enabled) { return enabled ? active.window : disabled.window }
|
||||
function windowText(enabled) { return enabled ? active.windowText : disabled.windowText }
|
||||
}
|
||||
@@ -1,329 +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 TabBar
|
||||
\internal
|
||||
\inqmlmodule QtQuick.Controls.Private
|
||||
*/
|
||||
FocusScope {
|
||||
id: tabbar
|
||||
height: Math.max(tabrow.height, Math.max(leftCorner.height, rightCorner.height))
|
||||
width: tabView.width
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
Keys.onRightPressed: {
|
||||
if (tabView && tabView.currentIndex < tabView.count - 1)
|
||||
tabView.currentIndex = tabView.currentIndex + 1
|
||||
}
|
||||
Keys.onLeftPressed: {
|
||||
if (tabView && tabView.currentIndex > 0)
|
||||
tabView.currentIndex = tabView.currentIndex - 1
|
||||
}
|
||||
|
||||
onTabViewChanged: parent = tabView
|
||||
visible: tabView ? tabView.tabsVisible : true
|
||||
|
||||
property var tabView
|
||||
property var style
|
||||
property var styleItem: tabView.__styleItem ? tabView.__styleItem : null
|
||||
|
||||
property bool tabsMovable: styleItem ? styleItem.tabsMovable : false
|
||||
|
||||
property int tabsAlignment: styleItem ? styleItem.tabsAlignment : Qt.AlignLeft
|
||||
|
||||
property int tabOverlap: styleItem ? styleItem.tabOverlap : 0
|
||||
|
||||
property int elide: Text.ElideRight
|
||||
|
||||
property real availableWidth: tabbar.width - leftCorner.width - rightCorner.width
|
||||
|
||||
property var __selectedTabRect
|
||||
|
||||
function tab(index) {
|
||||
for (var i = 0; i < tabrow.children.length; ++i) {
|
||||
if (tabrow.children[i].tabindex == index) {
|
||||
return tabrow.children[i]
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __isAncestorOf(item, child) {
|
||||
//TODO: maybe removed from 5.2 if the function was merged in qtdeclarative
|
||||
if (child === item)
|
||||
return false;
|
||||
|
||||
while (child) {
|
||||
child = child.parent;
|
||||
if (child === item)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Loader {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
sourceComponent: styleItem ? styleItem.tabBar : undefined
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: tabrow
|
||||
objectName: "tabrow"
|
||||
Accessible.role: Accessible.PageTabList
|
||||
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
|
||||
spacing: -tabOverlap
|
||||
orientation: Qt.Horizontal
|
||||
interactive: false
|
||||
focus: true
|
||||
|
||||
// Note this will silence the binding loop warnings caused by QTBUG-35038
|
||||
// and should be removed when this issue is resolved.
|
||||
property int contentWidthWorkaround: contentWidth > 0 ? contentWidth: 0
|
||||
width: Math.min(availableWidth, count ? contentWidthWorkaround : availableWidth)
|
||||
height: currentItem ? currentItem.height : 0
|
||||
|
||||
highlightMoveDuration: 0
|
||||
|
||||
// We cannot bind directly to the currentIndex because the actual model is
|
||||
// populated after the listview is completed, resulting in an invalid contentItem
|
||||
currentIndex: tabView.currentIndex < model.count ? tabView.currentIndex : -1
|
||||
onCurrentIndexChanged: tabrow.positionViewAtIndex(currentIndex, ListView.Contain)
|
||||
|
||||
moveDisplaced: Transition {
|
||||
NumberAnimation {
|
||||
property: "x"
|
||||
duration: 125
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "left"
|
||||
when: tabsAlignment === Qt.AlignLeft
|
||||
AnchorChanges { target:tabrow ; anchors.left: parent.left }
|
||||
PropertyChanges { target:tabrow ; anchors.leftMargin: leftCorner.width }
|
||||
},
|
||||
State {
|
||||
name: "center"
|
||||
when: tabsAlignment === Qt.AlignHCenter
|
||||
AnchorChanges { target:tabrow ; anchors.horizontalCenter: tabbar.horizontalCenter }
|
||||
},
|
||||
State {
|
||||
name: "right"
|
||||
when: tabsAlignment === Qt.AlignRight
|
||||
AnchorChanges { target:tabrow ; anchors.right: parent.right }
|
||||
PropertyChanges { target:tabrow ; anchors.rightMargin: rightCorner.width }
|
||||
}
|
||||
]
|
||||
|
||||
model: tabView.__tabs
|
||||
|
||||
delegate: MouseArea {
|
||||
id: tabitem
|
||||
objectName: "mousearea"
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
focus: true
|
||||
enabled: modelData.enabled
|
||||
|
||||
Binding {
|
||||
target: tabbar
|
||||
when: selected
|
||||
property: "__selectedTabRect"
|
||||
value: Qt.rect(x, y, width, height)
|
||||
}
|
||||
|
||||
drag.target: tabsMovable ? tabloader : null
|
||||
drag.axis: Drag.XAxis
|
||||
drag.minimumX: drag.active ? 0 : -Number.MAX_VALUE
|
||||
drag.maximumX: tabrow.width - tabitem.width
|
||||
|
||||
property int tabindex: index
|
||||
property bool selected : tabView.currentIndex === index
|
||||
property string title: modelData.title
|
||||
property bool nextSelected: tabView.currentIndex === index + 1
|
||||
property bool previousSelected: tabView.currentIndex === index - 1
|
||||
|
||||
property bool keyPressed: false
|
||||
property bool effectivePressed: pressed && containsMouse || keyPressed
|
||||
|
||||
z: selected ? 1 : -index
|
||||
implicitWidth: tabloader.implicitWidth
|
||||
implicitHeight: tabloader.implicitHeight
|
||||
|
||||
function changeTab() {
|
||||
tabView.currentIndex = index;
|
||||
var next = tabbar.nextItemInFocusChain(true);
|
||||
if (__isAncestorOf(tabView.getTab(currentIndex), next))
|
||||
next.forceActiveFocus();
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
if (tabrow.interactive) {
|
||||
changeTab()
|
||||
}
|
||||
}
|
||||
onPressed: {
|
||||
if (!tabrow.interactive) {
|
||||
changeTab()
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
if (event.key === Qt.Key_Space && !event.isAutoRepeat && !tabitem.pressed)
|
||||
tabitem.keyPressed = true
|
||||
}
|
||||
Keys.onReleased: {
|
||||
if (event.key === Qt.Key_Space && !event.isAutoRepeat && tabitem.keyPressed)
|
||||
tabitem.keyPressed = false
|
||||
}
|
||||
onFocusChanged: if (!focus) tabitem.keyPressed = false
|
||||
|
||||
Loader {
|
||||
id: tabloader
|
||||
|
||||
property Item control: tabView
|
||||
property int index: tabindex
|
||||
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias index: tabitem.tabindex
|
||||
readonly property alias selected: tabitem.selected
|
||||
readonly property alias title: tabitem.title
|
||||
readonly property alias nextSelected: tabitem.nextSelected
|
||||
readonly property alias previousSelected: tabitem.previousSelected
|
||||
readonly property alias pressed: tabitem.effectivePressed
|
||||
readonly property alias hovered: tabitem.containsMouse
|
||||
readonly property alias enabled: tabitem.enabled
|
||||
readonly property bool activeFocus: tabitem.activeFocus
|
||||
readonly property real availableWidth: tabbar.availableWidth
|
||||
readonly property real totalWidth: tabrow.contentWidth
|
||||
}
|
||||
|
||||
sourceComponent: loader.item ? loader.item.tab : null
|
||||
|
||||
Drag.keys: "application/x-tabbartab"
|
||||
Drag.active: tabitem.drag.active
|
||||
Drag.source: tabitem
|
||||
|
||||
property real __prevX: 0
|
||||
property real __dragX: 0
|
||||
onXChanged: {
|
||||
if (Drag.active) {
|
||||
// keep track for the snap back animation
|
||||
__dragX = tabitem.mapFromItem(tabrow, tabloader.x, 0).x
|
||||
|
||||
// when moving to the left, the hot spot is the left edge and vice versa
|
||||
Drag.hotSpot.x = x < __prevX ? 0 : width
|
||||
__prevX = x
|
||||
}
|
||||
}
|
||||
|
||||
width: tabitem.width
|
||||
state: Drag.active ? "drag" : ""
|
||||
|
||||
transitions: [
|
||||
Transition {
|
||||
to: "drag"
|
||||
PropertyAction { target: tabloader; property: "parent"; value: tabrow }
|
||||
},
|
||||
Transition {
|
||||
from: "drag"
|
||||
SequentialAnimation {
|
||||
PropertyAction { target: tabloader; property: "parent"; value: tabitem }
|
||||
NumberAnimation {
|
||||
target: tabloader
|
||||
duration: 50
|
||||
easing.type: Easing.OutQuad
|
||||
property: "x"
|
||||
from: tabloader.__dragX
|
||||
to: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Accessible.role: Accessible.PageTab
|
||||
Accessible.name: modelData.title
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: leftCorner
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
sourceComponent: styleItem ? styleItem.leftCorner : undefined
|
||||
width: item ? item.implicitWidth : 0
|
||||
height: item ? item.implicitHeight : 0
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: rightCorner
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
sourceComponent: styleItem ? styleItem.rightCorner : undefined
|
||||
width: item ? item.implicitWidth : 0
|
||||
height: item ? item.implicitHeight : 0
|
||||
}
|
||||
|
||||
DropArea {
|
||||
anchors.fill: tabrow
|
||||
keys: "application/x-tabbartab"
|
||||
onPositionChanged: {
|
||||
var source = drag.source
|
||||
var target = tabrow.itemAt(drag.x, drag.y)
|
||||
if (source && target && source !== target) {
|
||||
source = source.drag.target
|
||||
target = target.drag.target
|
||||
var center = target.parent.x + target.width / 2
|
||||
if ((source.index > target.index && source.x < center)
|
||||
|| (source.index < target.index && source.x + source.width > center))
|
||||
tabView.moveTab(source.index, target.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,197 +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
|
||||
|
||||
QtObject {
|
||||
|
||||
property int count: 0
|
||||
signal selectionChanged
|
||||
|
||||
property bool __dirty: false
|
||||
property var __ranges: []
|
||||
|
||||
function forEach (callback) {
|
||||
if (!(callback instanceof Function)) {
|
||||
console.warn("TableViewSelection.forEach: argument is not a function")
|
||||
return;
|
||||
}
|
||||
__forEach(callback, -1)
|
||||
}
|
||||
|
||||
function contains(index) {
|
||||
for (var i = 0 ; i < __ranges.length ; ++i) {
|
||||
if (__ranges[i][0] <= index && index <= __ranges[i][1])
|
||||
return true;
|
||||
else if (__ranges[i][0] > index)
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function clear() {
|
||||
__ranges = []
|
||||
__dirty = true
|
||||
count = 0
|
||||
selectionChanged()
|
||||
}
|
||||
|
||||
function selectAll() { select(0, rowCount - 1) }
|
||||
function select(first, last) { __select(true, first, last) }
|
||||
function deselect(first, last) { __select(false, first, last) }
|
||||
|
||||
// --- private section ---
|
||||
|
||||
function __printRanges() {
|
||||
var out = ""
|
||||
for (var i = 0 ; i < __ranges.length ; ++ i)
|
||||
out += ("{" + __ranges[i][0] + "," + __ranges[i][1] + "} ")
|
||||
print(out)
|
||||
}
|
||||
|
||||
function __count() {
|
||||
var sum = 0
|
||||
for (var i = 0 ; i < __ranges.length ; ++i) {
|
||||
sum += (1 + __ranges[i][1] - __ranges[i][0])
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
function __forEach (callback, startIndex) {
|
||||
__dirty = false
|
||||
var i, j
|
||||
|
||||
for (i = 0 ; i < __ranges.length && !__dirty ; ++i) {
|
||||
for (j = __ranges[i][0] ; !__dirty && j <= __ranges[i][1] ; ++j) {
|
||||
if (j >= startIndex)
|
||||
callback.call(this, j)
|
||||
}
|
||||
}
|
||||
|
||||
// Restart iteration at last index if selection changed
|
||||
if (__dirty)
|
||||
return __forEach(callback, j)
|
||||
}
|
||||
|
||||
function __selectOne(index) {
|
||||
__ranges = [[index, index]]
|
||||
__dirty = true
|
||||
count = 1
|
||||
selectionChanged();
|
||||
}
|
||||
|
||||
function __select(select, first, last) {
|
||||
|
||||
var i, range
|
||||
var start = first
|
||||
var stop = first
|
||||
var startRangeIndex = -1
|
||||
var stopRangeIndex = -1
|
||||
var newRangePos = 0
|
||||
|
||||
if (first < 0 || last < 0 || first >= rowCount || last >=rowCount) {
|
||||
console.warn("TableViewSelection: index out of range")
|
||||
return
|
||||
}
|
||||
|
||||
if (last !== undefined) {
|
||||
start = first <= last ? first : last
|
||||
stop = first <= last ? last : first
|
||||
}
|
||||
|
||||
if (select) {
|
||||
|
||||
// Find beginning and end ranges
|
||||
for (i = 0 ; i < __ranges.length; ++ i) {
|
||||
range = __ranges[i]
|
||||
if (range[0] > stop + 1) continue; // above range
|
||||
if (range[1] < start - 1) { // below range
|
||||
newRangePos = i + 1
|
||||
continue;
|
||||
}
|
||||
if (startRangeIndex === -1)
|
||||
startRangeIndex = i
|
||||
stopRangeIndex = i
|
||||
}
|
||||
|
||||
if (startRangeIndex !== -1)
|
||||
start = Math.min(__ranges[startRangeIndex][0], start)
|
||||
if (stopRangeIndex !== -1)
|
||||
stop = Math.max(__ranges[stopRangeIndex][1], stop)
|
||||
|
||||
if (startRangeIndex === -1)
|
||||
startRangeIndex = newRangePos
|
||||
|
||||
__ranges.splice(Math.max(0, startRangeIndex),
|
||||
1 + stopRangeIndex - startRangeIndex, [start, stop])
|
||||
|
||||
} else {
|
||||
|
||||
// Find beginning and end ranges
|
||||
for (i = 0 ; i < __ranges.length; ++ i) {
|
||||
range = __ranges[i]
|
||||
if (range[1] < start) continue; // below range
|
||||
if (range[0] > stop) continue; // above range
|
||||
if (startRangeIndex === -1)
|
||||
startRangeIndex = i
|
||||
stopRangeIndex = i
|
||||
}
|
||||
|
||||
// Slice ranges accordingly
|
||||
if (startRangeIndex >= 0 && stopRangeIndex >= 0) {
|
||||
var startRange = __ranges[startRangeIndex]
|
||||
var stopRange = __ranges[stopRangeIndex]
|
||||
var length = 1 + stopRangeIndex - startRangeIndex
|
||||
if (start <= startRange[0] && stop >= stopRange[1]) { //remove
|
||||
__ranges.splice(startRangeIndex, length)
|
||||
} else if (start - 1 < startRange[0] && stop <= stopRange[1]) { //cut front
|
||||
__ranges.splice(startRangeIndex, length, [stop + 1, stopRange[1]])
|
||||
} else if (start - 1 < startRange[1] && stop >= stopRange[1]) { // cut back
|
||||
__ranges.splice(startRangeIndex, length, [startRange[0], start - 1])
|
||||
} else { //split
|
||||
__ranges.splice(startRangeIndex, length, [startRange[0], start - 1], [stop + 1, stopRange[1]])
|
||||
}
|
||||
}
|
||||
}
|
||||
__dirty = true
|
||||
count = __count() // forces a re-evaluation of indexes in the delegates
|
||||
selectionChanged()
|
||||
}
|
||||
}
|
||||
@@ -1,126 +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 {
|
||||
id: handle
|
||||
|
||||
property Item editor
|
||||
property int minimum: -1
|
||||
property int maximum: -1
|
||||
property int position: -1
|
||||
property alias delegate: handle.sourceComponent
|
||||
|
||||
readonly property alias pressed: mouse.pressed
|
||||
|
||||
readonly property real handleX: x + (item ? item.x : 0)
|
||||
readonly property real handleY: y + (item ? item.y : 0)
|
||||
readonly property real handleWidth: item ? item.width : 0
|
||||
readonly property real handleHeight: item ? item.height : 0
|
||||
|
||||
property Item control
|
||||
property QtObject styleData: QtObject {
|
||||
id: styleData
|
||||
signal activated()
|
||||
readonly property alias pressed: mouse.pressed
|
||||
readonly property alias position: handle.position
|
||||
readonly property bool hasSelection: editor.selectionStart !== editor.selectionEnd
|
||||
readonly property real lineHeight: position !== -1 ? editor.positionToRectangle(position).height
|
||||
: editor.cursorRectangle.height
|
||||
}
|
||||
|
||||
function activate() {
|
||||
styleData.activated()
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouse
|
||||
anchors.fill: item
|
||||
enabled: item && item.visible
|
||||
preventStealing: true
|
||||
property real pressX
|
||||
property point offset
|
||||
property bool handleDragged: false
|
||||
|
||||
onPressed: {
|
||||
Qt.inputMethod.commit()
|
||||
handleDragged = false
|
||||
pressX = mouse.x
|
||||
var handleRect = editor.positionToRectangle(handle.position)
|
||||
var centerX = handleRect.x + (handleRect.width / 2)
|
||||
var centerY = handleRect.y + (handleRect.height / 2)
|
||||
var center = mapFromItem(editor, centerX, centerY)
|
||||
offset = Qt.point(mouseX - center.x, mouseY - center.y)
|
||||
}
|
||||
onReleased: {
|
||||
if (!handleDragged) {
|
||||
// The user just clicked on the handle. In that
|
||||
// case clear the selection.
|
||||
var mousePos = editor.mapFromItem(item, mouse.x, mouse.y)
|
||||
var editorPos = editor.positionAt(mousePos.x, mousePos.y)
|
||||
editor.select(editorPos, editorPos)
|
||||
}
|
||||
}
|
||||
onPositionChanged: {
|
||||
handleDragged = true
|
||||
var pt = mapToItem(editor, mouse.x - offset.x, mouse.y - offset.y)
|
||||
|
||||
// limit vertically within mix/max coordinates or content bounds
|
||||
var min = (minimum !== -1) ? minimum : 0
|
||||
var max = (maximum !== -1) ? maximum : editor.length
|
||||
pt.y = Math.max(pt.y, editor.positionToRectangle(min).y)
|
||||
pt.y = Math.min(pt.y, editor.positionToRectangle(max).y)
|
||||
|
||||
var pos = editor.positionAt(pt.x, pt.y)
|
||||
|
||||
// limit horizontally within min/max character positions
|
||||
if (minimum !== -1)
|
||||
pos = Math.max(pos, minimum)
|
||||
pos = Math.max(pos, 0)
|
||||
if (maximum !== -1)
|
||||
pos = Math.min(pos, maximum)
|
||||
pos = Math.min(pos, editor.length)
|
||||
|
||||
handle.position = pos
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,185 +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.Private 1.0
|
||||
|
||||
TextInput {
|
||||
id: input
|
||||
|
||||
property Item control
|
||||
property alias cursorHandle: cursorHandle.delegate
|
||||
property alias selectionHandle: selectionHandle.delegate
|
||||
|
||||
property bool blockRecursion: false
|
||||
property bool hasSelection: selectionStart !== selectionEnd
|
||||
readonly property int selectionPosition: selectionStart !== cursorPosition ? selectionStart : selectionEnd
|
||||
readonly property alias containsMouse: mouseArea.containsMouse
|
||||
property alias editMenu: editMenu
|
||||
cursorDelegate: __style && __style.__cursorDelegate ? __style.__cursorDelegate : null
|
||||
|
||||
selectByMouse: control.selectByMouse && (!Settings.isMobile || !cursorHandle.delegate || !selectionHandle.delegate)
|
||||
|
||||
// force re-evaluation when selection moves:
|
||||
// - cursorRectangle changes => content scrolled
|
||||
// - contentWidth changes => text layout changed
|
||||
property rect selectionRectangle: cursorRectangle.x && contentWidth ? positionToRectangle(selectionPosition)
|
||||
: positionToRectangle(selectionPosition)
|
||||
|
||||
onSelectionStartChanged: syncHandlesWithSelection()
|
||||
onCursorPositionChanged: syncHandlesWithSelection()
|
||||
|
||||
function syncHandlesWithSelection()
|
||||
{
|
||||
if (!blockRecursion && selectionHandle.delegate) {
|
||||
blockRecursion = true
|
||||
// We cannot use property selectionPosition since it gets updated after onSelectionStartChanged
|
||||
cursorHandle.position = cursorPosition
|
||||
selectionHandle.position = (selectionStart !== cursorPosition) ? selectionStart : selectionEnd
|
||||
blockRecursion = false
|
||||
}
|
||||
TextSingleton.updateSelectionItem(input)
|
||||
}
|
||||
|
||||
function activate() {
|
||||
if (activeFocusOnPress) {
|
||||
forceActiveFocus()
|
||||
if (!readOnly)
|
||||
Qt.inputMethod.show()
|
||||
}
|
||||
cursorHandle.activate()
|
||||
selectionHandle.activate()
|
||||
}
|
||||
|
||||
function moveHandles(cursor, selection) {
|
||||
blockRecursion = true
|
||||
cursorPosition = cursor
|
||||
if (selection === -1) {
|
||||
selectWord()
|
||||
selection = selectionStart
|
||||
}
|
||||
selectionHandle.position = selection
|
||||
cursorHandle.position = cursorPosition
|
||||
blockRecursion = false
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
cursorShape: Qt.IBeamCursor
|
||||
acceptedButtons: (input.selectByMouse ? Qt.NoButton : Qt.LeftButton) | (control.menu ? Qt.RightButton : Qt.NoButton)
|
||||
onClicked: {
|
||||
if (editMenu.item)
|
||||
return;
|
||||
var pos = input.positionAt(mouse.x, mouse.y)
|
||||
input.moveHandles(pos, pos)
|
||||
input.activate()
|
||||
}
|
||||
onPressAndHold: {
|
||||
if (editMenu.item)
|
||||
return;
|
||||
var pos = input.positionAt(mouse.x, mouse.y)
|
||||
input.moveHandles(pos, control.selectByMouse ? -1 : pos)
|
||||
input.activate()
|
||||
}
|
||||
}
|
||||
|
||||
EditMenu {
|
||||
id: editMenu
|
||||
input: parent
|
||||
mouseArea: mouseArea
|
||||
control: parent.control
|
||||
cursorHandle: cursorHandle
|
||||
selectionHandle: selectionHandle
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
TextHandle {
|
||||
id: selectionHandle
|
||||
|
||||
editor: input
|
||||
parent: control
|
||||
control: input.control
|
||||
active: control.selectByMouse && Settings.isMobile
|
||||
maximum: cursorHandle.position - 1
|
||||
|
||||
property var mappedPos: parent.mapFromItem(editor, editor.selectionRectangle.x, editor.selectionRectangle.y)
|
||||
x: mappedPos.x
|
||||
y: mappedPos.y
|
||||
|
||||
visible: pressed || (input.hasSelection && handleX + handleWidth >= -1 && handleX <= control.width + 1)
|
||||
|
||||
onPositionChanged: {
|
||||
if (!input.blockRecursion) {
|
||||
input.blockRecursion = true
|
||||
input.select(selectionHandle.position, cursorHandle.position)
|
||||
if (pressed)
|
||||
input.ensureVisible(position)
|
||||
input.blockRecursion = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextHandle {
|
||||
id: cursorHandle
|
||||
|
||||
editor: input
|
||||
parent: control
|
||||
control: input.control
|
||||
active: control.selectByMouse && Settings.isMobile
|
||||
minimum: input.hasSelection ? selectionHandle.position + 1 : -1
|
||||
|
||||
property var mappedPos: parent.mapFromItem(editor, editor.cursorRectangle.x, editor.cursorRectangle.y)
|
||||
x: mappedPos.x
|
||||
y: mappedPos.y
|
||||
|
||||
visible: pressed || ((input.cursorVisible || input.hasSelection) && handleX + handleWidth >= -1 && handleX <= control.width + 1)
|
||||
|
||||
onPositionChanged: {
|
||||
if (!input.blockRecursion) {
|
||||
input.blockRecursion = true
|
||||
if (!input.hasSelection)
|
||||
selectionHandle.position = cursorHandle.position
|
||||
input.select(selectionHandle.position, cursorHandle.position)
|
||||
input.blockRecursion = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +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:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
pragma Singleton
|
||||
import QtQuick 2.2
|
||||
Text {
|
||||
/**
|
||||
selectionItem is the item that currently has a text selection. On some platforms
|
||||
(iOS) you can select text without activating the input field. This means that
|
||||
selectionItem can be different from item with active focus on those platforms.
|
||||
*/
|
||||
property Item selectionItem: null
|
||||
|
||||
function updateSelectionItem(item)
|
||||
{
|
||||
// Convenience function to check if we should transfer or
|
||||
// remove selectionItem status from item.
|
||||
var selection = item.selectionStart !== item.selectionEnd
|
||||
if (item === selectionItem) {
|
||||
if (!selection)
|
||||
selectionItem = null
|
||||
} else if (selection) {
|
||||
if (selectionItem)
|
||||
selectionItem.select(selectionItem.cursorPosition, selectionItem.cursorPosition)
|
||||
selectionItem = item
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,125 +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.4
|
||||
import QtQuick.Controls 1.3
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
FocusScope {
|
||||
id: button
|
||||
|
||||
property Menu menu
|
||||
readonly property bool pressed: behavior.containsPress || behavior.keyPressed
|
||||
readonly property alias hovered: behavior.containsMouse
|
||||
|
||||
property alias panel: loader.sourceComponent
|
||||
property alias __panel: loader.item
|
||||
|
||||
activeFocusOnTab: true
|
||||
Accessible.role: Accessible.Button
|
||||
implicitWidth: __panel ? __panel.implicitWidth : 0
|
||||
implicitHeight: __panel ? __panel.implicitHeight : 0
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
anchors.fill: parent
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias pressed: button.pressed
|
||||
readonly property alias hovered: button.hovered
|
||||
readonly property alias activeFocus: button.activeFocus
|
||||
}
|
||||
onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", button)
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
if (event.key === Qt.Key_Space && !event.isAutoRepeat && !behavior.keyPressed)
|
||||
behavior.keyPressed = true
|
||||
}
|
||||
Keys.onReleased: {
|
||||
if (event.key === Qt.Key_Space && !event.isAutoRepeat && behavior.keyPressed)
|
||||
behavior.keyPressed = false
|
||||
}
|
||||
onFocusChanged: {
|
||||
if (!focus)
|
||||
behavior.keyPressed = false
|
||||
}
|
||||
onPressedChanged: {
|
||||
if (!Settings.hasTouchScreen && !pressed && menu)
|
||||
popupMenuTimer.start()
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: behavior
|
||||
property bool keyPressed: false
|
||||
|
||||
anchors.fill: parent
|
||||
enabled: !keyPressed
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
|
||||
onReleased: {
|
||||
if (Settings.hasTouchScreen && containsMouse && menu)
|
||||
popupMenuTimer.start()
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: popupMenuTimer
|
||||
interval: 10
|
||||
onTriggered: {
|
||||
behavior.keyPressed = false
|
||||
if (Qt.application.layoutDirection === Qt.RightToLeft)
|
||||
menu.__popup(Qt.rect(button.width, button.height, 0, 0), 0)
|
||||
else
|
||||
menu.__popup(Qt.rect(0, 0, button.width, button.height), 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: menu
|
||||
property: "__minimumWidth"
|
||||
value: button.width
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: menu
|
||||
property: "__visualItem"
|
||||
value: button
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
module QtQuick.Controls.Private
|
||||
AbstractCheckable 1.0 AbstractCheckable.qml
|
||||
CalendarHeaderModel 1.0 CalendarHeaderModel.qml
|
||||
Control 1.0 Control.qml
|
||||
CalendarUtils 1.0 CalendarUtils.js
|
||||
FocusFrame 1.0 FocusFrame.qml
|
||||
Margins 1.0 Margins.qml
|
||||
BasicButton 1.0 BasicButton.qml
|
||||
ScrollBar 1.0 ScrollBar.qml
|
||||
ScrollViewHelper 1.0 ScrollViewHelper.qml
|
||||
Style 1.0 Style.qml
|
||||
MenuItemSubControls 1.0 MenuItemSubControls.qml
|
||||
TabBar 1.0 TabBar.qml
|
||||
StackViewSlideDelegate 1.0 StackViewSlideDelegate.qml
|
||||
StyleHelpers 1.0 style.js
|
||||
JSArray 1.0 StackView.js
|
||||
TableViewSelection 1.0 TableViewSelection.qml
|
||||
FastGlow 1.0 FastGlow.qml
|
||||
SourceProxy 1.0 SourceProxy.qml
|
||||
GroupBoxStyle 1.0 ../Styles/Base/GroupBoxStyle.qml
|
||||
FocusFrameStyle 1.0 ../Styles/Base/FocusFrameStyle.qml
|
||||
ToolButtonStyle 1.0 ../Styles/Base/ToolButtonStyle.qml
|
||||
MenuContentItem 1.0 MenuContentItem.qml
|
||||
MenuContentScroller 1.0 MenuContentScroller.qml
|
||||
ColumnMenuContent 1.0 ColumnMenuContent.qml
|
||||
ContentItem 1.0 ContentItem.qml
|
||||
HoverButton 1.0 HoverButton.qml
|
||||
singleton SystemPaletteSingleton 1.0 SystemPaletteSingleton.qml
|
||||
singleton TextSingleton 1.0 TextSingleton.qml
|
||||
TextHandle 1.0 TextHandle.qml
|
||||
TextInputWithHandles 1.0 TextInputWithHandles.qml
|
||||
EditMenu 1.0 EditMenu.qml
|
||||
EditMenu_base 1.0 EditMenu_base.qml
|
||||
EditMenu_ios 1.0 EditMenu_ios.qml
|
||||
ToolMenuButton 1.0 ToolMenuButton.qml
|
||||
@@ -1,63 +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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
.pragma library
|
||||
|
||||
function underlineAmpersands(match, p1, p2, p3) {
|
||||
if (p2 === "&")
|
||||
return p1.concat(p2, p3)
|
||||
return p1.concat("<u>", p2, "</u>", p3)
|
||||
}
|
||||
|
||||
function removeAmpersands(match, p1, p2, p3) {
|
||||
return p1.concat(p2, p3)
|
||||
}
|
||||
|
||||
function replaceAmpersands(text, replaceFunction) {
|
||||
return text.replace(/([^&]*)&(.)([^&]*)/g, replaceFunction)
|
||||
}
|
||||
|
||||
function stylizeMnemonics(text) {
|
||||
return replaceAmpersands(text, underlineAmpersands)
|
||||
}
|
||||
|
||||
function removeMnemonics(text) {
|
||||
return replaceAmpersands(text, removeAmpersands)
|
||||
}
|
||||
@@ -1,168 +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 ProgressBar
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup controls
|
||||
\brief A progress indicator.
|
||||
|
||||
\image progressbar.png
|
||||
|
||||
The ProgressBar is used to give an indication of the progress of an operation.
|
||||
\l value is updated regularly and must be between \l minimumValue and \l maximumValue.
|
||||
|
||||
\code
|
||||
Column {
|
||||
ProgressBar {
|
||||
value: 0.5
|
||||
}
|
||||
ProgressBar {
|
||||
indeterminate: true
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
You can create a custom appearance for a ProgressBar by
|
||||
assigning a \l {QtQuick.Controls.Styles::ProgressBarStyle}{ProgressBarStyle}.
|
||||
*/
|
||||
|
||||
Control {
|
||||
id: progressbar
|
||||
|
||||
/*! This property holds the progress bar's current value.
|
||||
Attempting to change the current value to one outside the minimum-maximum
|
||||
range has no effect on the current value.
|
||||
|
||||
The default value is \c{0}.
|
||||
*/
|
||||
property real value: 0
|
||||
|
||||
/*! This property is the progress bar's minimum value.
|
||||
The \l value is clamped to this value.
|
||||
The default value is \c{0}.
|
||||
*/
|
||||
property real minimumValue: 0
|
||||
|
||||
/*! This property is the progress bar's maximum value.
|
||||
The \l value is clamped to this value.
|
||||
If maximumValue is smaller than \l minimumValue, \l minimumValue will be enforced.
|
||||
The default value is \c{1}.
|
||||
*/
|
||||
property real maximumValue: 1
|
||||
|
||||
/*! This property toggles indeterminate mode.
|
||||
When the actual progress is unknown, use this option.
|
||||
The progress bar will be animated as a busy indicator instead.
|
||||
The default value is \c false.
|
||||
*/
|
||||
property bool indeterminate: false
|
||||
|
||||
/*! \qmlproperty enumeration orientation
|
||||
|
||||
This property holds the orientation of the progress bar.
|
||||
|
||||
\list
|
||||
\li Qt.Horizontal - Horizontal orientation. (Default)
|
||||
\li Qt.Vertical - Vertical orientation.
|
||||
\endlist
|
||||
*/
|
||||
property int orientation: Qt.Horizontal
|
||||
|
||||
/*! \qmlproperty bool ProgressBar::hovered
|
||||
|
||||
This property indicates whether the control is being hovered.
|
||||
*/
|
||||
readonly property alias hovered: hoverArea.containsMouse
|
||||
|
||||
/*! \internal */
|
||||
style: Qt.createComponent(Settings.style + "/ProgressBarStyle.qml", progressbar)
|
||||
|
||||
/*! \internal */
|
||||
property bool __initialized: false
|
||||
/*! \internal */
|
||||
onMaximumValueChanged: setValue(value)
|
||||
/*! \internal */
|
||||
onMinimumValueChanged: setValue(value)
|
||||
/*! \internal */
|
||||
onValueChanged: if (__initialized) setValue(value)
|
||||
/*! \internal */
|
||||
Component.onCompleted: {
|
||||
__initialized = true;
|
||||
setValue(value)
|
||||
}
|
||||
|
||||
activeFocusOnTab: false
|
||||
|
||||
Accessible.role: Accessible.ProgressBar
|
||||
Accessible.name: value
|
||||
|
||||
implicitWidth:(__panel ? __panel.implicitWidth : 0)
|
||||
implicitHeight: (__panel ? __panel.implicitHeight: 0)
|
||||
|
||||
MouseArea {
|
||||
id: hoverArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function setValue(v) {
|
||||
var newval = parseFloat(v)
|
||||
if (!isNaN(newval)) {
|
||||
// we give minimumValue priority over maximum if they are inconsistent
|
||||
if (newval > maximumValue) {
|
||||
if (maximumValue >= minimumValue)
|
||||
newval = maximumValue;
|
||||
else
|
||||
newval = minimumValue
|
||||
} else if (v < minimumValue) {
|
||||
newval = minimumValue
|
||||
}
|
||||
if (value !== newval)
|
||||
value = newval
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,100 +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 RadioButton
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup controls
|
||||
\brief A radio button with a text label.
|
||||
|
||||
\image radiobutton.png
|
||||
|
||||
A RadioButton is an option button that can be switched on (checked) or off
|
||||
(unchecked). Radio buttons typically present the user with a "one of many"
|
||||
choices. In a group of radio buttons, only one radio button can be
|
||||
checked at a time; if the user selects another button, the previously
|
||||
selected button is switched off.
|
||||
|
||||
\qml
|
||||
GroupBox {
|
||||
title: "Tab Position"
|
||||
|
||||
RowLayout {
|
||||
ExclusiveGroup { id: tabPositionGroup }
|
||||
RadioButton {
|
||||
text: "Top"
|
||||
checked: true
|
||||
exclusiveGroup: tabPositionGroup
|
||||
}
|
||||
RadioButton {
|
||||
text: "Bottom"
|
||||
exclusiveGroup: tabPositionGroup
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
You can create a custom appearance for a RadioButton by
|
||||
assigning a \l {QtQuick.Controls.Styles::RadioButtonStyle}{RadioButtonStyle}.
|
||||
*/
|
||||
|
||||
AbstractCheckable {
|
||||
id: radioButton
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
Accessible.name: text
|
||||
Accessible.role: Accessible.RadioButton
|
||||
|
||||
/*!
|
||||
The style that should be applied to the radio button. Custom style
|
||||
components can be created with:
|
||||
|
||||
\codeline Qt.createComponent("path/to/style.qml", radioButtonId);
|
||||
*/
|
||||
style: Qt.createComponent(Settings.style + "/RadioButtonStyle.qml", radioButton)
|
||||
|
||||
__cycleStatesHandler: function() { checked = !checked; }
|
||||
}
|
||||
@@ -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 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 ScrollView
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup views
|
||||
\brief Provides a scrolling view within another Item.
|
||||
|
||||
\image scrollview.png
|
||||
|
||||
A ScrollView can be used either to replace a \l Flickable or decorate an
|
||||
existing \l Flickable. Depending on the platform, it will add scroll bars and
|
||||
a content frame.
|
||||
|
||||
Only one Item can be a direct child of the ScrollView and the child is implicitly anchored
|
||||
to fill the scroll view.
|
||||
|
||||
Example:
|
||||
\code
|
||||
ScrollView {
|
||||
Image { source: "largeImage.png" }
|
||||
}
|
||||
\endcode
|
||||
|
||||
In the previous example the Image item will implicitly get scroll behavior as if it was
|
||||
used within a \l Flickable. The width and height of the child item will be used to
|
||||
define the size of the content area.
|
||||
|
||||
Example:
|
||||
\code
|
||||
ScrollView {
|
||||
ListView {
|
||||
...
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
In this case the content size of the ScrollView will simply mirror that of its contained
|
||||
\l flickableItem.
|
||||
|
||||
You can create a custom appearance for a ScrollView by
|
||||
assigning a \l {QtQuick.Controls.Styles::ScrollViewStyle}{ScrollViewStyle}.
|
||||
*/
|
||||
|
||||
FocusScope {
|
||||
id: root
|
||||
|
||||
implicitWidth: 240
|
||||
implicitHeight: 150
|
||||
|
||||
/*!
|
||||
This property tells the ScrollView if it should render
|
||||
a frame around its content.
|
||||
|
||||
The default value is \c false.
|
||||
*/
|
||||
property bool frameVisible: false
|
||||
|
||||
/*! \qmlproperty enumeration ScrollView::horizontalScrollBarPolicy
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
This property holds the policy for showing the horizontal scrollbar.
|
||||
It can be any of the following values:
|
||||
\list
|
||||
\li Qt.ScrollBarAsNeeded
|
||||
\li Qt.ScrollBarAlwaysOff
|
||||
\li Qt.ScrollBarAlwaysOn
|
||||
\endlist
|
||||
|
||||
The default policy is \c Qt.ScrollBarAsNeeded.
|
||||
*/
|
||||
property alias horizontalScrollBarPolicy: scroller.horizontalScrollBarPolicy
|
||||
|
||||
/*! \qmlproperty enumeration ScrollView::verticalScrollBarPolicy
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
This property holds the policy for showing the vertical scrollbar.
|
||||
It can be any of the following values:
|
||||
\list
|
||||
\li Qt.ScrollBarAsNeeded
|
||||
\li Qt.ScrollBarAlwaysOff
|
||||
\li Qt.ScrollBarAlwaysOn
|
||||
\endlist
|
||||
|
||||
The default policy is \c Qt.ScrollBarAsNeeded.
|
||||
*/
|
||||
property alias verticalScrollBarPolicy: scroller.verticalScrollBarPolicy
|
||||
|
||||
/*!
|
||||
This property controls if there should be a highlight
|
||||
around the frame when the ScrollView has input focus.
|
||||
|
||||
The default value is \c false.
|
||||
|
||||
\note This property is only applicable on some platforms, such
|
||||
as Mac OS.
|
||||
*/
|
||||
property bool highlightOnFocus: false
|
||||
|
||||
/*!
|
||||
\qmlproperty Item ScrollView::viewport
|
||||
|
||||
The viewport determines the current "window" on the contentItem.
|
||||
In other words, it clips it and the size of the viewport tells you
|
||||
how much of the content area is visible.
|
||||
*/
|
||||
property alias viewport: viewportItem
|
||||
|
||||
/*!
|
||||
\qmlproperty Item ScrollView::flickableItem
|
||||
|
||||
The flickableItem of the ScrollView. If the contentItem provided
|
||||
to the ScrollView is a Flickable, it will be the \l contentItem.
|
||||
*/
|
||||
readonly property alias flickableItem: internal.flickableItem
|
||||
|
||||
/*!
|
||||
The contentItem of the ScrollView. This is set by the user.
|
||||
|
||||
Note that the definition of contentItem is somewhat different to that
|
||||
of a Flickable, where the contentItem is implicitly created.
|
||||
*/
|
||||
default property Item contentItem
|
||||
|
||||
/*! \internal */
|
||||
property Item __scroller: scroller
|
||||
/*! \internal */
|
||||
property alias __wheelAreaScrollSpeed: wheelArea.scrollSpeed
|
||||
/*! \internal */
|
||||
property int __scrollBarTopMargin: 0
|
||||
/*! \internal */
|
||||
property int __viewTopMargin: 0
|
||||
/*! \internal */
|
||||
property alias __horizontalScrollBar: scroller.horizontalScrollBar
|
||||
/*! \internal */
|
||||
property alias __verticalScrollBar: scroller.verticalScrollBar
|
||||
/*! \qmlproperty Component ScrollView::style
|
||||
|
||||
The style Component for this control.
|
||||
\sa {Qt Quick Controls Styles QML Types}
|
||||
|
||||
*/
|
||||
property Component style: Qt.createComponent(Settings.style + "/ScrollViewStyle.qml", root)
|
||||
|
||||
/*! \internal */
|
||||
property Style __style: styleLoader.item
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
onContentItemChanged: {
|
||||
|
||||
if (contentItem.hasOwnProperty("contentY") && // Check if flickable
|
||||
contentItem.hasOwnProperty("contentHeight")) {
|
||||
internal.flickableItem = contentItem // "Use content if it is a flickable
|
||||
internal.flickableItem.parent = viewportItem
|
||||
} else {
|
||||
internal.flickableItem = flickableComponent.createObject(viewportItem)
|
||||
contentItem.parent = internal.flickableItem.contentItem
|
||||
}
|
||||
internal.flickableItem.anchors.fill = viewportItem
|
||||
if (!Settings.hasTouchScreen)
|
||||
internal.flickableItem.interactive = false
|
||||
}
|
||||
|
||||
|
||||
children: Item {
|
||||
id: internal
|
||||
|
||||
property Flickable flickableItem
|
||||
|
||||
Loader {
|
||||
id: styleLoader
|
||||
sourceComponent: style
|
||||
onStatusChanged: {
|
||||
if (status === Loader.Error)
|
||||
console.error("Failed to load Style for", root)
|
||||
}
|
||||
property alias __control: root
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: flickableItem
|
||||
property: "contentHeight"
|
||||
when: contentItem !== flickableItem
|
||||
value: contentItem ? contentItem.height : 0
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: flickableItem
|
||||
when: contentItem !== flickableItem
|
||||
property: "contentWidth"
|
||||
value: contentItem ? contentItem.width : 0
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: flickableItem
|
||||
|
||||
onContentYChanged: {
|
||||
scroller.blockUpdates = true
|
||||
scroller.verticalScrollBar.value = flickableItem.contentY
|
||||
scroller.blockUpdates = false
|
||||
}
|
||||
|
||||
onContentXChanged: {
|
||||
scroller.blockUpdates = true
|
||||
scroller.horizontalScrollBar.value = flickableItem.contentX
|
||||
scroller.blockUpdates = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
Component {
|
||||
id: flickableComponent
|
||||
Flickable {}
|
||||
}
|
||||
|
||||
WheelArea {
|
||||
id: wheelArea
|
||||
parent: flickableItem
|
||||
z: -1
|
||||
// ### Note this is needed due to broken mousewheel behavior in Flickable.
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
property int acceleration: 40
|
||||
property int flickThreshold: Settings.dragThreshold
|
||||
property real speedThreshold: 3
|
||||
property real ignored: 0.001 // ## flick() does not work with 0 yVelocity
|
||||
property int maxFlick: 400
|
||||
|
||||
property bool horizontalRecursionGuard: false
|
||||
property bool verticalRecursionGuard: false
|
||||
|
||||
horizontalMinimumValue: flickableItem ? flickableItem.originX : 0
|
||||
horizontalMaximumValue: flickableItem ? flickableItem.originX + flickableItem.contentWidth - viewport.width : 0
|
||||
|
||||
verticalMinimumValue: flickableItem ? flickableItem.originY : 0
|
||||
verticalMaximumValue: flickableItem ? flickableItem.originY + flickableItem.contentHeight - viewport.height + __viewTopMargin : 0
|
||||
|
||||
Connections {
|
||||
target: flickableItem
|
||||
|
||||
onContentYChanged: {
|
||||
wheelArea.verticalRecursionGuard = true
|
||||
wheelArea.verticalValue = flickableItem.contentY
|
||||
wheelArea.verticalRecursionGuard = false
|
||||
}
|
||||
onContentXChanged: {
|
||||
wheelArea.horizontalRecursionGuard = true
|
||||
wheelArea.horizontalValue = flickableItem.contentX
|
||||
wheelArea.horizontalRecursionGuard = false
|
||||
}
|
||||
}
|
||||
|
||||
onVerticalValueChanged: {
|
||||
if (!verticalRecursionGuard) {
|
||||
if (flickableItem.contentY < flickThreshold && verticalDelta > speedThreshold) {
|
||||
flickableItem.flick(ignored, Math.min(maxFlick, acceleration * verticalDelta))
|
||||
} else if (flickableItem.contentY > flickableItem.contentHeight
|
||||
- flickThreshold - viewport.height && verticalDelta < -speedThreshold) {
|
||||
flickableItem.flick(ignored, Math.max(-maxFlick, acceleration * verticalDelta))
|
||||
} else {
|
||||
flickableItem.contentY = verticalValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onHorizontalValueChanged: {
|
||||
if (!horizontalRecursionGuard)
|
||||
flickableItem.contentX = horizontalValue
|
||||
}
|
||||
}
|
||||
|
||||
ScrollViewHelper {
|
||||
id: scroller
|
||||
anchors.fill: parent
|
||||
active: wheelArea.active
|
||||
property bool outerFrame: !frameVisible || !(__style ? __style.__externalScrollBars : 0)
|
||||
property int scrollBarSpacing: outerFrame ? 0 : (__style ? __style.__scrollBarSpacing : 0)
|
||||
property int verticalScrollbarOffset: verticalScrollBar.visible && !verticalScrollBar.isTransient ?
|
||||
verticalScrollBar.width + scrollBarSpacing : 0
|
||||
property int horizontalScrollbarOffset: horizontalScrollBar.visible && !horizontalScrollBar.isTransient ?
|
||||
horizontalScrollBar.height + scrollBarSpacing : 0
|
||||
Loader {
|
||||
id: frameLoader
|
||||
sourceComponent: __style ? __style.frame : null
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: scroller.outerFrame ? 0 : scroller.verticalScrollbarOffset
|
||||
anchors.bottomMargin: scroller.outerFrame ? 0 : scroller.horizontalScrollbarOffset
|
||||
}
|
||||
|
||||
Item {
|
||||
id: viewportItem
|
||||
anchors.fill: frameLoader
|
||||
anchors.topMargin: frameVisible ? __style.padding.top : 0
|
||||
anchors.leftMargin: frameVisible ? __style.padding.left : 0
|
||||
anchors.rightMargin: (frameVisible ? __style.padding.right : 0) + (scroller.outerFrame ? scroller.verticalScrollbarOffset : 0)
|
||||
anchors.bottomMargin: (frameVisible ? __style.padding.bottom : 0) + (scroller.outerFrame ? scroller.horizontalScrollbarOffset : 0)
|
||||
clip: true
|
||||
}
|
||||
}
|
||||
FocusFrame { visible: highlightOnFocus && root.activeFocus }
|
||||
}
|
||||
}
|
||||
@@ -1,332 +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
|
||||
|
||||
/*!
|
||||
\qmltype Slider
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup controls
|
||||
\brief Provides a vertical or horizontal slider control.
|
||||
|
||||
\image slider.png
|
||||
|
||||
The slider is the classic control for providing a bounded value. It lets
|
||||
the user move a slider handle along a horizontal or vertical groove
|
||||
and translates the handle's position into a value within the legal range.
|
||||
|
||||
\code
|
||||
Slider {
|
||||
value: 0.5
|
||||
}
|
||||
\endcode
|
||||
|
||||
The slider value is by default in the range [0, 1]. If integer values are
|
||||
needed, you can set the \l stepSize.
|
||||
|
||||
You can create a custom appearance for a Slider by
|
||||
assigning a \l {QtQuick.Controls.Styles::SliderStyle}{SliderStyle}.
|
||||
*/
|
||||
|
||||
Control {
|
||||
id: slider
|
||||
|
||||
/*!
|
||||
\qmlproperty enumeration Slider::orientation
|
||||
|
||||
This property holds the layout orientation of the slider.
|
||||
The default value is \c Qt.Horizontal.
|
||||
*/
|
||||
property int orientation: Qt.Horizontal
|
||||
|
||||
/*!
|
||||
\qmlproperty real Slider::minimumValue
|
||||
|
||||
This property holds the minimum value of the slider.
|
||||
The default value is \c{0.0}.
|
||||
*/
|
||||
property alias minimumValue: range.minimumValue
|
||||
|
||||
/*!
|
||||
\qmlproperty real Slider::maximumValue
|
||||
|
||||
This property holds the maximum value of the slider.
|
||||
The default value is \c{1.0}.
|
||||
*/
|
||||
property alias maximumValue: range.maximumValue
|
||||
|
||||
/*!
|
||||
\qmlproperty bool Slider::updateValueWhileDragging
|
||||
|
||||
This property indicates whether the current \l value should be updated while
|
||||
the user is moving the slider handle, or only when the button has been released.
|
||||
This property could for instance be modified if changing the slider value would turn
|
||||
out to be too time consuming.
|
||||
|
||||
The default value is \c true.
|
||||
*/
|
||||
property bool updateValueWhileDragging: true
|
||||
|
||||
/*!
|
||||
\qmlproperty bool Slider::pressed
|
||||
|
||||
This property indicates whether the slider handle is being pressed.
|
||||
*/
|
||||
readonly property alias pressed: mouseArea.pressed
|
||||
|
||||
/*!
|
||||
\qmlproperty bool Slider::hovered
|
||||
|
||||
This property indicates whether the slider handle is being hovered.
|
||||
*/
|
||||
readonly property alias hovered: mouseArea.handleHovered
|
||||
|
||||
/*!
|
||||
\qmlproperty real Slider::stepSize
|
||||
|
||||
This property indicates the slider step size.
|
||||
|
||||
A value of 0 indicates that the value of the slider operates in a
|
||||
continuous range between \l minimumValue and \l maximumValue.
|
||||
|
||||
Any non 0 value indicates a discrete stepSize. The following example
|
||||
will generate a slider with integer values in the range [0-5].
|
||||
|
||||
\qml
|
||||
Slider {
|
||||
maximumValue: 5.0
|
||||
stepSize: 1.0
|
||||
}
|
||||
\endqml
|
||||
|
||||
The default value is \c{0.0}.
|
||||
*/
|
||||
property alias stepSize: range.stepSize
|
||||
|
||||
/*!
|
||||
\qmlproperty real Slider::value
|
||||
|
||||
This property holds the current value of the slider.
|
||||
The default value is \c{0.0}.
|
||||
*/
|
||||
property alias value: range.value
|
||||
|
||||
/*!
|
||||
\qmlproperty bool Slider::activeFocusOnPress
|
||||
|
||||
This property indicates whether the slider should receive active focus when
|
||||
pressed.
|
||||
*/
|
||||
property bool activeFocusOnPress: false
|
||||
|
||||
/*!
|
||||
\qmlproperty bool Slider::tickmarksEnabled
|
||||
|
||||
This property indicates whether the slider should display tickmarks
|
||||
at step intervals. Tick mark spacing is calculated based on the
|
||||
\l stepSize property.
|
||||
|
||||
The default value is \c false.
|
||||
|
||||
\note This property may be ignored on some platforms when using the native style (e.g. Android).
|
||||
*/
|
||||
property bool tickmarksEnabled: false
|
||||
|
||||
/*! \internal */
|
||||
property bool __horizontal: orientation === Qt.Horizontal
|
||||
|
||||
/*! \internal
|
||||
The extra arguments positionAtMinimum and positionAtMaximum are there to force
|
||||
re-evaluation of the handle position when the constraints change (QTBUG-41255).
|
||||
*/
|
||||
property real __handlePos: range.valueForPosition(__horizontal ? fakeHandle.x : fakeHandle.y, range.positionAtMinimum, range.positionAtMaximum)
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
Accessible.role: Accessible.Slider
|
||||
/*! \internal */
|
||||
function accessibleIncreaseAction() {
|
||||
range.increaseSingleStep()
|
||||
}
|
||||
/*! \internal */
|
||||
function accessibleDecreaseAction() {
|
||||
range.decreaseSingleStep()
|
||||
}
|
||||
|
||||
style: Qt.createComponent(Settings.style + "/SliderStyle.qml", slider)
|
||||
|
||||
Keys.onRightPressed: if (__horizontal) range.increaseSingleStep()
|
||||
Keys.onLeftPressed: if (__horizontal) range.decreaseSingleStep()
|
||||
Keys.onUpPressed: if (!__horizontal) range.increaseSingleStep()
|
||||
Keys.onDownPressed: if (!__horizontal) range.decreaseSingleStep()
|
||||
|
||||
RangeModel {
|
||||
id: range
|
||||
minimumValue: 0.0
|
||||
maximumValue: 1.0
|
||||
value: 0
|
||||
stepSize: 0.0
|
||||
inverted: __horizontal ? false : true
|
||||
|
||||
positionAtMinimum: 0
|
||||
positionAtMaximum: __horizontal ? slider.width - fakeHandle.width : slider.height - fakeHandle.height
|
||||
}
|
||||
|
||||
Item {
|
||||
id: fakeHandle
|
||||
anchors.verticalCenter: __horizontal ? parent.verticalCenter : undefined
|
||||
anchors.horizontalCenter: !__horizontal ? parent.horizontalCenter : undefined
|
||||
width: __panel.handleWidth
|
||||
height: __panel.handleHeight
|
||||
|
||||
function updatePos() {
|
||||
if (updateValueWhileDragging && !mouseArea.drag.active)
|
||||
range.position = __horizontal ? x : y
|
||||
}
|
||||
|
||||
onXChanged: updatePos();
|
||||
onYChanged: updatePos();
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
property int clickOffset: 0
|
||||
property real pressX: 0
|
||||
property real pressY: 0
|
||||
property bool handleHovered: false
|
||||
|
||||
function clamp ( val ) {
|
||||
return Math.max(range.positionAtMinimum, Math.min(range.positionAtMaximum, val))
|
||||
}
|
||||
|
||||
function updateHandlePosition(mouse, force) {
|
||||
var pos, overThreshold
|
||||
if (__horizontal) {
|
||||
pos = clamp (mouse.x + clickOffset - fakeHandle.width/2)
|
||||
overThreshold = Math.abs(mouse.x - pressX) >= Settings.dragThreshold
|
||||
if (overThreshold)
|
||||
preventStealing = true
|
||||
if (overThreshold || force)
|
||||
fakeHandle.x = pos
|
||||
} else if (!__horizontal) {
|
||||
pos = clamp (mouse.y + clickOffset- fakeHandle.height/2)
|
||||
overThreshold = Math.abs(mouse.y - pressY) >= Settings.dragThreshold
|
||||
if (overThreshold)
|
||||
preventStealing = true
|
||||
if (overThreshold || force)
|
||||
fakeHandle.y = pos
|
||||
}
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
if (pressed)
|
||||
updateHandlePosition(mouse, preventStealing)
|
||||
|
||||
var point = mouseArea.mapToItem(fakeHandle, mouse.x, mouse.y)
|
||||
handleHovered = fakeHandle.contains(Qt.point(point.x, point.y))
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
if (slider.activeFocusOnPress)
|
||||
slider.forceActiveFocus();
|
||||
|
||||
if (handleHovered) {
|
||||
var point = mouseArea.mapToItem(fakeHandle, mouse.x, mouse.y)
|
||||
clickOffset = __horizontal ? fakeHandle.width/2 - point.x : fakeHandle.height/2 - point.y
|
||||
}
|
||||
pressX = mouse.x
|
||||
pressY = mouse.y
|
||||
updateHandlePosition(mouse, !Settings.hasTouchScreen)
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
updateHandlePosition(mouse, Settings.hasTouchScreen)
|
||||
// If we don't update while dragging, this is the only
|
||||
// moment that the range is updated.
|
||||
if (!slider.updateValueWhileDragging)
|
||||
range.position = __horizontal ? fakeHandle.x : fakeHandle.y;
|
||||
clickOffset = 0
|
||||
preventStealing = false
|
||||
}
|
||||
|
||||
onExited: handleHovered = false
|
||||
}
|
||||
|
||||
|
||||
// During the drag, we simply ignore the position set from the range, this
|
||||
// means that setting a value while dragging will not "interrupt" the
|
||||
// dragging activity.
|
||||
Binding {
|
||||
when: !mouseArea.drag.active
|
||||
target: fakeHandle
|
||||
property: __horizontal ? "x" : "y"
|
||||
value: range.position
|
||||
}
|
||||
|
||||
WheelArea {
|
||||
id: wheelarea
|
||||
anchors.fill: parent
|
||||
horizontalMinimumValue: slider.minimumValue
|
||||
horizontalMaximumValue: slider.maximumValue
|
||||
verticalMinimumValue: slider.minimumValue
|
||||
verticalMaximumValue: slider.maximumValue
|
||||
property real step: (slider.maximumValue - slider.minimumValue)/(range.positionAtMaximum - range.positionAtMinimum)
|
||||
|
||||
onVerticalWheelMoved: {
|
||||
if (verticalDelta !== 0) {
|
||||
var delta = Math.abs(verticalDelta)*step > stepSize ? verticalDelta*step : verticalDelta/Math.abs(verticalDelta)*stepSize
|
||||
value += delta
|
||||
}
|
||||
}
|
||||
|
||||
onHorizontalWheelMoved: {
|
||||
if (horizontalDelta !== 0) {
|
||||
var delta = Math.abs(horizontalDelta)*step > stepSize ? horizontalDelta*step : horizontalDelta/Math.abs(horizontalDelta)*stepSize
|
||||
value += delta
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,388 +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 SpinBox
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup controls
|
||||
\brief Provides a spin box control.
|
||||
|
||||
\image spinbox.png
|
||||
|
||||
SpinBox allows the user to choose a value by clicking the up or down buttons, or by
|
||||
pressing up or down on the keyboard. The user can also type the value in manually.
|
||||
|
||||
By default the SpinBox provides discrete values in the range [0-99] with a \l stepSize of 1 and 0 \l decimals.
|
||||
|
||||
\code
|
||||
SpinBox {
|
||||
id: spinbox
|
||||
}
|
||||
\endcode
|
||||
|
||||
Note that if you require decimal values you will need to set the \l decimals to a non 0 value.
|
||||
|
||||
\code
|
||||
SpinBox {
|
||||
id: spinbox
|
||||
decimals: 2
|
||||
}
|
||||
\endcode
|
||||
|
||||
*/
|
||||
|
||||
Control {
|
||||
id: spinbox
|
||||
|
||||
/*!
|
||||
\qmlproperty real SpinBox::value
|
||||
|
||||
The value of this SpinBox, clamped to \l minimumValue and \l maximumValue.
|
||||
|
||||
The default value is \c{0.0}.
|
||||
*/
|
||||
property alias value: validator.value
|
||||
|
||||
/*!
|
||||
\qmlproperty real SpinBox::minimumValue
|
||||
|
||||
The minimum value of the SpinBox range.
|
||||
The \l value is clamped to this value.
|
||||
|
||||
The default value is \c{0.0}.
|
||||
*/
|
||||
property alias minimumValue: validator.minimumValue
|
||||
|
||||
/*!
|
||||
\qmlproperty real SpinBox::maximumValue
|
||||
|
||||
The maximum value of the SpinBox range.
|
||||
The \l value is clamped to this value. If maximumValue is smaller than
|
||||
\l minimumValue, \l minimumValue will be enforced.
|
||||
|
||||
The default value is \c{99}.
|
||||
*/
|
||||
property alias maximumValue: validator.maximumValue
|
||||
|
||||
/*! \qmlproperty real SpinBox::stepSize
|
||||
The amount by which the \l value is incremented/decremented when a
|
||||
spin button is pressed.
|
||||
|
||||
The default value is \c{1.0}.
|
||||
*/
|
||||
property alias stepSize: validator.stepSize
|
||||
|
||||
/*! \qmlproperty string SpinBox::suffix
|
||||
The suffix for the value. I.e "cm" */
|
||||
property alias suffix: validator.suffix
|
||||
|
||||
/*! \qmlproperty string SpinBox::prefix
|
||||
The prefix for the value. I.e "$" */
|
||||
property alias prefix: validator.prefix
|
||||
|
||||
/*! \qmlproperty int SpinBox::decimals
|
||||
This property indicates the amount of decimals.
|
||||
Note that if you enter more decimals than specified, they will
|
||||
be truncated to the specified amount of decimal places.
|
||||
The default value is \c{0}.
|
||||
*/
|
||||
property alias decimals: validator.decimals
|
||||
|
||||
/*! \qmlproperty font SpinBox::font
|
||||
|
||||
This property indicates the current font used by the SpinBox.
|
||||
*/
|
||||
property alias font: input.font
|
||||
|
||||
/*! This property indicates whether the Spinbox should get active
|
||||
focus when pressed.
|
||||
The default value is \c true.
|
||||
*/
|
||||
property bool activeFocusOnPress: true
|
||||
|
||||
/*! \qmlproperty enumeration horizontalAlignment
|
||||
\since QtQuick.Controls 1.1
|
||||
|
||||
This property indicates how the content is horizontally aligned
|
||||
within the text field.
|
||||
|
||||
The supported values are:
|
||||
\list
|
||||
\li Qt.AlignLeft
|
||||
\li Qt.AlignHCenter
|
||||
\li Qt.AlignRight
|
||||
\endlist
|
||||
|
||||
The default value is style dependent.
|
||||
*/
|
||||
property int horizontalAlignment: __panel ? __panel.horizontalAlignment : Qt.AlignLeft
|
||||
|
||||
/*!
|
||||
\qmlproperty bool SpinBox::hovered
|
||||
|
||||
This property indicates whether the control is being hovered.
|
||||
*/
|
||||
readonly property bool hovered: mouseArea.containsMouse || input.containsMouse
|
||||
|| mouseUp.containsMouse || mouseDown.containsMouse
|
||||
|
||||
/*!
|
||||
\qmlsignal SpinBox::editingFinished()
|
||||
\since QtQuick.Controls 1.1
|
||||
|
||||
This signal is emitted when the Return or Enter key is pressed or
|
||||
the control loses focus. Note that if there is a validator
|
||||
set on the control and enter/return is pressed, this signal will
|
||||
only be emitted if the validator returns an acceptable state.
|
||||
|
||||
The corresponding handler is \c onEditingFinished.
|
||||
*/
|
||||
signal editingFinished()
|
||||
|
||||
/*!
|
||||
\qmlproperty bool SpinBox::selectByMouse
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
This property determines if the user can select the text with the
|
||||
mouse.
|
||||
|
||||
The default value is \c true.
|
||||
*/
|
||||
property bool selectByMouse: true
|
||||
|
||||
/*!
|
||||
\qmlproperty bool SpinBox::inputMethodComposing
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
This property holds whether the SpinBox has partial text input from an input method.
|
||||
|
||||
While it is composing an input method may rely on mouse or key events from the SpinBox
|
||||
to edit or commit the partial text. This property can be used to determine when to disable
|
||||
events handlers that may interfere with the correct operation of an input method.
|
||||
*/
|
||||
readonly property bool inputMethodComposing: !!input.inputMethodComposing
|
||||
|
||||
/*!
|
||||
\since QtQuick.Controls 1.3
|
||||
|
||||
This property contains the edit \l Menu for working
|
||||
with text selection. Set it to \c null if no menu
|
||||
is wanted.
|
||||
*/
|
||||
property Component menu: input.editMenu.defaultMenu
|
||||
|
||||
style: Qt.createComponent(Settings.style + "/SpinBoxStyle.qml", spinbox)
|
||||
|
||||
/*! \internal */
|
||||
function __increment() {
|
||||
validator.increment()
|
||||
if (activeFocus)
|
||||
input.selectValue()
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __decrement() {
|
||||
validator.decrement()
|
||||
if (activeFocus)
|
||||
input.selectValue()
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property alias __text: input.text
|
||||
|
||||
/*! \internal */
|
||||
property alias __baselineOffset: input.baselineOffset
|
||||
|
||||
__styleData: QtObject {
|
||||
readonly property bool upEnabled: value != maximumValue;
|
||||
readonly property alias upHovered: mouseUp.containsMouse
|
||||
readonly property alias upPressed: mouseUp.pressed
|
||||
|
||||
readonly property bool downEnabled: value != minimumValue;
|
||||
readonly property alias downPressed: mouseDown.pressed
|
||||
readonly property alias downHovered: mouseDown.containsMouse
|
||||
|
||||
readonly property int contentHeight: Math.max(input.implicitHeight, 16)
|
||||
readonly property int contentWidth: Math.max(maxSizeHint.implicitWidth, minSizeHint.implicitWidth)
|
||||
}
|
||||
|
||||
Text {
|
||||
id: maxSizeHint
|
||||
text: prefix + maximumValue.toFixed(decimals) + suffix
|
||||
font: input.font
|
||||
visible: false
|
||||
}
|
||||
|
||||
Text {
|
||||
id: minSizeHint
|
||||
text: prefix + minimumValue.toFixed(decimals) + suffix
|
||||
font: input.font
|
||||
visible: false
|
||||
}
|
||||
|
||||
activeFocusOnTab: true
|
||||
|
||||
onActiveFocusChanged: if (activeFocus) input.selectValue()
|
||||
|
||||
Accessible.name: input.text
|
||||
Accessible.role: Accessible.SpinBox
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
onPressed: if (activeFocusOnPress) input.forceActiveFocus()
|
||||
onWheel: {
|
||||
if (wheel.angleDelta.y > 0)
|
||||
__increment();
|
||||
else
|
||||
__decrement();
|
||||
}
|
||||
}
|
||||
|
||||
TextInputWithHandles {
|
||||
id: input
|
||||
clip: contentWidth > width
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: __style ? __style.padding.left : 0
|
||||
anchors.topMargin: __style ? __style.padding.top : 0
|
||||
anchors.rightMargin: __style ? __style.padding.right: 0
|
||||
anchors.bottomMargin: __style ? __style.padding.bottom: 0
|
||||
|
||||
control: spinbox
|
||||
cursorHandle: __style ? __style.__cursorHandle : undefined
|
||||
selectionHandle: __style ? __style.__selectionHandle : undefined
|
||||
|
||||
focus: true
|
||||
activeFocusOnPress: spinbox.activeFocusOnPress
|
||||
|
||||
horizontalAlignment: spinbox.horizontalAlignment
|
||||
verticalAlignment: __panel ? __panel.verticalAlignment : Qt.AlignVCenter
|
||||
inputMethodHints: Qt.ImhFormattedNumbersOnly
|
||||
|
||||
validator: SpinBoxValidator {
|
||||
id: validator
|
||||
property bool ready: false // Delay validation until all properties are ready
|
||||
onTextChanged: if (ready) input.text = validator.text
|
||||
Component.onCompleted: {input.text = validator.text ; ready = true}
|
||||
}
|
||||
onAccepted: {
|
||||
input.text = validator.text
|
||||
selectValue()
|
||||
}
|
||||
|
||||
Keys.forwardTo: spinbox
|
||||
|
||||
onEditingFinished: spinbox.editingFinished()
|
||||
|
||||
font: __panel ? __panel.font : TextSingleton.font
|
||||
color: __panel ? __panel.foregroundColor : "black"
|
||||
selectionColor: __panel ? __panel.selectionColor : "black"
|
||||
selectedTextColor: __panel ? __panel.selectedTextColor : "black"
|
||||
|
||||
opacity: parent.enabled ? 1 : 0.5
|
||||
renderType: __style ? __style.renderType : Text.NativeRendering
|
||||
|
||||
function selectValue() {
|
||||
select(prefix.length, text.length - suffix.length)
|
||||
}
|
||||
}
|
||||
|
||||
// Spinbox increment button
|
||||
|
||||
MouseArea {
|
||||
id: mouseUp
|
||||
objectName: "mouseUp"
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
|
||||
property var upRect: __panel ? __panel.upRect : null
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
|
||||
anchors.leftMargin: upRect ? upRect.x : 0
|
||||
anchors.topMargin: upRect ? upRect.y : 0
|
||||
|
||||
width: upRect ? upRect.width : 0
|
||||
height: upRect ? upRect.height : 0
|
||||
|
||||
onClicked: __increment()
|
||||
onPressed: if (!Settings.hasTouchScreen && activeFocusOnPress) input.forceActiveFocus()
|
||||
|
||||
property bool autoincrement: false;
|
||||
onReleased: autoincrement = false
|
||||
Timer { running: mouseUp.pressed; interval: 350 ; onTriggered: mouseUp.autoincrement = true }
|
||||
Timer { running: mouseUp.autoincrement; interval: 60 ; repeat: true ; onTriggered: __increment() }
|
||||
}
|
||||
|
||||
// Spinbox decrement button
|
||||
|
||||
MouseArea {
|
||||
id: mouseDown
|
||||
objectName: "mouseDown"
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
|
||||
onClicked: __decrement()
|
||||
onPressed: if (!Settings.hasTouchScreen && activeFocusOnPress) input.forceActiveFocus()
|
||||
|
||||
property var downRect: __panel ? __panel.downRect : null
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
|
||||
anchors.leftMargin: downRect ? downRect.x : 0
|
||||
anchors.topMargin: downRect ? downRect.y : 0
|
||||
|
||||
width: downRect ? downRect.width : 0
|
||||
height: downRect ? downRect.height : 0
|
||||
|
||||
property bool autoincrement: false;
|
||||
onReleased: autoincrement = false
|
||||
Timer { running: mouseDown.pressed; interval: 350 ; onTriggered: mouseDown.autoincrement = true }
|
||||
Timer { running: mouseDown.autoincrement; interval: 60 ; repeat: true ; onTriggered: __decrement() }
|
||||
}
|
||||
|
||||
Keys.onUpPressed: __increment()
|
||||
Keys.onDownPressed: __decrement()
|
||||
}
|
||||
@@ -1,540 +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.Layouts 1.0
|
||||
import QtQuick.Controls.Private 1.0 as Private
|
||||
import QtQuick.Window 2.1
|
||||
|
||||
/*!
|
||||
\qmltype SplitView
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup views
|
||||
\brief Lays out items with a draggable splitter between each item.
|
||||
|
||||
\image splitview.png
|
||||
|
||||
SplitView is a control that lays out items horizontally or
|
||||
vertically with a draggable splitter between each item.
|
||||
|
||||
There will always be one (and only one) item in the SplitView that has \l{Layout::fillWidth}{Layout.fillWidth}
|
||||
set to \c true (or \l{Layout::fillHeight}{Layout.fillHeight}, if orientation is Qt.Vertical). This means that the
|
||||
item will get all leftover space when other items have been laid out.
|
||||
By default, the last visible child of the SplitView will have this set, but
|
||||
it can be changed by explicitly setting fillWidth to \c true on another item.
|
||||
As the fillWidth item will automatically be resized to fit the extra space, explicit assignments
|
||||
to width and height will be ignored (but \l{Layout::minimumWidth}{Layout.minimumWidth} and
|
||||
\l{Layout::maximumWidth}{Layout.maximumWidth} will still be respected).
|
||||
|
||||
A handle can belong to the item either on the left or top side, or on the right or bottom side:
|
||||
\list
|
||||
\li If the fillWidth item is to the right: the handle belongs to the left item.
|
||||
\li if the fillWidth item is on the left: the handle belongs to the right item.
|
||||
\endlist
|
||||
|
||||
This will again control which item gets resized when the user drags a handle,
|
||||
and which handle gets hidden when an item is told to hide.
|
||||
|
||||
SplitView supports setting attached Layout properties on child items, which
|
||||
means that you can set the following attached properties for each child:
|
||||
\list
|
||||
\li \l{Layout::minimumWidth}{Layout.minimumWidth}
|
||||
\li \l{Layout::minimumHeight}{Layout.minimumHeight}
|
||||
\li \l{Layout::maximumWidth}{Layout.maximumWidth}
|
||||
\li \l{Layout::maximumHeight}{Layout.maximumHeight}
|
||||
\li \l{Layout::fillWidth}{Layout.fillWidth} (\c true for only one child)
|
||||
\li \l{Layout::fillHeight}{Layout.fillHeight} (\c true for only one child)
|
||||
\endlist
|
||||
|
||||
\note Please import QtQuick.Layout 1.0 in your QML file in order to use the Layout
|
||||
attached properties inside SplitView.
|
||||
|
||||
Example:
|
||||
|
||||
To create a SplitView with three items, and let the center item get superfluous space, one
|
||||
could do the following:
|
||||
|
||||
\qml
|
||||
SplitView {
|
||||
anchors.fill: parent
|
||||
orientation: Qt.Horizontal
|
||||
|
||||
Rectangle {
|
||||
width: 200
|
||||
Layout.maximumWidth: 400
|
||||
color: "lightblue"
|
||||
Text {
|
||||
text: "View 1"
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: centerItem
|
||||
Layout.minimumWidth: 50
|
||||
Layout.fillWidth: true
|
||||
color: "lightgray"
|
||||
Text {
|
||||
text: "View 2"
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
width: 200
|
||||
color: "lightgreen"
|
||||
Text {
|
||||
text: "View 3"
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\endqml
|
||||
*/
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
/*!
|
||||
\qmlproperty enumeration SplitView::orientation
|
||||
|
||||
This property holds the orientation of the SplitView.
|
||||
The value can be either \c Qt.Horizontal or \c Qt.Vertical.
|
||||
The default value is \c Qt.Horizontal.
|
||||
*/
|
||||
property int orientation: Qt.Horizontal
|
||||
|
||||
/*!
|
||||
This property holds the delegate that will be instantiated between each
|
||||
child item. Inside the delegate the following properties are available:
|
||||
|
||||
\table
|
||||
\row \li readonly property bool styleData.index \li Specifies the index of the splitter handle. The handle
|
||||
between the first and the second item will get index 0,
|
||||
the next handle index 1 etc.
|
||||
\row \li readonly property bool styleData.hovered \li The handle is being hovered.
|
||||
\row \li readonly property bool styleData.pressed \li The handle is being pressed.
|
||||
\row \li readonly property bool styleData.resizing \li The handle is being dragged.
|
||||
\endtable
|
||||
|
||||
*/
|
||||
property Component handleDelegate: Rectangle {
|
||||
width: 1
|
||||
height: 1
|
||||
color: Qt.darker(pal.window, 1.5)
|
||||
}
|
||||
|
||||
/*!
|
||||
This propery is \c true when the user is resizing any of the items by
|
||||
dragging on the splitter handles.
|
||||
*/
|
||||
property bool resizing: false
|
||||
|
||||
/*! \internal */
|
||||
default property alias __contents: contents.data
|
||||
/*! \internal */
|
||||
property alias __items: splitterItems.children
|
||||
/*! \internal */
|
||||
property alias __handles: splitterHandles.children
|
||||
|
||||
clip: true
|
||||
Component.onCompleted: d.init()
|
||||
onWidthChanged: d.updateLayout()
|
||||
onHeightChanged: d.updateLayout()
|
||||
onOrientationChanged: d.changeOrientation()
|
||||
|
||||
/*! Add an item to the end of the view.
|
||||
\since QtQuick.Controls 1.3 */
|
||||
function addItem(item) {
|
||||
d.updateLayoutGuard = true
|
||||
|
||||
d.addItem_impl(item)
|
||||
|
||||
d.calculateImplicitSize()
|
||||
d.updateLayoutGuard = false
|
||||
d.updateFillIndex()
|
||||
}
|
||||
|
||||
SystemPalette { id: pal }
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property bool horizontal: orientation == Qt.Horizontal
|
||||
readonly property string minimum: horizontal ? "minimumWidth" : "minimumHeight"
|
||||
readonly property string maximum: horizontal ? "maximumWidth" : "maximumHeight"
|
||||
readonly property string otherMinimum: horizontal ? "minimumHeight" : "minimumWidth"
|
||||
readonly property string otherMaximum: horizontal ? "maximumHeight" : "maximumWidth"
|
||||
readonly property string offset: horizontal ? "x" : "y"
|
||||
readonly property string otherOffset: horizontal ? "y" : "x"
|
||||
readonly property string size: horizontal ? "width" : "height"
|
||||
readonly property string otherSize: horizontal ? "height" : "width"
|
||||
readonly property string implicitSize: horizontal ? "implicitWidth" : "implicitHeight"
|
||||
readonly property string implicitOtherSize: horizontal ? "implicitHeight" : "implicitWidth"
|
||||
|
||||
property int fillIndex: -1
|
||||
property bool updateLayoutGuard: true
|
||||
|
||||
function addItem_impl(item)
|
||||
{
|
||||
// temporarily set fillIndex to new item
|
||||
fillIndex = __items.length
|
||||
if (splitterItems.children.length > 0)
|
||||
handleLoader.createObject(splitterHandles, {"__handleIndex":splitterItems.children.length - 1})
|
||||
|
||||
item.parent = splitterItems
|
||||
|
||||
// should match disconnections in Component.onDestruction
|
||||
item.widthChanged.connect(d.updateLayout)
|
||||
item.heightChanged.connect(d.updateLayout)
|
||||
item.Layout.maximumWidthChanged.connect(d.updateLayout)
|
||||
item.Layout.minimumWidthChanged.connect(d.updateLayout)
|
||||
item.Layout.maximumHeightChanged.connect(d.updateLayout)
|
||||
item.Layout.minimumHeightChanged.connect(d.updateLayout)
|
||||
item.visibleChanged.connect(d.updateFillIndex)
|
||||
item.Layout.fillWidthChanged.connect(d.updateFillIndex)
|
||||
item.Layout.fillHeightChanged.connect(d.updateFillIndex)
|
||||
}
|
||||
|
||||
function init()
|
||||
{
|
||||
for (var i=0; i<__contents.length; ++i) {
|
||||
var item = __contents[i];
|
||||
if (!item.hasOwnProperty("x"))
|
||||
continue
|
||||
addItem_impl(item)
|
||||
i-- // item was removed from list
|
||||
}
|
||||
|
||||
d.calculateImplicitSize()
|
||||
d.updateLayoutGuard = false
|
||||
d.updateFillIndex()
|
||||
}
|
||||
|
||||
function updateFillIndex()
|
||||
{
|
||||
if (lastItem.visible !== root.visible)
|
||||
return
|
||||
var policy = (root.orientation === Qt.Horizontal) ? "fillWidth" : "fillHeight"
|
||||
for (var i=0; i<__items.length-1; ++i) {
|
||||
if (__items[i].Layout[policy] === true)
|
||||
break;
|
||||
}
|
||||
|
||||
d.fillIndex = i
|
||||
d.updateLayout()
|
||||
}
|
||||
|
||||
function changeOrientation()
|
||||
{
|
||||
if (__items.length == 0)
|
||||
return;
|
||||
d.updateLayoutGuard = true
|
||||
|
||||
// Swap width/height for items and handles:
|
||||
for (var i=0; i<__items.length; ++i) {
|
||||
var item = __items[i]
|
||||
var tmp = item.x
|
||||
item.x = item.y
|
||||
item.y = tmp
|
||||
tmp = item.width
|
||||
item.width = item.height
|
||||
item.height = tmp
|
||||
|
||||
var handle = __handles[i]
|
||||
if (handle) {
|
||||
tmp = handle.x
|
||||
handle.x = handle.y
|
||||
handle.y = handle.x
|
||||
tmp = handle.width
|
||||
handle.width = handle.height
|
||||
handle.height = tmp
|
||||
}
|
||||
}
|
||||
|
||||
// Change d.horizontal explicit, since the binding will change too late:
|
||||
d.horizontal = orientation == Qt.Horizontal
|
||||
d.updateLayoutGuard = false
|
||||
d.updateFillIndex()
|
||||
}
|
||||
|
||||
function calculateImplicitSize()
|
||||
{
|
||||
var implicitSize = 0
|
||||
var implicitOtherSize = 0
|
||||
|
||||
for (var i=0; i<__items.length; ++i) {
|
||||
var item = __items[i];
|
||||
implicitSize += clampedMinMax(item[d.size], item.Layout[minimum], item.Layout[maximum])
|
||||
var os = clampedMinMax(item[otherSize], item.Layout[otherMinimum], item.Layout[otherMaximum])
|
||||
implicitOtherSize = Math.max(implicitOtherSize, os)
|
||||
|
||||
var handle = __handles[i]
|
||||
if (handle)
|
||||
implicitSize += handle[d.size]
|
||||
}
|
||||
|
||||
root[d.implicitSize] = implicitSize
|
||||
root[d.implicitOtherSize] = implicitOtherSize
|
||||
}
|
||||
|
||||
function clampedMinMax(value, minimum, maximum)
|
||||
{
|
||||
if (value < minimum)
|
||||
value = minimum
|
||||
if (value > maximum)
|
||||
value = maximum
|
||||
return value
|
||||
}
|
||||
|
||||
function accumulatedSize(firstIndex, lastIndex, includeFillItemMinimum)
|
||||
{
|
||||
// Go through items and handles, and
|
||||
// calculate their acummulated width.
|
||||
var w = 0
|
||||
for (var i=firstIndex; i<lastIndex; ++i) {
|
||||
|
||||
var item = __items[i]
|
||||
if (item.visible || i == d.fillIndex) {
|
||||
if (i !== d.fillIndex)
|
||||
w += item[d.size];
|
||||
else if (includeFillItemMinimum && item.Layout[minimum] !== undefined)
|
||||
w += item.Layout[minimum]
|
||||
}
|
||||
|
||||
var handle = __handles[i]
|
||||
if (handle && handle.visible)
|
||||
w += handle[d.size]
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
function updateLayout()
|
||||
{
|
||||
// This function will reposition both handles and
|
||||
// items according to the their width/height:
|
||||
if (__items.length === 0)
|
||||
return;
|
||||
if (!lastItem.visible)
|
||||
return;
|
||||
if (d.updateLayoutGuard === true)
|
||||
return
|
||||
d.updateLayoutGuard = true
|
||||
|
||||
// Ensure all items within their min/max:
|
||||
for (var i=0; i<__items.length; ++i) {
|
||||
if (i !== d.fillIndex) {
|
||||
var item = __items[i];
|
||||
var clampedSize = clampedMinMax(item[d.size], item.Layout[d.minimum], item.Layout[d.maximum])
|
||||
if (clampedSize != item[d.size])
|
||||
item[d.size] = clampedSize
|
||||
}
|
||||
}
|
||||
|
||||
// Set size of fillItem to remaining available space.
|
||||
// Special case: If SplitView size is zero, we leave fillItem with the size
|
||||
// it already got, and assume that SplitView ends up with implicit size as size:
|
||||
if (root[d.size] != 0) {
|
||||
var fillItem = __items[fillIndex]
|
||||
var superfluous = root[d.size] - d.accumulatedSize(0, __items.length, false)
|
||||
var s = Math.max(superfluous, fillItem.Layout[minimum])
|
||||
s = Math.min(s, fillItem.Layout[maximum])
|
||||
fillItem[d.size] = s
|
||||
}
|
||||
|
||||
// Position items and handles according to their width:
|
||||
var lastVisibleItem, lastVisibleHandle, handle
|
||||
for (i=0; i<__items.length; ++i) {
|
||||
// Position item to the right of the previous visible handle:
|
||||
item = __items[i];
|
||||
if (item.visible || i == d.fillIndex) {
|
||||
item[d.offset] = lastVisibleHandle ? lastVisibleHandle[d.offset] + lastVisibleHandle[d.size] : 0
|
||||
item[d.otherOffset] = 0
|
||||
item[d.otherSize] = clampedMinMax(root[otherSize], item.Layout[otherMinimum], item.Layout[otherMaximum])
|
||||
lastVisibleItem = item
|
||||
}
|
||||
|
||||
handle = __handles[i]
|
||||
if (handle && handle.visible) {
|
||||
handle[d.offset] = lastVisibleItem[d.offset] + Math.max(0, lastVisibleItem[d.size])
|
||||
handle[d.otherOffset] = 0
|
||||
handle[d.otherSize] = root[d.otherSize]
|
||||
lastVisibleHandle = handle
|
||||
}
|
||||
}
|
||||
|
||||
d.updateLayoutGuard = false
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: handleLoader
|
||||
Loader {
|
||||
id: itemHandle
|
||||
|
||||
property int __handleIndex: -1
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property int index: __handleIndex
|
||||
readonly property alias hovered: mouseArea.containsMouse
|
||||
readonly property alias pressed: mouseArea.pressed
|
||||
readonly property bool resizing: mouseArea.drag.active
|
||||
onResizingChanged: root.resizing = resizing
|
||||
}
|
||||
property bool resizeLeftItem: (d.fillIndex > __handleIndex)
|
||||
visible: __items[__handleIndex + (resizeLeftItem ? 0 : 1)].visible
|
||||
sourceComponent: handleDelegate
|
||||
onWidthChanged: d.updateLayout()
|
||||
onHeightChanged: d.updateLayout()
|
||||
onXChanged: moveHandle()
|
||||
onYChanged: moveHandle()
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
property real defaultMargin: Private.Settings.hasTouchScreen ? Screen.pixelDensity * 3.5 : 2
|
||||
anchors.leftMargin: (parent.width <= 1) ? -defaultMargin : 0
|
||||
anchors.rightMargin: (parent.width <= 1) ? -defaultMargin : 0
|
||||
anchors.topMargin: (parent.height <= 1) ? -defaultMargin : 0
|
||||
anchors.bottomMargin: (parent.height <= 1) ? -defaultMargin : 0
|
||||
hoverEnabled: Private.Settings.hoverEnabled
|
||||
drag.threshold: 0
|
||||
drag.target: parent
|
||||
drag.axis: root.orientation === Qt.Horizontal ? Drag.XAxis : Drag.YAxis
|
||||
cursorShape: root.orientation === Qt.Horizontal ? Qt.SplitHCursor : Qt.SplitVCursor
|
||||
}
|
||||
|
||||
function moveHandle() {
|
||||
// Moving the handle means resizing an item. Which one,
|
||||
// left or right, depends on where the fillItem is.
|
||||
// 'updateLayout' will be overridden in case new width violates max/min.
|
||||
// 'updateLayout' will be triggered when an item changes width.
|
||||
if (d.updateLayoutGuard)
|
||||
return
|
||||
|
||||
var leftHandle, leftItem, rightItem, rightHandle
|
||||
var leftEdge, rightEdge, newWidth, leftStopX, rightStopX
|
||||
var i
|
||||
|
||||
if (resizeLeftItem) {
|
||||
// Ensure that the handle is not crossing other handles. So
|
||||
// find the first visible handle to the left to determine the left edge:
|
||||
leftEdge = 0
|
||||
for (i=__handleIndex-1; i>=0; --i) {
|
||||
leftHandle = __handles[i]
|
||||
if (leftHandle.visible) {
|
||||
leftEdge = leftHandle[d.offset] + leftHandle[d.size]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure: leftStopX >= itemHandle[d.offset] >= rightStopX
|
||||
var min = d.accumulatedSize(__handleIndex+1, __items.length, true)
|
||||
rightStopX = root[d.size] - min - itemHandle[d.size]
|
||||
leftStopX = Math.max(leftEdge, itemHandle[d.offset])
|
||||
itemHandle[d.offset] = Math.min(rightStopX, Math.max(leftStopX, itemHandle[d.offset]))
|
||||
|
||||
newWidth = itemHandle[d.offset] - leftEdge
|
||||
leftItem = __items[__handleIndex]
|
||||
// The next line will trigger 'updateLayout':
|
||||
leftItem[d.size] = newWidth
|
||||
} else {
|
||||
// Resize item to the right.
|
||||
// Ensure that the handle is not crossing other handles. So
|
||||
// find the first visible handle to the right to determine the right edge:
|
||||
rightEdge = root[d.size]
|
||||
for (i=__handleIndex+1; i<__handles.length; ++i) {
|
||||
rightHandle = __handles[i]
|
||||
if (rightHandle.visible) {
|
||||
rightEdge = rightHandle[d.offset]
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure: leftStopX <= itemHandle[d.offset] <= rightStopX
|
||||
min = d.accumulatedSize(0, __handleIndex+1, true)
|
||||
leftStopX = min - itemHandle[d.size]
|
||||
rightStopX = Math.min((rightEdge - itemHandle[d.size]), itemHandle[d.offset])
|
||||
itemHandle[d.offset] = Math.max(leftStopX, Math.min(itemHandle[d.offset], rightStopX))
|
||||
|
||||
newWidth = rightEdge - (itemHandle[d.offset] + itemHandle[d.size])
|
||||
rightItem = __items[__handleIndex+1]
|
||||
// The next line will trigger 'updateLayout':
|
||||
rightItem[d.size] = newWidth
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contents
|
||||
visible: false
|
||||
anchors.fill: parent
|
||||
}
|
||||
Item {
|
||||
id: splitterItems
|
||||
anchors.fill: parent
|
||||
}
|
||||
Item {
|
||||
id: splitterHandles
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Item {
|
||||
id: lastItem
|
||||
onVisibleChanged: d.updateFillIndex()
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
for (var i=0; i<splitterItems.children.length; ++i) {
|
||||
var item = splitterItems.children[i];
|
||||
|
||||
// should match connections in init()
|
||||
item.widthChanged.disconnect(d.updateLayout)
|
||||
item.heightChanged.disconnect(d.updateLayout)
|
||||
item.Layout.maximumWidthChanged.disconnect(d.updateLayout)
|
||||
item.Layout.minimumWidthChanged.disconnect(d.updateLayout)
|
||||
item.Layout.maximumHeightChanged.disconnect(d.updateLayout)
|
||||
item.Layout.minimumHeightChanged.disconnect(d.updateLayout)
|
||||
item.visibleChanged.disconnect(d.updateFillIndex)
|
||||
item.Layout.fillWidthChanged.disconnect(d.updateFillIndex)
|
||||
item.Layout.fillHeightChanged.disconnect(d.updateFillIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,988 +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 StackView
|
||||
\inherits Item
|
||||
\ingroup views
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
|
||||
\brief Provides a stack-based navigation model.
|
||||
|
||||
\image stackview.png
|
||||
|
||||
StackView implements a stack-based navigation model, which can be used
|
||||
with a set of interlinked information pages. Items are pushed onto the stack
|
||||
as the user navigates deeper into the material, and popped off again when he
|
||||
chooses to go back.
|
||||
|
||||
The \l{Qt Quick Controls - Touch Gallery}{touch gallery} example is a good
|
||||
starting point to understand how StackView works. The following snippet
|
||||
from the example shows how it can be used:
|
||||
|
||||
\qml
|
||||
StackView {
|
||||
id: stack
|
||||
initialItem: view
|
||||
|
||||
Component {
|
||||
id: view
|
||||
|
||||
MouseArea {
|
||||
Text {
|
||||
text: stack.depth
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
onClicked: stack.push(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
\section1 Using StackView in an Application
|
||||
Using the StackView in the application is typically a simple matter of adding
|
||||
the StackView as a child of a Window. The stack is usually anchored to the
|
||||
edges of the window, except at the top or bottom where it might be anchored
|
||||
to a status bar, or some other similar UI component. The stack can then be
|
||||
used by invoking its navigation methods. The first item to show in the StackView
|
||||
is commonly loaded assigning it to \l initialItem.
|
||||
|
||||
\note Items pushed onto the stack view have \l{Supported Attached Properties}{Stack attached properties}.
|
||||
|
||||
\section1 Basic Navigation
|
||||
There are three primary navigation operations in StackView: push(), pop(), and
|
||||
replace (replace by specifying argument \c replace to push()).
|
||||
These correspond to classic stack operations where "push" adds an item to the
|
||||
top of a stack, "pop" removes the top item from the stack, and "replace" is like a
|
||||
pop followed by a push in that it replaces the topmost item on the stack with
|
||||
a new item (but the applied transtition might be different). The topmost item
|
||||
in the stack corresponds to the one that is \l{StackView::currentItem} {currently}
|
||||
visible on the screen. That means that "push" is the logical equivalent of navigating
|
||||
forward or deeper into the application, "pop" is the equivalent of navigating back,
|
||||
and "replace" is the equivalent of replacing the current item.
|
||||
|
||||
Sometimes it is necessary to go back more than a single step in the stack, for
|
||||
example, to return to a "main" item or some kind of section item in the application.
|
||||
For this use case, it is possible to specify an item as a parameter for pop().
|
||||
This is called an "unwind" operation as the stack gets unwound to the specified item.
|
||||
If the item is not found then the stack unwinds until there is only a single item in
|
||||
the stack, which becomes the current item. To explicitly unwind to the bottom
|
||||
of the stack it is recommended to use \l{pop()} {pop(null)}, though technically any
|
||||
non-existent item will do.
|
||||
|
||||
Given the stack [A, B, C]:
|
||||
|
||||
\list
|
||||
\li \l{push()}{push(D)} => [A, B, C, D] - "push" transition animation between C and D
|
||||
\li pop() => [A, B] - "pop" transition animation between C and B
|
||||
\li \l{push()}{push(D, replace)} => [A, B, D] - "replace" transition between C and D
|
||||
\li \l{pop()}{pop(A)} => [A] - "pop" transition between C and A
|
||||
\endlist
|
||||
|
||||
\note Note that when the stack is empty, a push() will not perform a
|
||||
transition animation because there is nothing to transition from (typically during
|
||||
application start-up). A pop() on a stack with depth 1 or 0 is a no-operation.
|
||||
If removing all items from the stack is needed, a separate function clear() is
|
||||
available.
|
||||
|
||||
Calling push() returns the item that was pushed onto the stack.
|
||||
Calling pop() returns the item that was popped off the stack. When pop() is
|
||||
called in an unwind operation the top-most item (the first item that was
|
||||
popped, which will also be the one transitioning out) is returned.
|
||||
|
||||
\section1 Deep Linking
|
||||
\e{Deep linking} means launching an application into a particular state. For example,
|
||||
a newspaper application could be launched into showing a particular article,
|
||||
bypassing the front item (and possibly a section item) that would normally have
|
||||
to be navigated through to get to the article concerned. In terms of StackView, deep
|
||||
linking means the ability to modify the state of the stack, so much so that it is
|
||||
possible to push a set of items to the top of the stack, or to completely reset
|
||||
the stack to a given state.
|
||||
|
||||
The API for deep linking in StackView is the same as for basic navigation. Pushing
|
||||
an array instead of a single item, will involve that all the items in that array will
|
||||
be pushed onto the stack. The transition animation, however, will be conducted as
|
||||
if only the last item in the array was pushed onto the stack. The normal semantics
|
||||
of push() apply for deep linking, meaning that push() adds whatever is pushed onto
|
||||
the stack. Note also that only the last item of the array will be loaded.
|
||||
The rest will be lazy-loaded as needed when entering the screen upon subsequent
|
||||
calls to pop (or when requesting the item by using \a get).
|
||||
|
||||
This gives us the following result, given the stack [A, B, C]:
|
||||
|
||||
\list
|
||||
\li \l{push()}{push([D, E, F])} => [A, B, C, D, E, F] - "push" transition animation between C and F
|
||||
\li \l{push()}{push([D, E, F], replace)} => [A, B, D, E, F] - "replace" transition animation between C and F
|
||||
\li clear(); \l{push()}{push([D, E, F])} => [D, E, F] - no transition animation (since the stack was empty)
|
||||
\endlist
|
||||
|
||||
\section1 Pushing items
|
||||
|
||||
An item pushed onto the StackView can be either an Item, a URL, a string
|
||||
with a URL, or a Component. To push it, assign it to a property "item"
|
||||
inside a property list, and send it as an argument to \l{StackView::push}{push}:
|
||||
|
||||
\code
|
||||
stackView.push({item: yourItem})
|
||||
\endcode
|
||||
|
||||
The list can contain several properties that control how the item should be pushed:
|
||||
\list
|
||||
\li \c item: this property is required, and holds the item to be pushed.
|
||||
\li \c properties: a list of QML properties to be assigned to the item upon push. These
|
||||
properties will be copied into the item at load time, or when the item will become
|
||||
the current item (normally upon push).
|
||||
\li \c immediate: set this property to \c true to skip transition effects. When pushing
|
||||
an array, this property only needs to be set on the first element to make the
|
||||
whole operation immediate.
|
||||
\li \c replace: set this property to replace the current item on the stack. When pushing
|
||||
an array, you only need to set this property on the first element to replace
|
||||
as many elements on the stack as inside the array.
|
||||
\li \c destroyOnPop: set this boolean to true if StackView needs to destroy the item when
|
||||
it is popped off the stack. By default (if \a destroyOnPop is not specified), StackView
|
||||
will destroy items pushed as components or URLs. Items not destroyed will be re-parented
|
||||
back to the original parents they had before being pushed onto the stack and hidden.
|
||||
If you need to set this property, do it with care, so that items are not leaked.
|
||||
\endlist
|
||||
|
||||
If the only argument needed is "item", the following short-hand notation can be applied:
|
||||
|
||||
\code
|
||||
stackView.push(yourItem)
|
||||
\endcode
|
||||
|
||||
You can push several items in one go by using an array of property lists. This is
|
||||
optimizing compared to pushing items one by one, since StackView then can load only the
|
||||
last item in the list. The rest will be loaded as they are about to become
|
||||
the current item (which happens when the stack is popped). The following example shows how
|
||||
to push an array of items:
|
||||
|
||||
\code
|
||||
stackView.push([{item: yourItem1}, {item: yourItem2}])
|
||||
\endcode
|
||||
|
||||
If an inline item is pushed, the item is temporarily re-parented into the StackView. When the item
|
||||
is later popped off, it gets re-parented back to its original owner again.
|
||||
If, however, an item is pushed as a component or a URL, the actual item will be created as an
|
||||
item from that component. This happens automatically when the item is about to become the current
|
||||
item in the stack. Ownership of the item will then normally be taken by the StackView. It will as
|
||||
such automatically destroy the item when it is later popped off. The component that declared the item, by
|
||||
contrast, remains in the ownership of the application and is not destroyed by the stack.
|
||||
This can be overridden by explicitly setting \c{destroyOnPop} in the list of arguments given to push.
|
||||
|
||||
If the \c properties to be pushed are specified, they will be copied into the item at loading time
|
||||
(in case of a component or URL), or when the item will become the current item (in case of an inline
|
||||
item). The following example shows how this can be done:
|
||||
|
||||
\code
|
||||
stackView.push({item: someItem, properties: {fgcolor: "red", bgcolor: "blue"}})
|
||||
\endcode
|
||||
|
||||
|
||||
\note Note that if an item is declared inside another item, and if that parent gets destroyed,
|
||||
(even if a component was used), that child item will also be destroyed.
|
||||
This follows normal Qt parent-child destruction rules, but sometimes comes as a surprise
|
||||
for developers.
|
||||
|
||||
\section1 Lifecycle
|
||||
An item's lifecycle in the StackView can have the following transitions:
|
||||
\list 1
|
||||
\li instantiation
|
||||
\li inactive
|
||||
\li activating
|
||||
\li active
|
||||
\li deactivating
|
||||
\li inactive
|
||||
\li destruction
|
||||
\endlist
|
||||
|
||||
It can move any number of times between inactive and active. When an item is activated,
|
||||
it's visible on the screen and is considered to be the current item. An item
|
||||
in a StackView that is not visible is not activated, even if the item is currently the
|
||||
top-most item in the stack. When the stack becomes visible, the item that is top-most gets
|
||||
activated. Likewise if the stack is then hidden, the topmost item would be deactivated.
|
||||
Popping the item off the top of the stack at this point would not result in further
|
||||
deactivation since the item is not active.
|
||||
|
||||
There is an attached \l{Stack::status}{Stack.status} property that tracks the lifecycle. The
|
||||
status values list is an enumeration with values \c Stack.Inactive, \c Stack.Activating,
|
||||
\c Stack.Active and \c Stack.Deactivating. Combined with the normal \c Component.onComplete and
|
||||
\c Component.onDestruction signals the entire lifecycle is thus:
|
||||
|
||||
\list
|
||||
\li Created: Component.onCompleted()
|
||||
\li Activating: Stack.onStatusChanged (Stack.status is Stack.Activating)
|
||||
\li Acivated: Stack.onStatusChanged (Stack.status is Stack.Active)
|
||||
\li Deactivating: Stack.onStatusChanged (Stack.status is Stack.Deactivating)
|
||||
\li Deactivated: Stack.onStatusChanged (Stack.status is Stack.Inactive)
|
||||
\li Destruction: Component.onDestruction()
|
||||
\endlist
|
||||
|
||||
\section1 Finding items
|
||||
Sometimes it is necessary to search for an item, for example, in order to unwind the stack to
|
||||
an item to which the application does not have a reference. This is facilitated using a
|
||||
function find() in StackView. The find() function takes a callback function as its
|
||||
only argument. The callback gets invoked for each item in the stack (starting at the top).
|
||||
If the callback returns true, then it signals that a match has been found and the find()
|
||||
function returns that item. If the callback fails to return true (no match is found),
|
||||
then find() returns \c null.
|
||||
|
||||
The code below searches for an item in the stack that has a name "order_id" and then unwinds to
|
||||
that item. Note that since find() returns \c {null} if no item is found, and since pop unwinds to
|
||||
the bottom of the stack if null is given as the target item, the code works well even in
|
||||
case no matching item is found.
|
||||
|
||||
\code
|
||||
stackView.pop(stackView.find(function(item) {
|
||||
return item.name == "order_id";
|
||||
}));
|
||||
\endcode
|
||||
|
||||
You can also get to an item in the stack using \l {get()}{get(index)}. You should use
|
||||
this function if your item depends on another item in the stack, as the function will
|
||||
ensure that the item at the given index gets loaded before it is returned.
|
||||
|
||||
\code
|
||||
previousItem = stackView.get(myItem.Stack.index - 1));
|
||||
\endcode
|
||||
|
||||
\section1 Transitions
|
||||
|
||||
A transition is performed whenever a item is pushed or popped, and consists of
|
||||
two items: enterItem and exitItem. The StackView itself will never move items
|
||||
around, but instead delegate the job to an external animation set provided
|
||||
by the style or the application developer. How items should visually enter and leave the stack
|
||||
(and the geometry they should end up with) is therefore completely controlled from the outside.
|
||||
|
||||
When the transition starts, the StackView will search for a transition that
|
||||
matches the operation executed. There are three transitions to choose
|
||||
from: pushTransition, popTransition, and replaceTransition. Each implements how
|
||||
enterItem should animate in, and exitItem out. The transitions are
|
||||
collected inside a StackViewDelegate object assigned to
|
||||
\l {StackView::delegate}{delegate}. By default, popTransition and
|
||||
replaceTransition will be the same as pushTransition, unless you set them
|
||||
to something else.
|
||||
|
||||
A simple fade transition could be implemented as:
|
||||
|
||||
\qml
|
||||
StackView {
|
||||
delegate: StackViewDelegate {
|
||||
function transitionFinished(properties)
|
||||
{
|
||||
properties.exitItem.opacity = 1
|
||||
}
|
||||
|
||||
pushTransition: StackViewTransition {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "opacity"
|
||||
from: 0
|
||||
to: 1
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "opacity"
|
||||
from: 1
|
||||
to: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
PushTransition needs to inherit from StackViewTransition, which is a ParallelAnimation that
|
||||
contains the properties \c enterItem and \c exitItem. You set the target of your
|
||||
inner animations to those items. Since the same items instance can be pushed several
|
||||
times to a StackView, you should always override
|
||||
\l {StackViewDelegate::transitionFinished()}{StackViewDelegate.transitionFinished()}.
|
||||
Implement this function to reset any properties animated on the exitItem so that later
|
||||
transitions can expect the items to be in a default state.
|
||||
|
||||
A more complex example could look like the following. Here, the items are lying on the side before
|
||||
being rotated to an upright position:
|
||||
|
||||
\qml
|
||||
StackView {
|
||||
delegate: StackViewDelegate {
|
||||
function transitionFinished(properties)
|
||||
{
|
||||
properties.exitItem.x = 0
|
||||
properties.exitItem.rotation = 0
|
||||
}
|
||||
|
||||
pushTransition: StackViewTransition {
|
||||
SequentialAnimation {
|
||||
ScriptAction {
|
||||
script: enterItem.rotation = 90
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "x"
|
||||
from: enterItem.width
|
||||
to: 0
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "rotation"
|
||||
from: 90
|
||||
to: 0
|
||||
}
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "x"
|
||||
from: 0
|
||||
to: -exitItem.width
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
\section2 Advanced usage
|
||||
|
||||
When the StackView needs a new transition, it first calls
|
||||
\l {StackViewDelegate::getTransition()}{StackViewDelegate.getTransition()}.
|
||||
The base implementation of this function just looks for a property named \c properties.name inside
|
||||
itself (root), which is how it finds \c {property Component pushTransition} in the examples above.
|
||||
|
||||
\code
|
||||
function getTransition(properties)
|
||||
{
|
||||
return root[properties.name]
|
||||
}
|
||||
\endcode
|
||||
|
||||
You can override this function for your delegate if you need extra logic to decide which
|
||||
transition to return. You could for example introspect the items, and return different animations
|
||||
depending on the their internal state. StackView will expect you to return a Component that
|
||||
contains a StackViewTransition, or a StackViewTransition directly. The former is easier, as StackView will
|
||||
then create the transition and later destroy it when it's done, while avoiding any sideeffects
|
||||
caused by the transition being alive long after it has run. Returning a StackViewTransition directly
|
||||
can be useful if you need to write some sort of transition caching for performance reasons.
|
||||
As an optimization, you can also return \c null to signal that you just want to show/hide the items
|
||||
immediately without creating or running any transitions. You can also override this function if
|
||||
you need to alter the items in any way before the transition starts.
|
||||
|
||||
\c properties contains the properties that will be assigned to the StackViewTransition before
|
||||
it runs. In fact, you can add more properties to this object during the call
|
||||
if you need to initialize additional properties of your custom StackViewTransition when the returned
|
||||
component is instantiated.
|
||||
|
||||
The following example shows how you can decide which animation to use during runtime :
|
||||
|
||||
\qml
|
||||
StackViewDelegate {
|
||||
function getTransition(properties)
|
||||
{
|
||||
return (properties.enterItem.Stack.index % 2) ? horizontalTransition : verticalTransition
|
||||
}
|
||||
|
||||
function transitionFinished(properties)
|
||||
{
|
||||
properties.exitItem.x = 0
|
||||
properties.exitItem.y = 0
|
||||
}
|
||||
|
||||
property Component horizontalTransition: StackViewTransition {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "x"
|
||||
from: target.width
|
||||
to: 0
|
||||
duration: 300
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "x"
|
||||
from: 0
|
||||
to: target.width
|
||||
duration: 300
|
||||
}
|
||||
}
|
||||
|
||||
property Component verticalTransition: StackViewTransition {
|
||||
PropertyAnimation {
|
||||
target: enterItem
|
||||
property: "y"
|
||||
from: target.height
|
||||
to: 0
|
||||
duration: 300
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: exitItem
|
||||
property: "y"
|
||||
from: 0
|
||||
to: target.height
|
||||
duration: 300
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
\section1 Supported Attached Properties
|
||||
|
||||
Items in a StackView support these attached properties:
|
||||
\list
|
||||
\li \l{Stack::index}{Stack.index} - Contains the index of the item inside the StackView
|
||||
\li \l{Stack::view}{Stack.view} - Contains the StackView the item is in
|
||||
\li \l{Stack::status}{Stack.status} - Contains the status of the item
|
||||
\endlist
|
||||
*/
|
||||
|
||||
FocusScope {
|
||||
id: root
|
||||
|
||||
/*! \qmlproperty int StackView::depth
|
||||
\readonly
|
||||
The number of items currently pushed onto the stack.
|
||||
*/
|
||||
readonly property alias depth: root.__depth
|
||||
|
||||
/*! \qmlproperty Item StackView::currentItem
|
||||
\readonly
|
||||
The currently top-most item in the stack.
|
||||
*/
|
||||
readonly property alias currentItem: root.__currentItem
|
||||
|
||||
/*! The first \l item that should be shown when the StackView is created.
|
||||
\a initialItem can take same value as the first argument to \l{StackView::push()}
|
||||
{StackView.push()}. Note that this is just a convenience for writing
|
||||
\c{Component.onCompleted: stackView.push(myInitialItem)}
|
||||
|
||||
Examples:
|
||||
|
||||
\list
|
||||
\li initialItem: Qt.resolvedUrl("MyItem.qml")
|
||||
\li initialItem: myItem
|
||||
\li initialItem: {"item" : Qt.resolvedUrl("MyRectangle.qml"), "properties" : {"color" : "red"}}
|
||||
\endlist
|
||||
\sa push
|
||||
*/
|
||||
property var initialItem: null
|
||||
|
||||
/*! \readonly
|
||||
\a busy is \c true if a transition is running, and \c false otherwise. */
|
||||
readonly property bool busy: __currentTransition !== null
|
||||
|
||||
/*! The transitions to use when pushing or popping items.
|
||||
For better understanding on how to apply custom transitions, read \l{Transitions}.
|
||||
\sa {Stack::transitions}{Stack.transitions} */
|
||||
property StackViewDelegate delegate: StackViewSlideDelegate {}
|
||||
|
||||
/*! Pushes an item onto the stack. The function takes a property list as argument, which
|
||||
should contain one or more of the following properties:
|
||||
\list
|
||||
\li \c item: this property is required, and holds the item you want to push.
|
||||
\li \c properties: a list of QML properties that should be assigned
|
||||
to the item upon push. These properties will be copied into the item when it is
|
||||
loaded (in case of a component or URL), or when it becomes the current item for the
|
||||
first time (normally upon push).
|
||||
\li \c immediate: set this property to \c true to skip transition effects. When pushing
|
||||
an array, you only need to set this property on the first element to make the
|
||||
whole operation immediate.
|
||||
\li \c replace: set this property to replace the current item on the stack. When pushing
|
||||
an array, you only need to set this property on the first element to replace
|
||||
as many elements on the stack as inside the array.
|
||||
\li \c destroyOnPop: set this property to specify if the item needs to be destroyed
|
||||
when its popped off the stack. By default (if \a destroyOnPop is not specified),
|
||||
StackView will destroy items pushed as components or URLs. Items
|
||||
not destroyed will be re-parented to the original parents they had before being
|
||||
pushed onto the stack, and hidden. If you need to set this property, do it with
|
||||
care, so that items are not leaked.
|
||||
\endlist
|
||||
|
||||
You can also push an array of items (property lists) if you need to push several items
|
||||
in one go. A transition will then only occur between the current item and the last
|
||||
item in the list. Loading the other items will be deferred until needed.
|
||||
|
||||
Examples:
|
||||
\list
|
||||
\li stackView.push({item:anItem})
|
||||
\li stackView.push({item:aURL, immediate: true, replace: true})
|
||||
\li stackView.push({item:aRectangle, properties:{color:"red"}})
|
||||
\li stackView.push({item:aComponent, properties:{color:"red"}})
|
||||
\li stackView.push({item:aComponent.createObject(), destroyOnPop:true})
|
||||
\li stackView.push([{item:anitem, immediate:true}, {item:aURL}])
|
||||
\endlist
|
||||
|
||||
\note Note: if the only argument needed is "item", you can apply the following short-
|
||||
hand notation: \c{stackView.push(anItem)}.
|
||||
|
||||
Returns the item that became current.
|
||||
|
||||
\sa initialItem
|
||||
\sa {Pushing items}
|
||||
*/
|
||||
function push(item) {
|
||||
// Note: we support two different APIs in this function; The old meego API, and
|
||||
// the new "property list" API. Hence the reason for hiding the fact that you
|
||||
// can pass more arguments than shown in the signature:
|
||||
if (__recursionGuard(true))
|
||||
return
|
||||
var properties = arguments[1]
|
||||
var immediate = arguments[2]
|
||||
var replace = arguments[3]
|
||||
var arrayPushed = (item instanceof Array)
|
||||
var firstItem = arrayPushed ? item[0] : item
|
||||
immediate = (immediate || JSArray.stackView.length === 0)
|
||||
|
||||
if (firstItem && firstItem.item && firstItem.hasOwnProperty("x") === false) {
|
||||
// Property list API used:
|
||||
immediate = immediate || firstItem.immediate
|
||||
replace = replace || firstItem.replace
|
||||
}
|
||||
|
||||
// Create, and push, a new javascript object, called "element", onto the stack.
|
||||
// This element contains all the information necessary to construct the item, and
|
||||
// will, after loaded, also contain the loaded item:
|
||||
if (arrayPushed) {
|
||||
if (item.length === 0)
|
||||
return
|
||||
var outElement = replace ? JSArray.pop() : JSArray.current()
|
||||
for (var i=0; i<item.length; ++i)
|
||||
JSArray.push({itemComponent:item[i], loaded: false, index: __depth, properties: properties});
|
||||
} else {
|
||||
outElement = replace ? JSArray.pop() : JSArray.current()
|
||||
JSArray.push({itemComponent:item, loaded: false, index: __depth, properties: properties})
|
||||
}
|
||||
|
||||
var currentElement = JSArray.current()
|
||||
var transition = {
|
||||
inElement: currentElement,
|
||||
outElement: outElement,
|
||||
immediate: immediate,
|
||||
replace: replace,
|
||||
push: true
|
||||
}
|
||||
__performTransition(transition)
|
||||
__recursionGuard(false)
|
||||
return __currentItem
|
||||
}
|
||||
|
||||
/*! Pops one or more items off the stack. The function takes a property list as argument
|
||||
which can contain one or more of the following properties:
|
||||
\list
|
||||
\li \c item: if specified, all items down to (but not including) \a item will be
|
||||
popped off. If \a item is \c null, all items down to (but not including) the
|
||||
first item will be popped. If not specified, only the current item will be
|
||||
popped.
|
||||
\li \c immediate: set this property to \c true to skip transition effects.
|
||||
\endlist
|
||||
|
||||
Examples:
|
||||
\list
|
||||
\li stackView.pop()
|
||||
\li stackView.pop({item:someItem, immediate: true})
|
||||
\li stackView.pop({immediate: true})
|
||||
\li stackView.pop(null)
|
||||
\endlist
|
||||
|
||||
\note Note: If the only argument needed is "item", you can apply the following short-
|
||||
hand notation: \c{stackView.pop(anItem)}.
|
||||
|
||||
Returns the item that was popped off
|
||||
\sa clear()
|
||||
*/
|
||||
function pop(item) {
|
||||
if (__depth <= 1)
|
||||
return null
|
||||
if (item && item.hasOwnProperty("x") === false) {
|
||||
// Property list API used:
|
||||
var immediate = (item.immediate === true)
|
||||
item = item.item
|
||||
} else {
|
||||
immediate = (arguments[1] === true)
|
||||
}
|
||||
|
||||
if (item === __currentItem)
|
||||
return
|
||||
|
||||
if (__recursionGuard(true))
|
||||
return
|
||||
|
||||
var outElement = JSArray.pop()
|
||||
var inElement = JSArray.current()
|
||||
|
||||
if (__depth > 1 && item !== undefined && item !== inElement.item) {
|
||||
// Pop from the top until we find 'item', and return the corresponding
|
||||
// element. Skip all non-loaded items (except the first), since no one
|
||||
// has any references to such items anyway:
|
||||
while (__depth > 1 && !JSArray.current().loaded)
|
||||
JSArray.pop()
|
||||
inElement = JSArray.current()
|
||||
while (__depth > 1 && item !== inElement.item) {
|
||||
JSArray.pop()
|
||||
__cleanup(inElement)
|
||||
while (__depth > 1 && !JSArray.current().loaded)
|
||||
JSArray.pop()
|
||||
inElement = JSArray.current()
|
||||
}
|
||||
}
|
||||
|
||||
var transition = {
|
||||
inElement: inElement,
|
||||
outElement: outElement,
|
||||
immediate: immediate,
|
||||
replace: false,
|
||||
push: false
|
||||
}
|
||||
__performTransition(transition)
|
||||
__recursionGuard(false)
|
||||
return outElement.item;
|
||||
}
|
||||
|
||||
/*! Remove all items from the stack. No animations will be applied. */
|
||||
function clear() {
|
||||
if (__recursionGuard(true))
|
||||
return
|
||||
if (__currentTransition)
|
||||
__currentTransition.animation.complete()
|
||||
__currentItem = null
|
||||
var count = __depth
|
||||
for (var i=0; i<count; ++i) {
|
||||
var element = JSArray.pop()
|
||||
if (element.item)
|
||||
__cleanup(element);
|
||||
}
|
||||
__recursionGuard(false)
|
||||
}
|
||||
|
||||
/*! Search for a specific item inside the stack. \a func will
|
||||
be called for each item in the stack (with the item as argument)
|
||||
until the function returns true. Return value will be the item found. For
|
||||
example:
|
||||
find(function(item, index) { return item.isTheOne })
|
||||
Set \a onlySearchLoadedItems to \c true to not load items that are
|
||||
not loaded into memory */
|
||||
function find(func, onlySearchLoadedItems) {
|
||||
for (var i=__depth-1; i>=0; --i) {
|
||||
var element = JSArray.stackView[i];
|
||||
if (onlySearchLoadedItems !== true)
|
||||
__loadElement(element)
|
||||
else if (!element.item)
|
||||
continue
|
||||
if (func(element.item))
|
||||
return element.item
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*! Returns the item at position \a index in
|
||||
the stack. If \a dontLoad is true, the
|
||||
item will not be forced to load (and \c null
|
||||
will be returned if not yet loaded) */
|
||||
function get(index, dontLoad)
|
||||
{
|
||||
if (index < 0 || index >= JSArray.stackView.length)
|
||||
return null
|
||||
var element = JSArray.stackView[index]
|
||||
if (dontLoad !== true) {
|
||||
__loadElement(element)
|
||||
return element.item
|
||||
} else if (element.item) {
|
||||
return element.item
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/*! Immediately completes any ongoing transition.
|
||||
/sa Animation.complete
|
||||
*/
|
||||
function completeTransition()
|
||||
{
|
||||
if (__recursionGuard(true))
|
||||
return
|
||||
if (__currentTransition)
|
||||
__currentTransition.animation.complete()
|
||||
__recursionGuard(false)
|
||||
}
|
||||
|
||||
/********* DEPRECATED API *********/
|
||||
|
||||
/*! \internal
|
||||
\deprecated Use Push() instead */
|
||||
function replace(item, properties, immediate) {
|
||||
push(item, properties, immediate, true)
|
||||
}
|
||||
|
||||
/********* PRIVATE API *********/
|
||||
|
||||
width: parent ? parent.width : 0
|
||||
height: parent ? parent.height : 0
|
||||
|
||||
/*! \internal The currently top-most item on the stack. */
|
||||
property Item __currentItem: null
|
||||
/*! \internal The number of items currently pushed onto the stack. */
|
||||
property int __depth: 0
|
||||
/*! \internal Stores the transition info while a transition is ongoing */
|
||||
property var __currentTransition: null
|
||||
/*! \internal Stops the user from pushing items while preparing a transition */
|
||||
property bool __guard: false
|
||||
|
||||
Component.onCompleted: {
|
||||
if (initialItem)
|
||||
push(initialItem)
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
if (__currentTransition)
|
||||
__currentTransition.animation.complete()
|
||||
__currentItem = null
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __recursionGuard(use)
|
||||
{
|
||||
if (use && __guard) {
|
||||
console.warn("Warning: StackView: You cannot push/pop recursively!")
|
||||
console.trace()
|
||||
return true
|
||||
}
|
||||
__guard = use
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __loadElement(element)
|
||||
{
|
||||
if (element.loaded) {
|
||||
if (!element.item) {
|
||||
element.item = invalidItemReplacement.createObject(root)
|
||||
element.item.text = "\nError: The item has been deleted outside StackView!"
|
||||
}
|
||||
return
|
||||
}
|
||||
if (!element.itemComponent) {
|
||||
element.item = invalidItemReplacement.createObject(root)
|
||||
element.item.text = "\nError: Invalid item (item was 'null'). "
|
||||
+ "This might indicate that the item was deleted outside StackView!"
|
||||
return
|
||||
}
|
||||
|
||||
var comp = __resolveComponent(element.itemComponent, element)
|
||||
|
||||
// Assign properties to item:
|
||||
if (!element.properties)
|
||||
element.properties = {}
|
||||
|
||||
if (comp.hasOwnProperty("createObject")) {
|
||||
if (comp.status === Component.Error) {
|
||||
element.item = invalidItemReplacement.createObject(root)
|
||||
element.item.text = "\nError: Could not load: " + comp.errorString()
|
||||
} else {
|
||||
element.item = comp.createObject(root, element.properties)
|
||||
// Destroy items we create unless the user specified something else:
|
||||
if (!element.hasOwnProperty("destroyOnPop"))
|
||||
element.destroyOnPop = true
|
||||
}
|
||||
} else {
|
||||
// comp is already an Item, so just re-parent it into the StackView:
|
||||
element.item = comp
|
||||
element.originalParent = parent
|
||||
element.item.parent = root
|
||||
for (var prop in element.properties) {
|
||||
if (element.item.hasOwnProperty(prop))
|
||||
element.item[prop] = element.properties[prop];
|
||||
}
|
||||
// Do not destroy items we didn't create, unless the user specified something else:
|
||||
if (!element.hasOwnProperty("destroyOnPop"))
|
||||
element.destroyOnPop = false
|
||||
}
|
||||
|
||||
element.item.Stack.__index = element.index
|
||||
element.item.Stack.__view = root
|
||||
// Let item fill all available space by default:
|
||||
element.item.width = Qt.binding(function() { return root.width })
|
||||
element.item.height = Qt.binding(function() { return root.height })
|
||||
element.loaded = true
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __resolveComponent(unknownObjectType, element)
|
||||
{
|
||||
// We need this extra resolve function since we don't really
|
||||
// know what kind of object the user pushed. So we try to
|
||||
// figure it out by inspecting the object:
|
||||
if (unknownObjectType.hasOwnProperty("createObject")) {
|
||||
return unknownObjectType
|
||||
} else if (typeof unknownObjectType == "string") {
|
||||
return Qt.createComponent(unknownObjectType)
|
||||
} else if (unknownObjectType.hasOwnProperty("x")) {
|
||||
return unknownObjectType
|
||||
} else if (unknownObjectType.hasOwnProperty("item")) {
|
||||
// INVARIANT: user pushed a JS-object
|
||||
element.properties = unknownObjectType.properties
|
||||
if (!unknownObjectType.item)
|
||||
unknownObjectType.item = invalidItemReplacement
|
||||
if (unknownObjectType.hasOwnProperty("destroyOnPop"))
|
||||
element.destroyOnPop = unknownObjectType.destroyOnPop
|
||||
return __resolveComponent(unknownObjectType.item, element)
|
||||
} else {
|
||||
// We cannot determine the type, so assume its a URL:
|
||||
return Qt.createComponent(unknownObjectType)
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __cleanup(element) {
|
||||
// INVARIANT: element has been removed from JSArray. Destroy its
|
||||
// item, or re-parent it back to the parent it had before it was pushed:
|
||||
var item = element.item
|
||||
if (element.destroyOnPop) {
|
||||
item.destroy()
|
||||
} else {
|
||||
// Mark the item as no longer part of the StackView. It
|
||||
// might reenter on pop if pushed several times:
|
||||
item.visible = false
|
||||
__setStatus(item, Stack.Inactive)
|
||||
item.Stack.__view = null
|
||||
item.Stack.__index = -1
|
||||
if (element.originalParent)
|
||||
item.parent = element.originalParent
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __setStatus(item, status) {
|
||||
item.Stack.__status = status
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function __performTransition(transition)
|
||||
{
|
||||
// Animate item in "outElement" out, and item in "inElement" in. Set a guard to protect
|
||||
// the user from pushing new items on signals that will fire while preparing for the transition
|
||||
// (e.g Stack.onCompleted, Stack.onStatusChanged, Stack.onIndexChanged etc). Otherwise, we will enter
|
||||
// this function several times, which causes the items to be updated half-way.
|
||||
if (__currentTransition)
|
||||
__currentTransition.animation.complete()
|
||||
__loadElement(transition.inElement)
|
||||
|
||||
transition.name = transition.replace ? "replaceTransition" : (transition.push ? "pushTransition" : "popTransition")
|
||||
var enterItem = transition.inElement.item
|
||||
transition.enterItem = enterItem
|
||||
|
||||
// Since an item can be pushed several times, we need to update its properties:
|
||||
enterItem.parent = root
|
||||
enterItem.Stack.__view = root
|
||||
enterItem.Stack.__index = transition.inElement.index
|
||||
__currentItem = enterItem
|
||||
|
||||
if (!transition.outElement) {
|
||||
// A transition consists of two items, but we got just one. So just show the item:
|
||||
enterItem.visible = true
|
||||
__setStatus(enterItem, Stack.Activating)
|
||||
__setStatus(enterItem, Stack.Active)
|
||||
return
|
||||
}
|
||||
|
||||
var exitItem = transition.outElement.item
|
||||
transition.exitItem = exitItem
|
||||
if (enterItem === exitItem)
|
||||
return
|
||||
|
||||
if (root.delegate) {
|
||||
transition.properties = {
|
||||
"name":transition.name,
|
||||
"enterItem":transition.enterItem,
|
||||
"exitItem":transition.exitItem,
|
||||
"immediate":transition.immediate }
|
||||
var anim = root.delegate.getTransition(transition.properties)
|
||||
if (anim.createObject) {
|
||||
anim = anim.createObject(null, transition.properties)
|
||||
anim.runningChanged.connect(function(){ if (anim.running === false) anim.destroy() })
|
||||
}
|
||||
transition.animation = anim
|
||||
}
|
||||
|
||||
if (!transition.animation) {
|
||||
console.warn("Warning: StackView: no", transition.name, "found!")
|
||||
return
|
||||
}
|
||||
if (enterItem.anchors.fill || exitItem.anchors.fill)
|
||||
console.warn("Warning: StackView: cannot transition an item that is anchored!")
|
||||
|
||||
__currentTransition = transition
|
||||
__setStatus(exitItem, Stack.Deactivating)
|
||||
enterItem.visible = true
|
||||
__setStatus(enterItem, Stack.Activating)
|
||||
transition.animation.runningChanged.connect(animationFinished)
|
||||
transition.animation.start()
|
||||
// NB! For empty animations, "animationFinished" is already
|
||||
// executed at this point, leaving __animation === null:
|
||||
if (transition.immediate === true && transition.animation)
|
||||
transition.animation.complete()
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
function animationFinished()
|
||||
{
|
||||
if (!__currentTransition || __currentTransition.animation.running)
|
||||
return
|
||||
|
||||
__currentTransition.animation.runningChanged.disconnect(animationFinished)
|
||||
__currentTransition.exitItem.visible = false
|
||||
__setStatus(__currentTransition.exitItem, Stack.Inactive);
|
||||
__setStatus(__currentTransition.enterItem, Stack.Active);
|
||||
__currentTransition.properties.animation = __currentTransition.animation
|
||||
root.delegate.transitionFinished(__currentTransition.properties)
|
||||
|
||||
if (!__currentTransition.push || __currentTransition.replace)
|
||||
__cleanup(__currentTransition.outElement)
|
||||
|
||||
__currentTransition = null
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component invalidItemReplacement: Component {
|
||||
Text {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +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
|
||||
|
||||
/*!
|
||||
\qmltype StackViewDelegate
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
|
||||
\brief A delegate used by StackView for loading transitions.
|
||||
|
||||
See the documentation for the \l {StackView} component.
|
||||
|
||||
*/
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
function getTransition(properties)
|
||||
{
|
||||
return root[properties.name]
|
||||
}
|
||||
|
||||
function transitionFinished(properties)
|
||||
{
|
||||
}
|
||||
|
||||
property Component pushTransition: StackViewTransition {}
|
||||
property Component popTransition: root["pushTransition"]
|
||||
property Component replaceTransition: root["pushTransition"]
|
||||
}
|
||||
@@ -1,60 +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
|
||||
|
||||
ParallelAnimation {
|
||||
id: root
|
||||
/*! The name of the animation that is running. Can be one of the following:
|
||||
\list
|
||||
\li 'PushTransition'
|
||||
\li 'PopTransition'
|
||||
\li 'ReplaceTransition'
|
||||
\endlist
|
||||
*/
|
||||
property string name
|
||||
/*! The page that is transitioning in. */
|
||||
property Item enterItem
|
||||
/*! The page that is transitioning out */
|
||||
property Item exitItem
|
||||
/*! Set to \c true if the transition is told to
|
||||
fast-forward directly to its end-state */
|
||||
property bool immediate
|
||||
}
|
||||
@@ -1,149 +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 StatusBar
|
||||
\inqmlmodule QtQuick.Controls
|
||||
\since 5.1
|
||||
\ingroup applicationwindow
|
||||
\brief Contains status information in your app.
|
||||
|
||||
The common way of using StatusBar is in relation to \l ApplicationWindow.
|
||||
|
||||
Note that the StatusBar does not provide a layout of its own, but requires
|
||||
you to position its contents, for instance by creating a \l RowLayout.
|
||||
|
||||
If only a single item is used within the StatusBar, it will resize to fit the implicitHeight
|
||||
of its contained item. This makes it particularly suitable for use together with layouts.
|
||||
Otherwise the height is platform dependent.
|
||||
|
||||
\code
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Layouts 1.0
|
||||
|
||||
ApplicationWindow {
|
||||
statusBar: StatusBar {
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
Label { text: "Read Only" }
|
||||
}
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
||||
FocusScope {
|
||||
id: statusbar
|
||||
|
||||
activeFocusOnTab: false
|
||||
Accessible.role: Accessible.StatusBar
|
||||
|
||||
width: parent ? parent.width : implicitWidth
|
||||
implicitWidth: container.leftMargin + container.rightMargin
|
||||
+ Math.max(container.layoutWidth, __panel ? __panel.implicitWidth : 0)
|
||||
implicitHeight: container.topMargin + container.bottomMargin
|
||||
+ Math.max(container.layoutHeight, __panel ? __panel.implicitHeight : 0)
|
||||
|
||||
/*! \internal */
|
||||
property Component style: Qt.createComponent(Settings.style + "/StatusBarStyle.qml", statusbar)
|
||||
|
||||
/*! \internal */
|
||||
property alias __style: styleLoader.item
|
||||
|
||||
/*! \internal */
|
||||
property Item __panel: panelLoader.item
|
||||
|
||||
/*! \internal */
|
||||
default property alias __content: container.data
|
||||
|
||||
/*!
|
||||
\qmlproperty Item StatusBar::contentItem
|
||||
|
||||
This property holds the content Item of the status bar.
|
||||
|
||||
Items declared as children of a StatusBar are automatically parented to the StatusBar's contentItem.
|
||||
Items created dynamically need to be explicitly parented to the contentItem:
|
||||
|
||||
\note The implicit size of the StatusBar is calculated based on the size of its content. If you want to anchor
|
||||
items inside the status bar, you must specify an explicit width and height on the StatusBar itself.
|
||||
*/
|
||||
readonly property alias contentItem: container
|
||||
|
||||
data: [
|
||||
Loader {
|
||||
id: panelLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: styleLoader.item ? styleLoader.item.panel : null
|
||||
onLoaded: item.z = -1
|
||||
Loader {
|
||||
id: styleLoader
|
||||
property alias __control: statusbar
|
||||
sourceComponent: style
|
||||
}
|
||||
},
|
||||
Item {
|
||||
id: container
|
||||
z: 1
|
||||
focus: true
|
||||
anchors.fill: parent
|
||||
|
||||
anchors.topMargin: topMargin
|
||||
anchors.leftMargin: leftMargin
|
||||
anchors.rightMargin: rightMargin
|
||||
anchors.bottomMargin: bottomMargin
|
||||
|
||||
property int topMargin: __style ? __style.padding.top : 0
|
||||
property int bottomMargin: __style ? __style.padding.bottom : 0
|
||||
property int leftMargin: __style ? __style.padding.left : 0
|
||||
property int rightMargin: __style ? __style.padding.right : 0
|
||||
|
||||
property Item layoutItem: container.children.length === 1 ? container.children[0] : null
|
||||
property real layoutWidth: layoutItem ? (layoutItem.implicitWidth || layoutItem.width) +
|
||||
(layoutItem.anchors.fill ? layoutItem.anchors.leftMargin +
|
||||
layoutItem.anchors.rightMargin : 0) : 0
|
||||
property real layoutHeight: layoutItem ? (layoutItem.implicitHeight || layoutItem.height) +
|
||||
(layoutItem.anchors.fill ? layoutItem.anchors.topMargin +
|
||||
layoutItem.anchors.bottomMargin : 0) : 0
|
||||
}]
|
||||
}
|
||||
@@ -1,136 +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
|
||||
|
||||
/*!
|
||||
\qmltype ApplicationWindowStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.4
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for ApplicationWindow
|
||||
|
||||
You can create a custom window background by replacing the "background"
|
||||
delegate of ApplicationWindowStyle with a custom design.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
ApplicationWindow {
|
||||
style: ApplicationWindowStyle {
|
||||
background: BorderImage {
|
||||
source: "background.png"
|
||||
border { left: 20; top: 20; right: 20; bottom: 20 }
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
QtObject {
|
||||
/*! The window attached to this style. */
|
||||
readonly property ApplicationWindow control: __control
|
||||
|
||||
/*! A custom background for the window.
|
||||
|
||||
\note The window might have a custom background color set. The custom
|
||||
background color is automatically filled by the window. The background
|
||||
delegate should respect the custom background color by either hiding
|
||||
itself altogether when a custom background color is set, or by letting
|
||||
the custom background color shine through.
|
||||
|
||||
The following read-only property is available within the scope
|
||||
of the background delegate:
|
||||
\table
|
||||
\row \li \b {styleData.hasColor} : bool \li Whether the window has a custom background color set.
|
||||
\endtable
|
||||
*/
|
||||
property Component background: Rectangle {
|
||||
visible: !styleData.hasColor
|
||||
color: SystemPaletteSingleton.window(true)
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
readonly property alias contentArea: contentArea
|
||||
readonly property alias menuBarArea: menuBarArea
|
||||
readonly property alias toolBarArea: toolBarArea
|
||||
readonly property alias statusBarArea: statusBarArea
|
||||
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
sourceComponent: background
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentArea
|
||||
anchors.top: toolBarArea.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: statusBarArea.top
|
||||
}
|
||||
|
||||
Item {
|
||||
id: toolBarArea
|
||||
anchors.top: parent.menuBarArea.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
implicitHeight: childrenRect.height
|
||||
height: visibleChildren.length > 0 ? implicitHeight: 0
|
||||
}
|
||||
|
||||
Item {
|
||||
id: menuBarArea
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
implicitHeight: childrenRect.height
|
||||
height: visibleChildren.length > 0 ? implicitHeight: 0
|
||||
}
|
||||
|
||||
Item {
|
||||
id: statusBarArea
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
implicitHeight: childrenRect.height
|
||||
height: visibleChildren.length > 0 ? implicitHeight: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,120 +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 BusyIndicatorStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.2
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for BusyIndicatorStyle
|
||||
|
||||
You can create a busy indicator by replacing the "indicator" delegate
|
||||
of the BusyIndicatorStyle with a custom design.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
BusyIndicator {
|
||||
style: BusyIndicatorStyle {
|
||||
indicator: Image {
|
||||
visible: control.running
|
||||
source: "spinner.png"
|
||||
RotationAnimator on rotation {
|
||||
running: control.running
|
||||
loops: Animation.Infinite
|
||||
duration: 2000
|
||||
from: 0 ; to: 360
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
Style {
|
||||
id: indicatorstyle
|
||||
|
||||
/*! The \l BusyIndicator this style is attached to. */
|
||||
readonly property BusyIndicator control: __control
|
||||
|
||||
/*! This defines the appearance of the busy indicator. */
|
||||
property Component indicator: Item {
|
||||
id: indicatorItem
|
||||
|
||||
implicitWidth: 48
|
||||
implicitHeight: 48
|
||||
|
||||
opacity: control.running ? 1 : 0
|
||||
Behavior on opacity { OpacityAnimator { duration: 250 } }
|
||||
|
||||
Image {
|
||||
anchors.centerIn: parent
|
||||
anchors.alignWhenCentered: true
|
||||
width: Math.min(parent.width, parent.height)
|
||||
height: width
|
||||
source: width <= 32 ? "images/spinner_small.png" :
|
||||
width >= 48 ? "images/spinner_large.png" :
|
||||
"images/spinner_medium.png"
|
||||
RotationAnimator on rotation {
|
||||
duration: 800
|
||||
loops: Animation.Infinite
|
||||
from: 0
|
||||
to: 360
|
||||
running: indicatorItem.visible && (control.running || indicatorItem.opacity > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
anchors.fill: parent
|
||||
implicitWidth: indicatorLoader.implicitWidth
|
||||
implicitHeight: indicatorLoader.implicitHeight
|
||||
|
||||
Loader {
|
||||
id: indicatorLoader
|
||||
sourceComponent: indicator
|
||||
anchors.centerIn: parent
|
||||
width: Math.min(parent.width, parent.height)
|
||||
height: width
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,175 +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 ButtonStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.1
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for Button
|
||||
|
||||
You can create a custom button by replacing the "background" delegate
|
||||
of the ButtonStyle with a custom design.
|
||||
|
||||
Example:
|
||||
\qml
|
||||
Button {
|
||||
text: "A button"
|
||||
style: ButtonStyle {
|
||||
background: Rectangle {
|
||||
implicitWidth: 100
|
||||
implicitHeight: 25
|
||||
border.width: control.activeFocus ? 2 : 1
|
||||
border.color: "#888"
|
||||
radius: 4
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0 ; color: control.pressed ? "#ccc" : "#eee" }
|
||||
GradientStop { position: 1 ; color: control.pressed ? "#aaa" : "#ccc" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
If you need a custom label, you can replace the label item.
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: buttonstyle
|
||||
|
||||
/*! The \l {QtQuick.Controls::}{Button} this style is attached to. */
|
||||
readonly property Button control: __control
|
||||
|
||||
/*! The padding between the background and the label components. */
|
||||
padding {
|
||||
top: 4
|
||||
left: 4
|
||||
right: 4 + (control.menu !== null ? Math.round(TextSingleton.implicitHeight * 0.5) : 0)
|
||||
bottom: 4
|
||||
}
|
||||
|
||||
/*! This defines the background of the button. */
|
||||
property Component background: Item {
|
||||
property bool down: control.pressed || (control.checkable && control.checked)
|
||||
implicitWidth: Math.round(TextSingleton.implicitHeight * 4.5)
|
||||
implicitHeight: Math.max(25, Math.round(TextSingleton.implicitHeight * 1.2))
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: down ? 0 : -1
|
||||
color: "#10000000"
|
||||
radius: baserect.radius
|
||||
}
|
||||
Rectangle {
|
||||
id: baserect
|
||||
gradient: Gradient {
|
||||
GradientStop {color: down ? "#aaa" : "#fefefe" ; position: 0}
|
||||
GradientStop {color: down ? "#ccc" : "#e3e3e3" ; position: down ? 0.1: 1}
|
||||
}
|
||||
radius: TextSingleton.implicitHeight * 0.16
|
||||
anchors.fill: parent
|
||||
border.color: control.activeFocus ? "#47b" : "#999"
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: parent.radius
|
||||
color: control.activeFocus ? "#47b" : "white"
|
||||
opacity: control.hovered || control.activeFocus ? 0.1 : 0
|
||||
Behavior on opacity {NumberAnimation{ duration: 100 }}
|
||||
}
|
||||
}
|
||||
Image {
|
||||
id: imageItem
|
||||
visible: control.menu !== null
|
||||
source: "images/arrow-down.png"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 4
|
||||
opacity: control.enabled ? 0.6 : 0.5
|
||||
}
|
||||
}
|
||||
|
||||
/*! This defines the label of the button. */
|
||||
property Component label: Item {
|
||||
implicitWidth: row.implicitWidth
|
||||
implicitHeight: row.implicitHeight
|
||||
baselineOffset: row.y + text.y + text.baselineOffset
|
||||
Row {
|
||||
id: row
|
||||
anchors.centerIn: parent
|
||||
spacing: 2
|
||||
Image {
|
||||
source: control.iconSource
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
Text {
|
||||
id: text
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: StyleHelpers.stylizeMnemonics(control.text)
|
||||
color: SystemPaletteSingleton.buttonText(control.enabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
anchors.fill: parent
|
||||
implicitWidth: Math.max(labelLoader.implicitWidth + padding.left + padding.right, backgroundLoader.implicitWidth)
|
||||
implicitHeight: Math.max(labelLoader.implicitHeight + padding.top + padding.bottom, backgroundLoader.implicitHeight)
|
||||
baselineOffset: labelLoader.item ? padding.top + labelLoader.item.baselineOffset : 0
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: background
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: labelLoader
|
||||
sourceComponent: label
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: padding.left
|
||||
anchors.topMargin: padding.top
|
||||
anchors.rightMargin: padding.right
|
||||
anchors.bottomMargin: padding.bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,691 +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
|
||||
|
||||
/*!
|
||||
\qmltype CalendarStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.3
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for \l Calendar
|
||||
|
||||
\section2 Component Map
|
||||
|
||||
\image calendarstyle-components-week-numbers.png
|
||||
|
||||
The calendar has the following styleable components:
|
||||
|
||||
\table
|
||||
\row \li \image square-white.png
|
||||
\li \l background
|
||||
\li Fills the entire control.
|
||||
\row \li \image square-yellow.png
|
||||
\li \l navigationBar
|
||||
\li
|
||||
\row \li \image square-green.png
|
||||
\li \l dayOfWeekDelegate
|
||||
\li One instance per day of week.
|
||||
\row \li \image square-red.png
|
||||
\li \l weekNumberDelegate
|
||||
\li One instance per week.
|
||||
\row \li \image square-blue.png
|
||||
\li \l dayDelegate
|
||||
\li One instance per day of month.
|
||||
\endtable
|
||||
|
||||
\section2 Custom Style Example
|
||||
\qml
|
||||
Calendar {
|
||||
anchors.centerIn: parent
|
||||
|
||||
style: CalendarStyle {
|
||||
gridVisible: false
|
||||
dayDelegate: Rectangle {
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0.00
|
||||
color: styleData.selected ? "#111" : (styleData.visibleMonth && styleData.valid ? "#444" : "#666");
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.00
|
||||
color: styleData.selected ? "#444" : (styleData.visibleMonth && styleData.valid ? "#111" : "#666");
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.00
|
||||
color: styleData.selected ? "#777" : (styleData.visibleMonth && styleData.valid ? "#111" : "#666");
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: styleData.date.getDate()
|
||||
anchors.centerIn: parent
|
||||
color: styleData.valid ? "white" : "grey"
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: "#555"
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 1
|
||||
height: parent.height
|
||||
color: "#555"
|
||||
anchors.right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
|
||||
Style {
|
||||
id: calendarStyle
|
||||
|
||||
/*!
|
||||
The Calendar this style is attached to.
|
||||
*/
|
||||
readonly property Calendar control: __control
|
||||
|
||||
/*!
|
||||
The color of the grid lines.
|
||||
*/
|
||||
property color gridColor: "#d3d3d3"
|
||||
|
||||
/*!
|
||||
This property determines the visibility of the grid.
|
||||
|
||||
The default value is \c true.
|
||||
*/
|
||||
property bool gridVisible: true
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
||||
The width of each grid line.
|
||||
*/
|
||||
property real __gridLineWidth: 1
|
||||
|
||||
/*! \internal */
|
||||
property color __horizontalSeparatorColor: gridColor
|
||||
|
||||
/*! \internal */
|
||||
property color __verticalSeparatorColor: gridColor
|
||||
|
||||
function __cellRectAt(index) {
|
||||
return CalendarUtils.cellRectAt(index, control.__panel.columns, control.__panel.rows,
|
||||
control.__panel.availableWidth, control.__panel.availableHeight, gridVisible ? __gridLineWidth : 0);
|
||||
}
|
||||
|
||||
function __isValidDate(date) {
|
||||
return date !== undefined
|
||||
&& date.getTime() >= control.minimumDate.getTime()
|
||||
&& date.getTime() <= control.maximumDate.getTime();
|
||||
}
|
||||
|
||||
/*!
|
||||
The background of the calendar.
|
||||
|
||||
The implicit size of the calendar is calculated based on the implicit size of the background delegate.
|
||||
*/
|
||||
property Component background: Rectangle {
|
||||
color: "#fff"
|
||||
implicitWidth: Math.max(250, Math.round(TextSingleton.implicitHeight * 14))
|
||||
implicitHeight: Math.max(250, Math.round(TextSingleton.implicitHeight * 14))
|
||||
}
|
||||
|
||||
/*!
|
||||
The navigation bar of the calendar.
|
||||
|
||||
Styles the bar at the top of the calendar that contains the
|
||||
next month/previous month buttons and the selected date label.
|
||||
|
||||
The properties provided to the delegate are:
|
||||
\table
|
||||
\row \li readonly property string \b styleData.title
|
||||
\li The title of the calendar.
|
||||
\endtable
|
||||
*/
|
||||
property Component navigationBar: Rectangle {
|
||||
height: Math.round(TextSingleton.implicitHeight * 2.73)
|
||||
color: "#f9f9f9"
|
||||
|
||||
Rectangle {
|
||||
color: Qt.rgba(1,1,1,0.6)
|
||||
height: 1
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.bottom: parent.bottom
|
||||
height: 1
|
||||
width: parent.width
|
||||
color: "#ddd"
|
||||
}
|
||||
HoverButton {
|
||||
id: previousMonth
|
||||
width: parent.height
|
||||
height: width
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
source: "images/leftanglearrow.png"
|
||||
onClicked: control.showPreviousMonth()
|
||||
}
|
||||
Label {
|
||||
id: dateText
|
||||
text: styleData.title
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: TextSingleton.implicitHeight * 1.25
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: previousMonth.right
|
||||
anchors.leftMargin: 2
|
||||
anchors.right: nextMonth.left
|
||||
anchors.rightMargin: 2
|
||||
}
|
||||
HoverButton {
|
||||
id: nextMonth
|
||||
width: parent.height
|
||||
height: width
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
source: "images/rightanglearrow.png"
|
||||
onClicked: control.showNextMonth()
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The delegate that styles each date in the calendar.
|
||||
|
||||
The properties provided to each delegate are:
|
||||
\table
|
||||
\row \li readonly property date \b styleData.date
|
||||
\li The date this delegate represents.
|
||||
\row \li readonly property bool \b styleData.selected
|
||||
\li \c true if this is the selected date.
|
||||
\row \li readonly property int \b styleData.index
|
||||
\li The index of this delegate.
|
||||
\row \li readonly property bool \b styleData.valid
|
||||
\li \c true if this date is greater than or equal to than \l {Calendar::minimumDate}{minimumDate} and
|
||||
less than or equal to \l {Calendar::maximumDate}{maximumDate}.
|
||||
\row \li readonly property bool \b styleData.today
|
||||
\li \c true if this date is equal to today's date.
|
||||
\row \li readonly property bool \b styleData.visibleMonth
|
||||
\li \c true if the month in this date is the visible month.
|
||||
\row \li readonly property bool \b styleData.hovered
|
||||
\li \c true if the mouse is over this cell.
|
||||
\note This property is \c true even when the mouse is hovered over an invalid date.
|
||||
\row \li readonly property bool \b styleData.pressed
|
||||
\li \c true if the mouse is pressed on this cell.
|
||||
\note This property is \c true even when the mouse is pressed on an invalid date.
|
||||
\endtable
|
||||
*/
|
||||
property Component dayDelegate: Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: (!addExtraMargin || control.weekNumbersVisible) && styleData.index % CalendarUtils.daysInAWeek === 0 ? 0 : -1
|
||||
anchors.rightMargin: !addExtraMargin && styleData.index % CalendarUtils.daysInAWeek === CalendarUtils.daysInAWeek - 1 ? 0 : -1
|
||||
anchors.bottomMargin: !addExtraMargin && styleData.index >= CalendarUtils.daysInAWeek * (CalendarUtils.weeksOnACalendarMonth - 1) ? 0 : -1
|
||||
anchors.topMargin: styleData.selected ? -1 : 0
|
||||
color: styleData.date !== undefined && styleData.selected ? selectedDateColor : "transparent"
|
||||
|
||||
readonly property bool addExtraMargin: control.frameVisible && styleData.selected
|
||||
readonly property color sameMonthDateTextColor: "#444"
|
||||
readonly property color selectedDateColor: Qt.platform.os === "osx" ? "#3778d0" : SystemPaletteSingleton.highlight(control.enabled)
|
||||
readonly property color selectedDateTextColor: "white"
|
||||
readonly property color differentMonthDateTextColor: "#bbb"
|
||||
readonly property color invalidDateColor: "#dddddd"
|
||||
Label {
|
||||
id: dayDelegateText
|
||||
text: styleData.date.getDate()
|
||||
anchors.centerIn: parent
|
||||
horizontalAlignment: Text.AlignRight
|
||||
font.pixelSize: Math.min(parent.height/3, parent.width/3)
|
||||
color: {
|
||||
var theColor = invalidDateColor;
|
||||
if (styleData.valid) {
|
||||
// Date is within the valid range.
|
||||
theColor = styleData.visibleMonth ? sameMonthDateTextColor : differentMonthDateTextColor;
|
||||
if (styleData.selected)
|
||||
theColor = selectedDateTextColor;
|
||||
}
|
||||
theColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The delegate that styles each weekday.
|
||||
|
||||
The height of the weekday row is calculated based on the maximum implicit height of the delegates.
|
||||
|
||||
The properties provided to each delegate are:
|
||||
\table
|
||||
\row \li readonly property int \b styleData.index
|
||||
\li The index (0-6) of the delegate.
|
||||
\row \li readonly property int \b styleData.dayOfWeek
|
||||
\li The day of the week this delegate represents. Possible values:
|
||||
\list
|
||||
\li \c Locale.Sunday
|
||||
\li \c Locale.Monday
|
||||
\li \c Locale.Tuesday
|
||||
\li \c Locale.Wednesday
|
||||
\li \c Locale.Thursday
|
||||
\li \c Locale.Friday
|
||||
\li \c Locale.Saturday
|
||||
\endlist
|
||||
\endtable
|
||||
*/
|
||||
property Component dayOfWeekDelegate: Rectangle {
|
||||
color: gridVisible ? "#fcfcfc" : "transparent"
|
||||
implicitHeight: Math.round(TextSingleton.implicitHeight * 2.25)
|
||||
Label {
|
||||
text: control.__locale.dayName(styleData.dayOfWeek, control.dayOfWeekFormat)
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
The delegate that styles each week number.
|
||||
|
||||
The width of the week number column is calculated based on the maximum implicit width of the delegates.
|
||||
|
||||
The properties provided to each delegate are:
|
||||
\table
|
||||
\row \li readonly property int \b styleData.index
|
||||
\li The index (0-5) of the delegate.
|
||||
\row \li readonly property int \b styleData.weekNumber
|
||||
\li The number of the week this delegate represents.
|
||||
\endtable
|
||||
*/
|
||||
property Component weekNumberDelegate: Rectangle {
|
||||
implicitWidth: Math.round(TextSingleton.implicitHeight * 2)
|
||||
Label {
|
||||
text: styleData.weekNumber
|
||||
anchors.centerIn: parent
|
||||
color: "#444"
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
id: panelItem
|
||||
|
||||
implicitWidth: backgroundLoader.implicitWidth
|
||||
implicitHeight: backgroundLoader.implicitHeight
|
||||
|
||||
property alias navigationBarItem: navigationBarLoader.item
|
||||
|
||||
property alias dayOfWeekHeaderRow: dayOfWeekHeaderRow
|
||||
|
||||
readonly property int weeksToShow: 6
|
||||
readonly property int rows: weeksToShow
|
||||
readonly property int columns: CalendarUtils.daysInAWeek
|
||||
|
||||
// The combined available width and height to be shared amongst each cell.
|
||||
readonly property real availableWidth: viewContainer.width
|
||||
readonly property real availableHeight: viewContainer.height
|
||||
|
||||
property int hoveredCellIndex: -1
|
||||
property int pressedCellIndex: -1
|
||||
property int pressCellIndex: -1
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
border.color: gridColor
|
||||
visible: control.frameVisible
|
||||
}
|
||||
|
||||
Item {
|
||||
id: container
|
||||
anchors.fill: parent
|
||||
anchors.margins: control.frameVisible ? 1 : 0
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
anchors.fill: parent
|
||||
sourceComponent: background
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: navigationBarLoader
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
sourceComponent: navigationBar
|
||||
active: control.navigationBarVisible
|
||||
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property string title: control.__locale.standaloneMonthName(control.visibleMonth)
|
||||
+ new Date(control.visibleYear, control.visibleMonth, 1).toLocaleDateString(control.__locale, " yyyy")
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: dayOfWeekHeaderRow
|
||||
anchors.top: navigationBarLoader.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: (control.weekNumbersVisible ? weekNumbersItem.width : 0)
|
||||
anchors.right: parent.right
|
||||
spacing: gridVisible ? __gridLineWidth : 0
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: CalendarHeaderModel {
|
||||
locale: control.__locale
|
||||
}
|
||||
Loader {
|
||||
id: dayOfWeekDelegateLoader
|
||||
sourceComponent: dayOfWeekDelegate
|
||||
width: __cellRectAt(index).width
|
||||
|
||||
readonly property int __index: index
|
||||
readonly property var __dayOfWeek: dayOfWeek
|
||||
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias index: dayOfWeekDelegateLoader.__index
|
||||
readonly property alias dayOfWeek: dayOfWeekDelegateLoader.__dayOfWeek
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: topGridLine
|
||||
color: __horizontalSeparatorColor
|
||||
width: parent.width
|
||||
height: __gridLineWidth
|
||||
visible: gridVisible
|
||||
anchors.top: dayOfWeekHeaderRow.bottom
|
||||
}
|
||||
|
||||
Row {
|
||||
id: gridRow
|
||||
width: weekNumbersItem.width + viewContainer.width
|
||||
height: viewContainer.height
|
||||
anchors.top: topGridLine.bottom
|
||||
|
||||
Column {
|
||||
id: weekNumbersItem
|
||||
visible: control.weekNumbersVisible
|
||||
height: viewContainer.height
|
||||
spacing: gridVisible ? __gridLineWidth : 0
|
||||
Repeater {
|
||||
id: weekNumberRepeater
|
||||
model: panelItem.weeksToShow
|
||||
|
||||
Loader {
|
||||
id: weekNumberDelegateLoader
|
||||
height: __cellRectAt(index * panelItem.columns).height
|
||||
sourceComponent: weekNumberDelegate
|
||||
|
||||
readonly property int __index: index
|
||||
property int __weekNumber: control.__model.weekNumberAt(index)
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
onVisibleMonthChanged: __weekNumber = control.__model.weekNumberAt(index)
|
||||
onVisibleYearChanged: __weekNumber = control.__model.weekNumberAt(index)
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: control.__model
|
||||
onCountChanged: __weekNumber = control.__model.weekNumberAt(index)
|
||||
}
|
||||
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias index: weekNumberDelegateLoader.__index
|
||||
readonly property int weekNumber: weekNumberDelegateLoader.__weekNumber
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: separator
|
||||
anchors.topMargin: - dayOfWeekHeaderRow.height - 1
|
||||
anchors.top: weekNumbersItem.top
|
||||
anchors.bottom: weekNumbersItem.bottom
|
||||
|
||||
width: __gridLineWidth
|
||||
color: __verticalSeparatorColor
|
||||
visible: control.weekNumbersVisible
|
||||
}
|
||||
|
||||
// Contains the grid lines and the grid itself.
|
||||
Item {
|
||||
id: viewContainer
|
||||
width: container.width - (control.weekNumbersVisible ? weekNumbersItem.width + separator.width : 0)
|
||||
height: container.height - navigationBarLoader.height - dayOfWeekHeaderRow.height - topGridLine.height
|
||||
|
||||
Repeater {
|
||||
id: verticalGridLineRepeater
|
||||
model: panelItem.columns - 1
|
||||
delegate: Rectangle {
|
||||
x: __cellRectAt(index + 1).x - __gridLineWidth
|
||||
y: 0
|
||||
width: __gridLineWidth
|
||||
height: viewContainer.height
|
||||
color: gridColor
|
||||
visible: gridVisible
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: horizontalGridLineRepeater
|
||||
model: panelItem.rows - 1
|
||||
delegate: Rectangle {
|
||||
x: 0
|
||||
y: __cellRectAt((index + 1) * panelItem.columns).y - __gridLineWidth
|
||||
width: viewContainer.width
|
||||
height: __gridLineWidth
|
||||
color: gridColor
|
||||
visible: gridVisible
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
|
||||
hoverEnabled: Settings.hoverEnabled
|
||||
|
||||
function cellIndexAt(mouseX, mouseY) {
|
||||
var viewContainerPos = viewContainer.mapFromItem(mouseArea, mouseX, mouseY);
|
||||
var child = viewContainer.childAt(viewContainerPos.x, viewContainerPos.y);
|
||||
// In the tests, the mouseArea sometimes gets picked instead of the cells,
|
||||
// probably because stuff is still loading. To be safe, we check for that here.
|
||||
return child && child !== mouseArea ? child.__index : -1;
|
||||
}
|
||||
|
||||
onEntered: {
|
||||
hoveredCellIndex = cellIndexAt(mouseX, mouseY);
|
||||
if (hoveredCellIndex === undefined) {
|
||||
hoveredCellIndex = cellIndexAt(mouseX, mouseY);
|
||||
}
|
||||
|
||||
var date = view.model.dateAt(hoveredCellIndex);
|
||||
if (__isValidDate(date)) {
|
||||
control.hovered(date);
|
||||
}
|
||||
}
|
||||
|
||||
onExited: {
|
||||
hoveredCellIndex = -1;
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
var indexOfCell = cellIndexAt(mouse.x, mouse.y);
|
||||
var previousHoveredCellIndex = hoveredCellIndex;
|
||||
hoveredCellIndex = indexOfCell;
|
||||
if (indexOfCell !== -1) {
|
||||
var date = view.model.dateAt(indexOfCell);
|
||||
if (__isValidDate(date)) {
|
||||
if (hoveredCellIndex !== previousHoveredCellIndex)
|
||||
control.hovered(date);
|
||||
|
||||
// The date must be different for the pressed signal to be emitted.
|
||||
if (pressed && date.getTime() !== control.selectedDate.getTime()) {
|
||||
control.pressed(date);
|
||||
|
||||
// You can't select dates in a different month while dragging.
|
||||
if (date.getMonth() === control.selectedDate.getMonth()) {
|
||||
control.selectedDate = date;
|
||||
pressedCellIndex = indexOfCell;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
pressCellIndex = cellIndexAt(mouse.x, mouse.y);
|
||||
if (pressCellIndex !== -1) {
|
||||
var date = view.model.dateAt(pressCellIndex);
|
||||
pressedCellIndex = pressCellIndex;
|
||||
if (__isValidDate(date)) {
|
||||
control.selectedDate = date;
|
||||
control.pressed(date);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
var indexOfCell = cellIndexAt(mouse.x, mouse.y);
|
||||
if (indexOfCell !== -1) {
|
||||
// The cell index might be valid, but the date has to be too. We could let the
|
||||
// selected date validation take care of this, but then the selected date would
|
||||
// change to the earliest day if a day before the minimum date is clicked, for example.
|
||||
var date = view.model.dateAt(indexOfCell);
|
||||
if (__isValidDate(date)) {
|
||||
control.released(date);
|
||||
}
|
||||
}
|
||||
pressedCellIndex = -1;
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
var indexOfCell = cellIndexAt(mouse.x, mouse.y);
|
||||
if (indexOfCell !== -1 && indexOfCell === pressCellIndex) {
|
||||
var date = view.model.dateAt(indexOfCell);
|
||||
if (__isValidDate(date))
|
||||
control.clicked(date);
|
||||
}
|
||||
}
|
||||
|
||||
onDoubleClicked: {
|
||||
var indexOfCell = cellIndexAt(mouse.x, mouse.y);
|
||||
if (indexOfCell !== -1) {
|
||||
var date = view.model.dateAt(indexOfCell);
|
||||
if (__isValidDate(date))
|
||||
control.doubleClicked(date);
|
||||
}
|
||||
}
|
||||
|
||||
onPressAndHold: {
|
||||
var indexOfCell = cellIndexAt(mouse.x, mouse.y);
|
||||
if (indexOfCell !== -1 && indexOfCell === pressCellIndex) {
|
||||
var date = view.model.dateAt(indexOfCell);
|
||||
if (__isValidDate(date))
|
||||
control.pressAndHold(date);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: control
|
||||
onSelectedDateChanged: view.selectedDateChanged()
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: view
|
||||
|
||||
property int currentIndex: -1
|
||||
|
||||
model: control.__model
|
||||
|
||||
Component.onCompleted: selectedDateChanged()
|
||||
|
||||
function selectedDateChanged() {
|
||||
if (model !== undefined && model.locale !== undefined) {
|
||||
currentIndex = model.indexAt(control.selectedDate);
|
||||
}
|
||||
}
|
||||
|
||||
delegate: Loader {
|
||||
id: delegateLoader
|
||||
|
||||
x: __cellRectAt(index).x
|
||||
y: __cellRectAt(index).y
|
||||
width: __cellRectAt(index).width
|
||||
height: __cellRectAt(index).height
|
||||
sourceComponent: dayDelegate
|
||||
|
||||
readonly property int __index: index
|
||||
readonly property date __date: date
|
||||
// We rely on the fact that an invalid QDate will be converted to a Date
|
||||
// whose year is -4713, which is always an invalid date since our
|
||||
// earliest minimum date is the year 1.
|
||||
readonly property bool valid: __isValidDate(date)
|
||||
|
||||
property QtObject styleData: QtObject {
|
||||
readonly property alias index: delegateLoader.__index
|
||||
readonly property bool selected: control.selectedDate.getTime() === date.getTime()
|
||||
readonly property alias date: delegateLoader.__date
|
||||
readonly property bool valid: delegateLoader.valid
|
||||
// TODO: this will not be correct if the app is running when a new day begins.
|
||||
readonly property bool today: date.getTime() === new Date().setHours(0, 0, 0, 0)
|
||||
readonly property bool visibleMonth: date.getMonth() === control.visibleMonth
|
||||
readonly property bool hovered: panelItem.hoveredCellIndex == index
|
||||
readonly property bool pressed: panelItem.pressedCellIndex == index
|
||||
// todo: pressed property here, clicked and doubleClicked in the control itself
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,195 +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.Layouts 1.1
|
||||
import QtQuick.Window 2.1
|
||||
import QtQuick.Controls.Private 1.0
|
||||
|
||||
/*!
|
||||
\qmltype CheckBoxStyle
|
||||
\inqmlmodule QtQuick.Controls.Styles
|
||||
\since 5.1
|
||||
\ingroup controlsstyling
|
||||
\brief Provides custom styling for CheckBox
|
||||
|
||||
Example:
|
||||
\qml
|
||||
CheckBox {
|
||||
text: "Check Box"
|
||||
style: CheckBoxStyle {
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 16
|
||||
implicitHeight: 16
|
||||
radius: 3
|
||||
border.color: control.activeFocus ? "darkblue" : "gray"
|
||||
border.width: 1
|
||||
Rectangle {
|
||||
visible: control.checked
|
||||
color: "#555"
|
||||
border.color: "#333"
|
||||
radius: 1
|
||||
anchors.margins: 4
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
Style {
|
||||
id: checkboxStyle
|
||||
|
||||
/*! The \l CheckBox this style is attached to. */
|
||||
readonly property CheckBox control: __control
|
||||
|
||||
/*! This defines the text label. */
|
||||
property Component label: Item {
|
||||
implicitWidth: text.implicitWidth + 2
|
||||
implicitHeight: text.implicitHeight
|
||||
baselineOffset: text.baselineOffset
|
||||
Rectangle {
|
||||
anchors.fill: text
|
||||
anchors.margins: -1
|
||||
anchors.leftMargin: -3
|
||||
anchors.rightMargin: -3
|
||||
visible: control.activeFocus
|
||||
height: 6
|
||||
radius: 3
|
||||
color: "#224f9fef"
|
||||
border.color: "#47b"
|
||||
opacity: 0.6
|
||||
}
|
||||
Text {
|
||||
id: text
|
||||
text: StyleHelpers.stylizeMnemonics(control.text)
|
||||
anchors.centerIn: parent
|
||||
color: SystemPaletteSingleton.text(control.enabled)
|
||||
renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering
|
||||
}
|
||||
}
|
||||
/*! The background under indicator and label. */
|
||||
property Component background
|
||||
|
||||
/*! The spacing between indicator and label. */
|
||||
property int spacing: Math.round(TextSingleton.implicitHeight/4)
|
||||
|
||||
/*! This defines the indicator button. */
|
||||
property Component indicator: Item {
|
||||
implicitWidth: Math.round(TextSingleton.implicitHeight)
|
||||
height: width
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: -1
|
||||
color: "#44ffffff"
|
||||
radius: baserect.radius
|
||||
}
|
||||
Rectangle {
|
||||
id: baserect
|
||||
gradient: Gradient {
|
||||
GradientStop {color: "#eee" ; position: 0}
|
||||
GradientStop {color: control.pressed ? "#eee" : "#fff" ; position: 0.1}
|
||||
GradientStop {color: "#fff" ; position: 1}
|
||||
}
|
||||
radius: TextSingleton.implicitHeight * 0.16
|
||||
anchors.fill: parent
|
||||
border.color: control.activeFocus ? "#47b" : "#999"
|
||||
}
|
||||
|
||||
Image {
|
||||
source: "images/check.png"
|
||||
opacity: control.checkedState === Qt.Checked ? control.enabled ? 1 : 0.5 : 0
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: 1
|
||||
Behavior on opacity {NumberAnimation {duration: 80}}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Math.round(baserect.radius)
|
||||
antialiasing: true
|
||||
gradient: Gradient {
|
||||
GradientStop {color: control.pressed ? "#555" : "#999" ; position: 0}
|
||||
GradientStop {color: "#555" ; position: 1}
|
||||
}
|
||||
radius: baserect.radius - 1
|
||||
anchors.centerIn: parent
|
||||
anchors.alignWhenCentered: true
|
||||
border.color: "#222"
|
||||
Behavior on opacity {NumberAnimation {duration: 80}}
|
||||
opacity: control.checkedState === Qt.PartiallyChecked ? control.enabled ? 1 : 0.5 : 0
|
||||
}
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
property Component panel: Item {
|
||||
implicitWidth: Math.max(backgroundLoader.implicitWidth, row.implicitWidth + padding.left + padding.right)
|
||||
implicitHeight: Math.max(backgroundLoader.implicitHeight, labelLoader.implicitHeight + padding.top + padding.bottom,indicatorLoader.implicitHeight + padding.top + padding.bottom)
|
||||
baselineOffset: labelLoader.item ? padding.top + labelLoader.item.baselineOffset : 0
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
sourceComponent: background
|
||||
anchors.fill: parent
|
||||
}
|
||||
RowLayout {
|
||||
id: row
|
||||
anchors.fill: parent
|
||||
|
||||
anchors.leftMargin: padding.left
|
||||
anchors.rightMargin: padding.right
|
||||
anchors.topMargin: padding.top
|
||||
anchors.bottomMargin: padding.bottom
|
||||
|
||||
spacing: checkboxStyle.spacing
|
||||
Loader {
|
||||
id: indicatorLoader
|
||||
sourceComponent: indicator
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
Loader {
|
||||
id: labelLoader
|
||||
Layout.fillWidth: true
|
||||
sourceComponent: label
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user