Compare commits

..

10 Commits

Author SHA1 Message Date
Matthias Clasen
244cdafe1b Add gsk_path_get_previous/next_point
These functions let you iterate over the 'significant'
points of a path.
2023-08-08 11:06:35 -04:00
Matthias Clasen
a0d17418de fixup start/end point 2023-08-08 10:41:03 -04:00
Matthias Clasen
093e6241e7 path: Add gsk_path_get_start/end_point
These are useful to have, now that we are
relying more on GskPathPoint in our api.
2023-08-08 08:38:36 -04:00
Matthias Clasen
67b504f823 Add tests for gsk_path_builder_add_segment
Test at least some of the special cases:
- start and end point on the same contour
- start and end point on the same segment
- end before start
2023-08-08 08:37:51 -04:00
Matthias Clasen
659bc813a4 Redo gsk_path_builder_add_segment 2023-08-08 08:37:51 -04:00
Benjamin Otte
293c0774b3 demos: Add a text-on-path demo 2023-08-07 19:52:17 -04:00
Matthias Clasen
988062889b Add tests for GskPathMeasure 2023-08-07 19:52:17 -04:00
Matthias Clasen
461922b495 Avoid zero-length measure segments
if measure->start == measure->end, we are in trouble.
2023-08-07 19:52:17 -04:00
Matthias Clasen
7150a53ccb contour: measure fixes 2023-08-07 19:43:47 -04:00
Matthias Clasen
1e306b148e Add GskPathMeasure
GskPathMeasure is an auxiliary object for
measuring path lengths.
2023-08-07 19:43:47 -04:00
2299 changed files with 123234 additions and 264153 deletions

View File

@@ -1,4 +1,4 @@
# See https://www.apertis.org/policies/coding_conventions/#code-formatting
# See https://wiki.apertis.org/Guidelines/Coding_conventions#Code_formatting
BasedOnStyle: GNU
AlwaysBreakAfterDefinitionReturnType: All
BreakBeforeBinaryOperators: None

View File

@@ -26,21 +26,12 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Dbuild-testsuite=true -Dintrospection=enabled"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
MESON_TEST_MAX_PROCESSES: 8
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v52"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v48"
workflow:
rules:
# run merge request pipelines
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# do not run branch pipelines if corresponding merge requests exist...
# (this avoids duplicate pipelines)
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
# ...but otherwise run branch pipelines
- if: $CI_COMMIT_BRANCH
# run tag pipelines
- if: $CI_COMMIT_TAG
- if: $CI_COMMIT_BRANCH
default:
retry:
@@ -67,7 +58,7 @@ style-check-diff:
junit:
- "${CI_PROJECT_DIR}/_build/report-x11.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gl.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gles.xml"
- "${CI_PROJECT_DIR}/_build/report-broadway.xml"
name: "gtk-${CI_COMMIT_REF_NAME}"
paths:
@@ -78,7 +69,6 @@ style-check-diff:
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.node"
- "${CI_PROJECT_DIR}/_build/testsuite/tools/output/*/*"
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.node"
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
- "${CI_PROJECT_DIR}/_build/testsuite/headless/*/*.log"
- "${CI_PROJECT_DIR}/_build_hello/meson-logs"
@@ -105,9 +95,8 @@ fedora-x86_64:
${FEATURE_FLAGS}
_build
- meson compile -C _build
- .gitlab-ci/run-tests.sh _build x11 gtk
# only repeat test runs that are likely affected by test setups
- .gitlab-ci/run-tests.sh _build wayland_gl gtk:gdk,gtk:gsk-gl
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build wayland_gles
release-build:
extends: .build-fedora-default
@@ -117,12 +106,10 @@ release-build:
EXTRA_MESON_FLAGS: "--buildtype=release"
script:
- .gitlab-ci/show-info-linux.sh
- mkdir _install
# don't use catch by default, since it causes sporadic test failures
# - export PATH="$HOME/.local/bin:${CI_PROJECT_DIR}/_install/bin:$PATH"
# - .gitlab-ci/install-meson-project.sh --prefix ${CI_PROJECT_DIR}/_install https://gitlab.gnome.org/jadahl/catch.git main
- export PATH="$HOME/.local/bin:$PATH"
- meson subprojects download
- meson subprojects update --reset
- mkdir _install
- meson setup
--prefix=${CI_PROJECT_DIR}/_install
${COMMON_MESON_FLAGS}
@@ -134,7 +121,7 @@ release-build:
- meson install -C _build
- PKG_CONFIG_PATH=${CI_PROJECT_DIR}/_install/lib64/pkgconfig:${CI_PROJECT_DIR}/_install/share/pkgconfig meson setup _build_hello examples/hello
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
- .gitlab-ci/run-tests.sh _build wayland gtk
- .gitlab-ci/run-tests.sh _build x11
fedora-clang:
extends: .build-fedora-default
@@ -211,53 +198,34 @@ msys2-mingw64:
- "${CI_PROJECT_DIR}/_build/gtkdll.tar.gz"
macos:
# Sadly, this fails regularly, and its failure is never enlightening
allow_failure: true
rules:
# Do not run in forks as the runner is not available there.
# (except for dehesselle who maintains the runner)
- if: $CI_PROJECT_NAMESPACE != "GNOME" && $CI_PROJECT_NAMESPACE != "dehesselle"
when: never
- if: $RUNNER == "macosintel"
variables:
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
NINJA_PKG: $CI_API_V4_URL/projects/30745/packages/generic/ninja_macos/v1.11.1.1+9/ninja-1.11.1.1-cp38-cp38-macosx_11_0_x86_64.whl
when: manual
allow_failure: true
- if: $RUNNER == "macosarm"
variables:
SDKROOT: /opt/sdks/MacOSX11.3.sdk
NINJA_PKG: ninja==1.11.1.1
- if: $CI_PROJECT_NAMESPACE == "GNOME"
stage: build
parallel:
matrix:
- RUNNER: [ "macosintel", "macosarm" ]
tags:
- ${RUNNER}
- macos
needs: []
variables:
EXTRA_MESON_FLAGS: ""
BACKEND_FLAGS: "-Dx11-backend=false -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dmedia-gstreamer=disabled -Dintrospection=enabled -Dgobject-introspection:werror=false"
TMPDIR: /Users/Shared/work/tmp
PIP_CACHE_DIR: /Users/Shared/build/cache
PIPENV_CACHE_DIR: $PIP_CACHE_DIR
PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR
before_script:
- .gitlab-ci/show-info-macos.sh
- python3 -m venv .venv
# Building the introspection feature requires pkg-config and bison.
- curl -L $CI_API_V4_URL/projects/30437/packages/generic/pkgconfig/v0.29.2+10/pkg-config-0.29.2+10_$(uname -m).tar.xz | tar -C .venv -xJ
- curl -L $CI_API_V4_URL/projects/30438/packages/generic/bison/v3.8.2+3/bison-3.8.2+3_$(uname -m).tar.xz | tar -C .venv -xJ
- source .venv/bin/activate
- pip3 install meson==1.3.2 $NINJA_PKG
# We're not setting up ccache here on purpose as it accelerates the build
# so much that it triggers race conditions in the gobject-introspection
# subproject.
- bash .gitlab-ci/show-info-osx.sh
- pip3 install --user meson~=1.0
- pip3 install --user ninja
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
- export MESON_FORCE_BACKTRACE=1
script:
- meson setup
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
${BACKEND_FLAGS}
${FEATURE_FLAGS}
- meson setup ${COMMON_MESON_FLAGS}
-Dx11-backend=false
-Dbroadway-backend=true
-Dmacos-backend=true
-Dmedia-gstreamer=disabled
-Dintrospection=disabled
-Dcpp_std=c++11
-Dpixman:tests=disabled
-Dlibjpeg-turbo:simd=disabled
-Dbuild-demos=false
-Dbuild-tests=false
-Dbuild-examples=false
-Dbuild-testsuite=false
_build
- meson compile -C _build
artifacts:
@@ -413,12 +381,11 @@ static-scan:
# Run tests with the address sanitizer. We need to turn off introspection
# and f16c, since they are incompatible with asan
asan-build:
extends: .build-fedora-default
image: $FEDORA_IMAGE
tags: [ asan ]
stage: analysis
needs: []
variables:
MESON_TEST_MAX_PROCESSES: 4
script:
- export PATH="$HOME/.local/bin:$PATH"
- CC=clang meson setup
@@ -432,7 +399,13 @@ asan-build:
-Df16c=disabled
_build
- ninja -C _build
- .gitlab-ci/run-tests.sh _build wayland gtk
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build wayland_gles
- .gitlab-ci/run-tests.sh _build x11
artifacts:
when: always
paths:
- "${CI_PROJECT_DIR}/_build/meson-logs"
reference:
image: $FEDORA_IMAGE
@@ -446,10 +419,10 @@ reference:
--force-fallback-for=gdk-pixbuf,pango
-Dintrospection=enabled
-Ddocumentation=true
-Dman-pages=true
-Dgtk_doc=true
-Dgdk-pixbuf:gtk_doc=true
-Dpango:documentation=true
-Dbuild-demos=true
-Dpango:gtk_doc=true
-Dbuild-demos=false
-Dbuild-examples=false
-Dbuild-tests=false
-Dbuild-testsuite=false
@@ -461,7 +434,6 @@ reference:
- mv _build/docs/reference/gdk/gdk4-wayland/ _reference/gdk4-wayland/
- mv _build/docs/reference/gsk/gsk4/ _reference/gsk4/
- mv _build/docs/reference/gtk/gtk4/ _reference/gtk4/
- mv _build/docs/reference/gtk/*.html _reference/gtk4/
- mv _build/subprojects/pango/docs/Pango/ _reference/Pango/
- mv _build/subprojects/pango/docs/PangoCairo/ _reference/PangoCairo/
- mv _build/subprojects/pango/docs/PangoFc/ _reference/PangoFc/
@@ -483,4 +455,3 @@ publish-docs:
- "curl -X POST -F token=${PAGES_TRIGGER_TOKEN} -F ref=docs-gtk-org https://gitlab.gnome.org/api/v4/projects/665/trigger/pipeline"
rules:
- if: $CI_COMMIT_REF_NAME == "main"

View File

@@ -1,7 +1,9 @@
FROM fedora:40
FROM fedora:38
RUN dnf -y install \
adwaita-icon-theme \
atk-devel \
at-spi2-atk-devel \
avahi-gobject-devel \
cairo-devel \
cairo-gobject-devel \
@@ -16,6 +18,7 @@ RUN dnf -y install \
dejavu-sans-mono-fonts \
desktop-file-utils \
diffutils \
docbook-style-xsl \
elfutils-libelf-devel \
expat-devel \
fribidi-devel \
@@ -99,11 +102,8 @@ RUN dnf -y install \
which \
wireplumber \
xorg-x11-server-Xvfb \
&& dnf -y update \
&& dnf clean all
RUN rm /usr/share/vulkan/icd.d/powervr_mesa_icd.x86_64.json
# Enable sudo for wheel users
RUN sed -i -e 's/# %wheel/%wheel/' -e '0,/%wheel/{s/%wheel/# %wheel/}' /etc/sudoers

View File

@@ -24,10 +24,10 @@ flatpak build ${builddir} meson \
-Dbuild-examples=false \
-Dintrospection=disabled \
-Dbuild-demos=true \
-Dprofile=devel \
-Ddemo-profile=devel \
_flatpak_build
flatpak build --env=CI_COMMIT_SHORT_SHA=$CI_COMMIT_SHORT_SHA ${builddir} ninja -C _flatpak_build install
flatpak build ${builddir} ninja -C _flatpak_build install
flatpak-builder \
--user --disable-rofiles-fuse \

View File

@@ -1,91 +0,0 @@
#!/bin/bash
set -e
usage() {
cat <<-EOF
Usage: $(basename $0) [OPTION…] REPO_URL COMMIT
Check out and install a meson project
Options:
-Dkey=val Option to pass on to meson
--prefix Prefix to install to
--subdir Build subdirectory instead of whole project
--prepare Script to run before build
-h, --help Display this help
EOF
}
TEMP=$(getopt \
--name=$(basename $0) \
--options='D:h' \
--longoptions='prefix:' \
--longoptions='subdir:' \
--longoptions='prepare:' \
--longoptions='help' \
-- "$@")
eval set -- "$TEMP"
unset TEMP
MESON_OPTIONS=()
PREFIX=/usr
SUBDIR=.
PREPARE=:
while true; do
case "$1" in
-D)
MESON_OPTIONS+=( -D$2 )
shift 2
;;
--prefix)
PREFIX=$2
shift 2
;;
--subdir)
SUBDIR=$2
shift 2
;;
--prepare)
PREPARE=$2
shift 2
;;
-h|--help)
usage
exit 0
;;
--)
shift
break
;;
esac
done
if [[ $# -lt 2 ]]; then
usage
exit 1
fi
REPO_URL="$1"
COMMIT="$2"
CHECKOUT_DIR=$(mktemp --directory)
trap "rm -rf $CHECKOUT_DIR" EXIT
git clone --depth 1 "$REPO_URL" -b "$COMMIT" "$CHECKOUT_DIR"
pushd "$CHECKOUT_DIR/$SUBDIR"
sh -c "$PREPARE"
meson setup --prefix "$PREFIX" _build "${MESON_OPTIONS[@]}"
meson compile -C _build
meson install -C _build
popd

View File

@@ -324,7 +324,7 @@ for line in args.infile:
units.append(unit)
report = {}
report['date'] = datetime.datetime.now(datetime.UTC)
report['date'] = datetime.datetime.utcnow()
report['locale_date'] = report['date'].strftime("%c")
report['project_name'] = args.project_name
report['backend'] = args.backend

View File

@@ -44,7 +44,7 @@ outfile = args.output
testsuites = ET.Element('testsuites')
testsuites.set('id', '{}/{}'.format(args.job_id, args.branch))
testsuites.set('package', args.project_name)
testsuites.set('timestamp', datetime.datetime.now(datetime.UTC).isoformat(timespec='minutes'))
testsuites.set('timestamp', datetime.datetime.utcnow().isoformat(timespec='minutes'))
suites = {}
for line in args.infile:

View File

@@ -1,33 +1,28 @@
#!/bin/bash
set -x
set +x
set +e
srcdir=$( pwd )
builddir=$1
setup=$2
suite=$3
backend=$2
multiplier=${MESON_TEST_TIMEOUT_MULTIPLIER:-1}
n_processes=${MESON_TEST_MAX_PROCESSES:-1}
# Ignore memory leaks lower in dependencies
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:detect_leaks=0:allocator_may_return_null=1
export G_SLICE=always-malloc
case "${setup}" in
x11*)
dbus-run-session -- \
xvfb-run -a -s "-screen 0 1024x768x24 -noreset" \
case "${backend}" in
x11)
xvfb-run -a -s "-screen 0 1024x768x24 -noreset" \
meson test -C ${builddir} \
--quiet \
--timeout-multiplier "${multiplier}" \
--num-processes "${n_processes}" \
--print-errorlogs \
--setup=${setup} \
--suite=${suite//,/ --suite=} \
--setup=${backend} \
--suite=gtk \
--no-suite=failing \
--no-suite=${setup}_failing \
--no-suite=flaky \
--no-suite=headless \
--no-suite=gsk-compare-broadway
# Store the exit code for the CI run, but always
@@ -42,50 +37,43 @@ case "${setup}" in
compositor=$!
export WAYLAND_DISPLAY=wayland-5
dbus-run-session -- \
meson test -C ${builddir} \
meson test -C ${builddir} \
--quiet \
--timeout-multiplier "${multiplier}" \
--num-processes "${n_processes}" \
--print-errorlogs \
--setup=${setup} \
--suite=${suite//,/ --suite=} \
--setup=${backend} \
--suite=gtk \
--no-suite=failing \
--no-suite=${setup}_failing \
--no-suite=flaky \
--no-suite=headless \
--no-suite=${backend}_failing \
--no-suite=gsk-compare-broadway
exit_code=$?
kill ${compositor}
;;
broadway*)
broadway)
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
${builddir}/gdk/broadway/gtk4-broadwayd :5 &
server=$!
export BROADWAY_DISPLAY=:5
dbus-run-session -- \
meson test -C ${builddir} \
meson test -C ${builddir} \
--quiet \
--timeout-multiplier "${multiplier}" \
--num-processes "${n_processes}" \
--print-errorlogs \
--setup=${setup} \
--suite=${suite//,/ --suite=} \
--setup=${backend} \
--suite=gtk \
--no-suite=failing \
--no-suite=${setup}_failing \
--no-suite=flaky \
--no-suite=headless \
--no-suite=gsk-compare-opengl
kill ${server}
;;
*)
echo "Failed to add ${setup} to .gitlab-ci/run-tests.sh"
echo "Failed to add ${backend} to .gitlab-ci/run-tests.sh"
exit 1
;;
@@ -95,17 +83,17 @@ cd ${builddir}
$srcdir/.gitlab-ci/meson-junit-report.py \
--project-name=gtk \
--backend="${setup}" \
--backend="${backend}" \
--job-id="${CI_JOB_NAME}" \
--output="report-${setup}.xml" \
"meson-logs/testlog-${setup}.json"
--output="report-${backend}.xml" \
"meson-logs/testlog-${backend}.json"
$srcdir/.gitlab-ci/meson-html-report.py \
--project-name=gtk \
--backend="${setup}" \
--backend="${backend}" \
--job-id="${CI_JOB_NAME}" \
--reftest-output-dir="testsuite/reftests/output/${setup}" \
--output="report-${setup}.html" \
"meson-logs/testlog-${setup}.json"
--reftest-output-dir="testsuite/reftests/output/${backend}" \
--output="report-${backend}.html" \
"meson-logs/testlog-${backend}.json"
exit $exit_code

View File

@@ -3,11 +3,6 @@
set -eux -o pipefail
xcodebuild -version || :
if [ -z "$SDKROOT" ]; then
xcodebuild -showsdks || :
else
echo "SDKROOT = $SDKROOT"
fi
xcodebuild -showsdks || :
system_profiler SPSoftwareDataType || :

View File

@@ -6,7 +6,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
:: FIXME: make warnings fatal
pip3 install --upgrade --user meson~=0.64 || goto :error
meson setup -Dbackend_max_links=1 -Ddebug=false -Dmedia-gstreamer=disabled -Dvulkan=disabled _build || goto :error
meson -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error
ninja -C _build || goto :error
goto :EOF

View File

@@ -33,9 +33,7 @@ pacman --noconfirm -S --needed \
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
mingw-w64-$MSYS2_ARCH-shared-mime-info \
mingw-w64-$MSYS2_ARCH-python-gobject \
mingw-w64-$MSYS2_ARCH-shaderc \
mingw-w64-$MSYS2_ARCH-vulkan \
mingw-w64-$MSYS2_ARCH-vulkan-headers
mingw-w64-$MSYS2_ARCH-shaderc
mkdir -p _ccache
export CCACHE_BASEDIR="$(pwd)"
@@ -45,10 +43,11 @@ export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
ccache --zero-stats
ccache --show-stats
export CCACHE_DISABLE=true
meson setup \
meson \
-Dx11-backend=false \
-Dwayland-backend=false \
-Dwin32-backend=true \
-Dvulkan=disabled \
-Dintrospection=enabled \
-Dgtk:werror=true \
_build

View File

@@ -34,9 +34,7 @@
<!--
- Which version of GTK you are using
- What operating system and version
- What windowing system (X11 or Wayland)
- What graphics driver / mesa version
- For Linux, which distribution
- For Linux, which distribution
- If you built GTK yourself, the list of options used to configure the build
-->

View File

@@ -35,7 +35,8 @@ The issue tracker is meant to be used for actionable issues only.
You should not open a new issue for security related questions.
When in doubt, follow the process for [GNOME security issues](https://security.gnome.org/).
When in doubt, send an email to the [security](mailto:security@gnome.org)
mailing list.
### Bug reports
@@ -100,16 +101,14 @@ development tools appropriate for your operating system, including:
- Meson
- Ninja
- Gettext (19.7 or newer)
- a [C99 compatible compiler][glib-toolchain-reqs]
- a [C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
Up-to-date instructions about developing GNOME applications and libraries
can be found on [the GNOME Developer Center](https://developer.gnome.org).
The GTK project uses GitLab for code hosting and for tracking issues. More
information about using GitLab can be found on [the GNOME handbook][handbook].
[glib-toolchain-reqs]: https://gitlab.gnome.org/GNOME/glib/-/blob/main/docs/toolchain-requirements.md
[handbook]: https://handbook.gnome.org/infrastructure/gitlab.html
information about using GitLab can be found [on the GNOME
wiki](https://wiki.gnome.org/GitLab).
### Dependencies
@@ -133,7 +132,7 @@ GTK will attempt to download and build some of these dependencies if it
cannot find them on your system.
Additionally, you may want to look at projects that create a development
environment for you, like [jhbuild](https://gitlab.gnome.org/GNOME/jhbuild)
environment for you, like [jhbuild](https://wiki.gnome.org/HowDoI/Jhbuild)
and [gvsbuild](https://github.com/wingtk/gvsbuild).
### Getting started
@@ -146,28 +145,33 @@ $ git clone https://gitlab.gnome.org/yourusername/gtk.git
$ cd gtk
```
**Note**: if you plan to push changes to back to the main repository and
have a GNOME account, you can skip the fork, and use the following instead:
```sh
$ git clone git@gitlab.gnome.org:GNOME/gtk.git
$ cd gtk
```
To compile the Git version of GTK on your system, you will need to
configure your build using Meson:
```sh
$ meson setup _builddir .
$ meson compile -C _builddir
$ meson _builddir .
$ cd _builddir
$ ninja
```
Typically, you should work on your own branch:
```sh
$ git switch -C your-branch
$ git checkout -b your-branch
```
Once you've finished working on the bug fix or feature, push the branch
to the Git repository and open a new merge request, to let the GTK
maintainers review your contribution.
**Important**: Do **not** attach a diff or a patch file to a GitLab issue.
Patches cannot be reviewed, and do not not go through the CI pipeline. If
you wish to submit your changes to GTK, always use a merge request.
### Code reviews
Each contribution is reviewed by the core developers of the GTK project.
@@ -210,7 +214,7 @@ Closes #1234
`git commit -a --author "Joe Coder <joe@coder.org>"` and `--signoff`.
- If your commit is addressing an issue, use the
[GitLab syntax](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
[GitLab syntax](https://docs.gitlab.com/ce/user/project/issues/automatic_issue_closing.html)
to automatically close the issue when merging the commit with the upstream
repository:
@@ -240,11 +244,13 @@ people committing to GTK to follow a few rules:
code, you should always ask. If your change is minor and you've been
working on GTK for a while it probably isn't necessary to ask. But when
in doubt, ask. Even if your change is correct, somebody may know a
better way to do things.
The `gtk` [room on matrix](https://matrix.to/#/#gtk:gnome.org) is also a
good place to find GTK developers to discuss changes, but if you live
outside of the EU/US time zones, the [gtk tag on the GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
is the most certain and preferred method.
better way to do things. If you are making changes to GTK, you should
be subscribed to the [gtk-devel](https://mail.gnome.org/mailman/listinfo/gtk-devel-list)
mailing list; this is a good place to ask about intended changes.
The `#gtk` IRC channel on irc.gnome.org is also a good place to find GTK
developers to discuss changes, but if you live outside of the EU/US time
zones, an email to the gtk-devel mailing list is the most certain and
preferred method.
0. Ask _first_.
@@ -259,4 +265,4 @@ people committing to GTK to follow a few rules:
If you have been contributing to GTK for a while and you don't have commit
access to the repository, you may ask to obtain it following the [GNOME account
process](https://handbook.gnome.org/infrastructure/developer-access.html).
process](https://wiki.gnome.org/AccountsTeam/NewAccounts).

150
LOG Normal file
View File

@@ -0,0 +1,150 @@
TAP version 13
# random seed: R02S22611f6aefc1121b0ab2dc5286960449
# GLib-GIO-DEBUG: _g_io_module_get_default: Found default implementation dconf (DConfSettingsBackend) for gsettings-backend
# GLib-GIO-DEBUG: Using cross-namespace EXTERNAL authentication (this will deadlock if server is GDBus < 2.73.3)
# GLib-GIO-DEBUG: Using cross-namespace EXTERNAL authentication (this will deadlock if server is GDBus < 2.73.3)
1..1
# Start of ops tests
# testcase 0 op 0
collecting#
Cubic 0: # M 100.000000 100.000000 C 150.000000 100.000000 200.000000 100.000000 250.000000 100.000000
Cubic 1: # M 250.000000 100.000000 C 300.000000 100.000000 350.000000 100.000000 400.000000 100.000000
Line 2: # M 400 100 L 200 300
Line 3: # M 200 300 L 100 100
Cubic 4: # M 200.000000 100.000000 C 250.000000 100.000000 300.000000 100.000000 350.000000 100.000000
Cubic 5: # M 350.000000 100.000000 C 400.000000 100.000000 450.000000 100.000000 500.000000 100.000000
Line 6: # M 500 100 L 300 300
Line 7: # M 300 300 L 200 100
splitting#
1 intersections between Cubic 0 and Cubic 1#
1 intersections between Cubic 0 and Line 3#
9 intersections between Cubic 0 and Cubic 4#
# split Cubic 0.0 from Cubic 0 at 0.666666: M 100.000000 100.000000 C 133.333298 100.000000 166.666595 100.000000 199.999893 100.000000
split Cubic 0.1 from Cubic 0 at 0.666666: M 199.999893 100.000000 C 216.666595 100.000000 233.333298 100.000000 250.000000 100.000000split Cubic 0.4 from Cubic 0 at 0.00600814: M 200.300323 100.000000 C 216.866882 100.000000 233.433441 100.000000 250.000000 100.000000split Cubic 0.7 from Cubic 0 at 0.00604445: M 200.600708 100.000000 C 217.067139 100.000000 233.533569 100.000000 250.000000 100.000000# split Cubic 4.9 from Cubic 4 at 0.00533867: M 200.800812 100.000000 C 250.533875 100.000000 300.266937 100.000000 350.000000 100.000000
1 intersections between Cubic 0.1 and Line 7#
1 intersections between Cubic 1 and Line 2#
9 intersections between Cubic 1 and Cubic 4.9#
split Cubic 1.9 from Cubic 1 at 0.00534248: M 250.801361 100.000000 C 300.534241 100.000000 350.267120 100.000000 400.000000 100.000000# split Cubic 4.9.0 from Cubic 4.9 at 0.329756: M 200.800812 100.000000 C 217.200577 100.000000 233.600342 100.000000 250.000122 100.000000
# split Cubic 4.9.1 from Cubic 4.9 at 0.329756: M 250.000122 100.000000 C 283.333435 100.000000 316.666718 100.000000 350.000000 100.000000
# split Cubic 4.9.6 from Cubic 4.9 at 0.00500283: M 250.500412 100.000000 C 283.666931 100.000000 316.833466 100.000000 350.000000 100.000000
9 intersections between Cubic 1.9 and Cubic 5#
# split Cubic 1.9.0 from Cubic 1.9 at 0.664877: M 250.801361 100.000000 C 283.867615 100.000000 316.933868 100.000000 350.000122 100.000000
split Cubic 1.9.1 from Cubic 1.9 at 0.664877: M 350.000122 100.000000 C 366.666748 100.000000 383.333374 100.000000 400.000000 100.000000split Cubic 1.9.4 from Cubic 1.9 at 0.00601021: M 350.300598 100.000000 C 366.867065 100.000000 383.433533 100.000000 400.000000 100.000000split Cubic 1.9.7 from Cubic 1.9 at 0.00604655: M 350.601074 100.000000 C 367.067383 100.000000 383.533691 100.000000 400.000000 100.000000# split Cubic 5.9 from Cubic 5 at 0.00534248: M 350.801361 100.000000 C 400.534241 100.000000 450.267120 100.000000 500.000000 100.000000
1 intersections between Line 2 and Line 3#
1 intersections between Line 2 and Line 7#
# split Line 2.0 from Line 2 at 0.666667: M 400 100 L 266.667 233.333
split Line 2.1 from Line 2 at 0.666667: M 266.667 233.333 L 200 300# split Line 7.0 from Line 7 at 0.333333: M 300 300 L 266.667 233.333
# split Line 7.1 from Line 7 at 0.333333: M 266.667 233.333 L 200 100
1 intersections between Cubic 4 and Cubic 4.9.0#
1 intersections between Cubic 4 and Line 7.1#
1 intersections between Cubic 4.9.0 and Cubic 4.9.1#
1 intersections between Cubic 4.9.1 and Cubic 4.9.6#
1 intersections between Cubic 4.9.6 and Cubic 5#
1 intersections between Cubic 5 and Cubic 5.9#
1 intersections between Cubic 5.9 and Line 6#
1 intersections between Line 6 and Line 7.0#
Cubic 0.0: # M 100.000000 100.000000 C 133.333298 100.000000 166.666595 100.000000 199.999893 100.000000
Cubic 0.1: # M 199.999893 100.000000 C 200.100037 100.000000 200.200180 100.000000 200.300323 100.000000
Cubic 0.4: # M 200.300323 100.000000 C 200.400452 100.000000 200.500580 100.000000 200.600708 100.000000
Cubic 0.7: # M 200.600708 100.000000 C 217.067139 100.000000 233.533569 100.000000 250.000000 100.000000
Cubic 1: # M 250.000000 100.000000 C 250.267120 100.000000 250.534241 100.000000 250.801361 100.000000
Cubic 1.9.0: # M 250.801361 100.000000 C 283.867615 100.000000 316.933868 100.000000 350.000122 100.000000
Cubic 1.9.1: # M 350.000122 100.000000 C 350.100281 100.000000 350.200439 100.000000 350.300598 100.000000
Cubic 1.9.4: # M 350.300598 100.000000 C 350.400757 100.000000 350.500916 100.000000 350.601074 100.000000
Cubic 1.9.7: # M 350.601074 100.000000 C 367.067383 100.000000 383.533691 100.000000 400.000000 100.000000
Line 2.0: # M 400 100 L 266.667 233.333
Line 2.1: # M 266.667 233.333 L 200 300
Line 3: # M 200 300 L 100 100
Cubic 4: # M 200.000000 100.000000 C 200.266937 100.000000 200.533875 100.000000 200.800812 100.000000
Cubic 4.9.0: # M 200.800812 100.000000 C 217.200577 100.000000 233.600342 100.000000 250.000122 100.000000
Cubic 4.9.1: # M 250.000122 100.000000 C 250.166885 100.000000 250.333649 100.000000 250.500412 100.000000
Cubic 4.9.6: # M 250.500412 100.000000 C 283.666931 100.000000 316.833466 100.000000 350.000000 100.000000
Cubic 5: # M 350.000000 100.000000 C 350.267120 100.000000 350.534241 100.000000 350.801361 100.000000
Cubic 5.9: # M 350.801361 100.000000 C 400.534241 100.000000 450.267120 100.000000 500.000000 100.000000
Line 6: # M 500 100 L 300 300
Line 7.0: # M 300 300 L 266.667 233.333
Line 7.1: # M 266.667 233.333 L 200 100
classifying#
01 Cubic 0.0: # M 100.000000 100.000000 C 133.333298 100.000000 166.666595 100.000000 199.999893 100.000000
[11 Cubic 0.7: # M 200.600708 100.000000 C 217.067139 100.000000 233.533569 100.000000 250.000000 100.000000 ]
[11 Cubic 1.9.0: # M 250.801361 100.000000 C 283.867615 100.000000 316.933868 100.000000 350.000122 100.000000 ]
[11 Cubic 1.9.7: # M 350.601074 100.000000 C 367.067383 100.000000 383.533691 100.000000 400.000000 100.000000 ]
[11 Line 2.0: # M 400 100 L 266.667 233.333 ]
01 Line 2.1: # M 266.667 233.333 L 200 300
01 Line 3: # M 200 300 L 100 100
[11 Cubic 4: # M 200.000000 100.000000 C 200.266937 100.000000 200.533875 100.000000 200.800812 100.000000 ]
[11 Cubic 4.9.0: # M 200.800812 100.000000 C 217.200577 100.000000 233.600342 100.000000 250.000122 100.000000 ]
[11 Cubic 4.9.6: # M 250.500412 100.000000 C 283.666931 100.000000 316.833466 100.000000 350.000000 100.000000 ]
[11 Cubic 5: # M 350.000000 100.000000 C 350.267120 100.000000 350.534241 100.000000 350.801361 100.000000 ]
01 Cubic 5.9: # M 350.801361 100.000000 C 400.534241 100.000000 450.267120 100.000000 500.000000 100.000000
01 Line 6: # M 500 100 L 300 300
01 Line 7.0: # M 300 300 L 266.667 233.333
[11 Line 7.1: # M 266.667 233.333 L 200 100 ]
fixups#
# found 3 bad nodes
# split Cubic 0/Cubic 4 BAD 200.600723 100.000000
# [11 Line 7.1 ] 116.565
# [11 Cubic 0.7 ] 180
# [11 Cubic 4 ] 180
# [11 Cubic 4 ] 180
# [11 Cubic 4.9.0 ] 180
# >01 Cubic 0.0 360
# split Cubic 1/Cubic 4.9 BAD 250.801376 100.000000
# [11 Cubic 1.9.0 ] 180
# [11 Cubic 4.9.6 ] 180
# [11 Cubic 0.7 ] 360
# [11 Cubic 4.9.0 ] 360
# split Cubic 1.9/Cubic 5 BAD 350.601105 100.000000
# [11 Cubic 1.9.7 ] 180
# [11 Cubic 5 ] 180
# [11 Cubic 5 ] 180
# <01 Cubic 5.9 180
# [11 Cubic 1.9.0 ] 360
# [11 Cubic 4.9.6 ] 360
reassembling#
start new contour Cubic 0.0#
# Cubic 0.0 ends at:
# start 0 100.000000 100.000000
# >01 Line 3 116.565
# (10 Cubic 0.0 ) 180
picking cw#
append Line 3#
# Line 3 ends at:
# end 2 200.000000 300.000000
# >01 Line 2.1 225
# (10 Line 3 ) 296.565
picking cw#
append Line 2.1#
# Line 2.1 ends at:
# split Line 2/Line 7 266.666656 233.333344
# (10 Line 2.1 ) 45
# >01 Line 7.0 116.565
# [11 Line 2.0 ] 225
# [11 Line 7.1 ] 296.565
picking cw#
append Line 7.0#
# Line 7.0 ends at:
# end 6 300.000000 300.000000
# >01 Line 6 225
# (10 Line 7.0 ) 296.565
picking cw#
append Line 6#
# Line 6 ends at:
# end 5 500.000000 100.000000
# (10 Line 6 ) 45
# >01 Cubic 5.9 360
picking cw#
append Cubic 5.9#
# Cubic 5.9 ends at:
# split Cubic 1.9/Cubic 5 BAD 350.601105 100.000000
# [11 Cubic 1.9.7 ] 180
# [11 Cubic 5 ] 180
# [11 Cubic 5 ] 180
# (10 Cubic 5.9 ) 180
# [11 Cubic 1.9.0 ] 360
# [11 Cubic 4.9.6 ] 360
picking cw#
**
ERROR:../testsuite/gsk/path-ops.c:359:test_ops_simple: assertion failed (s == tests[i].out): ("M 354.60110473632812 100 A 4 4 0 0 0 346.60110473632812 100 A 4 4 0 0 0 354.60110473632812 100 z M 252.80137634277344 100 A 2 2 0 0 0 248.80137634277344 100 A 2 2 0 0 0 252.80137634277344 100 z M 204.60072326660156 100 A 4 4 0 0 0 196.60072326660156 100 A 4 4 0 0 0 204.60072326660156 100 z" == "M 100 100 z")
not ok /ops/simple - ERROR:../testsuite/gsk/path-ops.c:359:test_ops_simple: assertion failed (s == tests[i].out): ("M 354.60110473632812 100 A 4 4 0 0 0 346.60110473632812 100 A 4 4 0 0 0 354.60110473632812 100 z M 252.80137634277344 100 A 2 2 0 0 0 248.80137634277344 100 A 2 2 0 0 0 252.80137634277344 100 z M 204.60072326660156 100 A 4 4 0 0 0 196.60072326660156 100 A 4 4 0 0 0 204.60072326660156 100 z" == "M 100 100 z")
Bail out!

1305
NEWS

File diff suppressed because it is too large Load Diff

View File

@@ -39,21 +39,18 @@ Nightly documentation can be found at
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk4/
Nightly flatpaks of our demos can be installed from the
[GNOME Nightly](https://nightly.gnome.org/) repository:
```sh
flatpak remote-add --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo
flatpak install gnome-nightly org.gtk.Demo4
flatpak install gnome-nightly org.gtk.WidgetFactory4
flatpak install gnome-nightly org.gtk.IconBrowser4
```
[GNOME Nightly](https://wiki.gnome.org/Apps/Nightly) repository:
- `flatpak remote-add --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo`
- `flatpak install gnome-nightly org.gtk.Demo4`
- `flatpak install gnome-nightly org.gtk.WidgetFactory4`
- `flatpak install gnome-nightly org.gtk.IconBrowser4`
Building and installing
-----------------------
In order to build GTK you will need:
- [a C11 compatible compiler](https://gitlab.gnome.org/GNOME/glib/-/blob/main/docs/toolchain-requirements.md)
- [a C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
- [Python 3](https://www.python.org/)
- [Meson](http://mesonbuild.com)
- [Ninja](https://ninja-build.org)
@@ -128,7 +125,7 @@ version, for example `gtk-4-10`.
How to report bugs
------------------
Bugs should be reported on the [issues page](https://gitlab.gnome.org/GNOME/gtk/issues/).
Bugs should be reported on the [issues page](https://gitlab.gnome.org/GNOME/gtk/issues/new).
In the bug report please include:
@@ -136,13 +133,9 @@ In the bug report please include:
- which version of GTK you are using
- what operating system and version
- what windowing system (X11 or Wayland)
- what graphics driver / mesa version
- for Linux, which distribution
- if you built GTK, the list of options used to configure the build
Most of this information can be found in the GTK inspector.
And anything else you think is relevant.
* How to reproduce the bug.

View File

@@ -185,8 +185,9 @@
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Dvulkan=disabled",
"-Dbuildtype=debugoptimized",
"-Dprofile=devel"
"-Ddemo-profile=devel"
],
"sources" : [
{

View File

@@ -114,8 +114,9 @@
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Dvulkan=disabled",
"-Dbuildtype=debugoptimized",
"-Dprofile=devel"
"-Ddemo-profile=devel"
],
"sources" : [
{

View File

@@ -114,8 +114,9 @@
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Dvulkan=disabled",
"-Dbuildtype=debugoptimized",
"-Dprofile=devel"
"-Ddemo-profile=devel"
],
"sources" : [
{
@@ -130,6 +131,7 @@
"env" : {
"DBUS_SESSION_BUS_ADDRESS" : "''",
"GSK_RENDERER" : "opengl",
"GDK_DEBUG" : "vulkan-disable",
"G_ENABLE_DEBUG" : "true"
}
}

View File

@@ -114,8 +114,9 @@
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Dvulkan=disabled",
"-Dbuildtype=debugoptimized",
"-Dprofile=devel"
"-Ddemo-profile=devel"
],
"sources" : [
{
@@ -130,6 +131,7 @@
"env" : {
"DBUS_SESSION_BUS_ADDRESS" : "''",
"GSK_RENDERER" : "opengl",
"GDK_DEBUG" : "vulkan-disable",
"G_ENABLE_DEBUG" : "true"
}
}

View File

@@ -1,41 +0,0 @@
#ifndef _MSC_VER
#pragma error "This header is for Microsoft VC or clang-cl only."
#endif /* _MSC_VER */
/* Make MSVC more pedantic, this is a recommended pragma list
* from _Win32_Programming_ by Rector and Newcomer.
*/
#ifndef __clang__
#pragma warning(error:4002) /* too many actual parameters for macro */
#pragma warning(error:4003) /* not enough actual parameters for macro */
#pragma warning(1:4010) /* single-line comment contains line-continuation character */
#pragma warning(error:4013) /* 'function' undefined; assuming extern returning int */
#pragma warning(1:4016) /* no function return type; using int as default */
#pragma warning(error:4020) /* too many actual parameters */
#pragma warning(error:4021) /* too few actual parameters */
#pragma warning(error:4027) /* function declared without formal parameter list */
#pragma warning(error:4029) /* declared formal parameter list different from definition */
#pragma warning(error:4033) /* 'function' must return a value */
#pragma warning(error:4035) /* 'function' : no return value */
#pragma warning(error:4045) /* array bounds overflow */
#pragma warning(error:4047) /* different levels of indirection */
#pragma warning(error:4049) /* terminating line number emission */
#pragma warning(error:4053) /* An expression of type void was used as an operand */
#pragma warning(error:4071) /* no function prototype given */
#pragma warning(disable:4101) /* unreferenced local variable */
#pragma warning(error:4150)
/* G_NORETURN */
#pragma warning(error:4646) /* function declared with __declspec(noreturn) has non-void return type */
#pragma warning(error:4715) /* 'function': not all control paths return a value */
#pragma warning(error:4098) /* 'void' function returning a value */
#pragma warning(disable:4244) /* No possible loss of data warnings */
#pragma warning(disable:4305) /* No truncation from int to char warnings */
#pragma warning(error:4819) /* The file contains a character that cannot be represented in the current code page */
#endif /* __clang__ */
/* work around Microsoft's premature attempt to deprecate the C-Library */
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NONSTDC_NO_WARNINGS

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -35,7 +35,7 @@ show_action_dialog (GSimpleAction *action)
{
GtkAlertDialog *dialog;
dialog = gtk_alert_dialog_new ("You activated action: \"%s\"",
dialog = gtk_alert_dialog_new ("You activated action: \"%s\n",
g_action_get_name (G_ACTION (action)));
gtk_alert_dialog_show (dialog, NULL);
g_object_unref (dialog);
@@ -223,7 +223,7 @@ delete_messages (gpointer data)
static void
pop_message (GtkWidget *status)
{
GList *messages = (GList *) g_object_steal_data (G_OBJECT (status), "messages");
GList *messages = (GList *) g_object_get_data (G_OBJECT (status), "messages");
if (messages)
{
@@ -241,7 +241,7 @@ static void
push_message (GtkWidget *status,
const char *message)
{
GList *messages = (GList *) g_object_steal_data (G_OBJECT (status), "messages");
GList *messages = (GList *) g_object_get_data (G_OBJECT (status), "messages");
gtk_label_set_label (GTK_LABEL (status), message);
messages = g_list_prepend (messages, g_strdup (message));

View File

@@ -0,0 +1,26 @@
uniform float u_time;
void
mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
vec2 pos = (fragCoord.xy * 2.0 - resolution.xy)/ min (resolution.x, resolution.y) ;
float t0 = sin ((u_time + 0.00)*1.0);
float t1 = sin ((u_time + 0.30)*0.4);
float t2 = cos ((u_time + 0.23)*0.9);
float t3 = cos ((u_time + 0.41)*0.6);
float t4 = cos ((u_time + 0.11)*0.3);
vec2 p0 = vec2 (t1, t0) ;
vec2 p1 = vec2 (t2, t3) ;
vec2 p2 = vec2 (t4, t3) ;
float r = 1.0/distance (pos, p0);
float g = 1.0/distance (pos, p1);
float b = 1.0/distance (pos, p2);
float sum = r + g + b;
float alpha = 1.0 - pow (1.0/(sum), 40.0)*pow (10.0, 40.0*0.7);
fragColor = vec4 (r*0.5, g*0.5, b*0.5, 1.0) * alpha;
}

View File

@@ -18,7 +18,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __BLUR_OVERLAY_H__
#define __BLUR_OVERLAY_H__
#include <gtk/gtk.h>
@@ -59,3 +60,5 @@ void blur_overlay_set_child (BlurOverlay *overlay,
GtkWidget *widget);
G_END_DECLS
#endif /* __BLUR_OVERLAY_H__ */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

226
demos/gtk-demo/cogs2.glsl Normal file
View File

@@ -0,0 +1,226 @@
uniform float iTime;
// Originally from: https://www.shadertoy.com/view/3ljyDD
// License CC0: Hexagonal tiling + cog wheels
// Nothing fancy, just hexagonal tiling + cog wheels
#define PI 3.141592654
#define TAU (2.0*PI)
#define MROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
float hash(in vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,58.233))) * 13758.5453);
}
float pcos(float a) {
return 0.5 + 0.5*cos(a);
}
void rot(inout vec2 p, float a) {
float c = cos(a);
float s = sin(a);
p = vec2(c*p.x + s*p.y, -s*p.x + c*p.y);
}
float modPolar(inout vec2 p, float repetitions) {
float angle = 2.0*PI/repetitions;
float a = atan(p.y, p.x) + angle/2.;
float r = length(p);
float c = floor(a/angle);
a = mod(a,angle) - angle/2.;
p = vec2(cos(a), sin(a))*r;
// For an odd number of repetitions, fix cell index of the cell in -x direction
// (cell index would be e.g. -5 and 5 in the two halves of the cell):
if (abs(c) >= (repetitions/2.0)) c = abs(c);
return c;
}
float pmin(float a, float b, float k) {
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
return mix( b, a, h ) - k*h*(1.0-h);
}
const vec2 sz = vec2(1.0, sqrt(3.0));
const vec2 hsz = 0.5*sz;
const float smallCount = 16.0;
vec2 hextile(inout vec2 p) {
// See Art of Code: Hexagonal Tiling Explained!
// https://www.youtube.com/watch?v=VmrIDyYiJBA
vec2 p1 = mod(p, sz)-hsz;
vec2 p2 = mod(p - hsz*1.0, sz)-hsz;
vec2 p3 = mix(p2, p1, vec2(length(p1) < length(p2)));
vec2 n = p3 - p;
p = p3;
return n;
}
float circle(vec2 p, float r) {
return length(p) - r;
}
float box(vec2 p, vec2 b) {
vec2 d = abs(p)-b;
return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
}
float unevenCapsule(vec2 p, float r1, float r2, float h) {
p.x = abs(p.x);
float b = (r1-r2)/h;
float a = sqrt(1.0-b*b);
float k = dot(p,vec2(-b,a));
if( k < 0.0 ) return length(p) - r1;
if( k > a*h ) return length(p-vec2(0.0,h)) - r2;
return dot(p, vec2(a,b) ) - r1;
}
float cogwheel(vec2 p, float innerRadius, float outerRadius, float cogs, float holes) {
float cogWidth = 0.25*innerRadius*TAU/cogs;
float d0 = circle(p, innerRadius);
vec2 icp = p;
modPolar(icp, holes);
icp -= vec2(innerRadius*0.55, 0.0);
float d1 = circle(icp, innerRadius*0.25);
vec2 cp = p;
modPolar(cp, cogs);
cp -= vec2(innerRadius, 0.0);
float d2 = unevenCapsule(cp.yx, cogWidth, cogWidth*0.75, (outerRadius-innerRadius));
float d3 = circle(p, innerRadius*0.20);
float d = 1E6;
d = min(d, d0);
d = pmin(d, d2, 0.5*cogWidth);
d = min(d, d2);
d = max(d, -d1);
d = max(d, -d3);
return d;
}
float ccell1(vec2 p, float r) {
float d = 1E6;
const float bigCount = 60.0;
vec2 cp0 = p;
rot(cp0, -iTime*TAU/bigCount);
float d0 = cogwheel(cp0, 0.36, 0.38, bigCount, 5.0);
vec2 cp1 = p;
float nm = modPolar(cp1, 6.0);
cp1 -= vec2(0.5, 0.0);
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
d = min(d, d0);
d = min(d, d1);
return d;
}
float ccell2(vec2 p, float r) {
float d = 1E6;
vec2 cp0 = p;
float nm = modPolar(cp0, 6.0);
vec2 cp1 = cp0;
const float off = 0.275;
const float count = smallCount + 2.0;
cp0 -= vec2(off, 0.0);
rot(cp0, 0.+TAU*nm/2.0 - iTime*TAU/count);
float d0 = cogwheel(cp0, 0.09, 0.105, count, 5.0);
cp1 -= vec2(0.5, 0.0);
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
float l = length(p);
float d2 = l - (off+0.055);
float d3 = d2 + 0.020;;
vec2 tp0 = p;
modPolar(tp0, 60.0);
tp0.x -= off;
float d4 = box(tp0, vec2(0.0125, 0.005));
float ctime = -(iTime*0.05 + r)*TAU;
vec2 tp1 = p;
rot(tp1, ctime*12.0);
tp1.x -= 0.13;
float d5 = box(tp1, vec2(0.125, 0.005));
vec2 tp2 = p;
rot(tp2, ctime);
tp2.x -= 0.13*0.5;
float d6 = box(tp2, vec2(0.125*0.5, 0.0075));
float d7 = l - 0.025;
float d8 = l - 0.0125;
d = min(d, d0);
d = min(d, d1);
d = min(d, d2);
d = max(d, -d3);
d = min(d, d4);
d = min(d, d5);
d = min(d, d6);
d = min(d, d7);
d = max(d, -d8);
return d;
}
float df(vec2 p, float scale, inout vec2 nn) {
p /= scale;
nn = hextile(p);
nn = floor(nn + 0.5);
float r = hash(nn);
float d;;
if (r < 0.5) {
d = ccell1(p, r);
} else {
d = ccell2(p, r);
}
return d*scale;
}
vec3 postProcess(vec3 col, vec2 q) {
//col = saturate(col);
col=pow(clamp(col,0.0,1.0),vec3(0.75));
col=col*0.6+0.4*col*col*(3.0-2.0*col); // contrast
col=mix(col, vec3(dot(col, vec3(0.33))), -0.4); // satuation
col*=0.5+0.5*pow(19.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7); // vigneting
return col;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv) {
vec2 q = fragCoord/resolution.xy;
vec2 p = -1.0 + 2.0*q;
p.x *= resolution.x/resolution.y;
float tm = iTime*0.1;
p += vec2(cos(tm), sin(tm*sqrt(0.5)));
float z = mix(0.5, 1.0, pcos(tm*sqrt(0.3)));
float aa = 4.0 / resolution.y;
vec2 nn = vec2(0.0);
float d = df(p, z, nn);
vec3 col = vec3(160.0)/vec3(255.0);
vec3 baseCol = vec3(0.3);
vec4 logoCol = vec4(baseCol, 1.0)*smoothstep(-aa, 0.0, -d);
col = mix(col, logoCol.xyz, pow(logoCol.w, 8.0));
col += 0.4*pow(abs(sin(20.0*d)), 0.6);
col = postProcess(col, q);
fragColor = vec4(col, 1.0);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1019 B

After

Width:  |  Height:  |  Size: 985 B

View File

@@ -0,0 +1,27 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/crosswarp
// Author: Eke Péter <peterekepeter@gmail.com>
// License: MIT
vec4 transition(vec2 p) {
float x = progress;
x=smoothstep(.0,1.0,(x*2.0+p.x-1.0));
return mix(getFromColor((p-.5)*(1.-x)+.5), getToColor((p-.5)*x+.5), x);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}

View File

@@ -15,54 +15,12 @@ on_destroy (gpointer data)
window = NULL;
}
static GdkTexture *
cursor_callback (GdkCursor *cursor,
int cursor_size,
double scale,
int *width,
int *height,
int *hotspot_x,
int *hotspot_y,
gpointer data)
{
GdkPixbuf *pixbuf;
GdkTexture *texture;
GError *error = NULL;
int scaled_size;
scaled_size = ceil (cursor_size * scale);
pixbuf = gdk_pixbuf_new_from_resource_at_scale ("/cursors/images/gtk-logo.svg",
scaled_size, scaled_size,
TRUE,
&error);
if (!pixbuf)
{
g_print ("%s\n", error->message);
g_error_free (error);
return NULL;
}
texture = gdk_texture_new_for_pixbuf (pixbuf);
g_object_unref (pixbuf);
*width = cursor_size;
*height = cursor_size;
*hotspot_x = 18 * cursor_size / 32.0;
*hotspot_y = 2 * cursor_size / 32.0;
return texture;
}
GtkWidget *
do_cursors (GtkWidget *do_widget)
{
if (!window)
{
GtkBuilder *builder;
GtkWidget *logo_callback;
GdkCursor *cursor;
builder = gtk_builder_new_from_resource ("/cursors/cursors.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
@@ -71,10 +29,6 @@ do_cursors (GtkWidget *do_widget)
gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy",
G_CALLBACK (on_destroy), NULL);
logo_callback = GTK_WIDGET (gtk_builder_get_object (builder, "logo_callback"));
cursor = gdk_cursor_new_from_callback (cursor_callback, NULL, NULL, NULL);
gtk_widget_set_cursor (logo_callback, cursor);
g_object_unref (cursor);
g_object_unref (builder);
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -116,7 +116,6 @@
<file>w_resize_cursor.png</file>
<file>zoom_in_cursor.png</file>
<file>zoom_out_cursor.png</file>
<file>gtk-logo.svg</file>
</gresource>
<gresource prefix="/dnd">
<file>dnd.css</file>
@@ -128,7 +127,6 @@
<file>fishbowl.ui</file>
<file>gtkfishbowl.c</file>
<file>gtkfishbowl.h</file>
<file>tiger.node</file>
</gresource>
<gresource prefix="/frames">
<file>frames.ui</file>
@@ -146,6 +144,21 @@
<file>cogs.glsl</file>
<file>glowingstars.glsl</file>
</gresource>
<gresource prefix="/gltransition">
<file>gtkshaderstack.c</file>
<file>gtkshaderstack.h</file>
<file>gtkshaderbin.h</file>
<file>gtkshaderbin.c</file>
<file>gskshaderpaintable.h</file>
<file>gskshaderpaintable.c</file>
<file>wind.glsl</file>
<file>radial.glsl</file>
<file>crosswarp.glsl</file>
<file>kaleidoscope.glsl</file>
<file>cogs2.glsl</file>
<file>ripple.glsl</file>
<file>background.glsl</file>
</gresource>
<gresource prefix="/iconscroll">
<file>iconscroll.ui</file>
</gresource>
@@ -281,6 +294,7 @@
<file>gears.c</file>
<file>gestures.c</file>
<file>glarea.c</file>
<file>gltransition.c</file>
<file>headerbar.c</file>
<file>hypertext.c</file>
<file>iconscroll.c</file>
@@ -322,9 +336,6 @@
<file>panes.c</file>
<file>password_entry.c</file>
<file>path_fill.c</file>
<file>path_maze.c</file>
<file>path_spinner.c</file>
<file>path_walk.c</file>
<file>path_text.c</file>
<file>peg_solitaire.c</file>
<file>pickers.c</file>
@@ -411,10 +422,6 @@
<gresource prefix="/fontrendering">
<file>fontrendering.ui</file>
</gresource>
<gresource prefix="/path_walk">
<file>path_walk.ui</file>
<file compressed="true">path_world.txt</file>
</gresource>
<gresource prefix="/path_text">
<file>path_text.ui</file>
</gresource>
@@ -438,10 +445,6 @@
<file>icons/16x16/categories/applications-other.png</file>
<file>icons/48x48/status/starred.png</file>
<file alias="icons/scalable/apps/org.gtk.Demo4.svg">data/scalable/apps/org.gtk.Demo4.svg</file>
<file>portland-rose-thumbnail.png</file>
<file>large-image-thumbnail.png</file>
<file compressed="true">large-image.png</file>
<file compressed="true">Moby-Dick.txt</file>
</gresource>
<gresource prefix="/org/gtk/Demo4/gtk">
<file preprocess="xml-stripblanks">help-overlay.ui</file>

View File

@@ -75,9 +75,7 @@ query_tooltip (GtkWidget *widget,
gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
precision = 1;
s = NULL;
do {
g_free (s);
s = g_strdup_printf ("%.*f", precision, self->scale);
l = strlen (s) - 1;
while (s[l] == '0')

View File

@@ -18,7 +18,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __DEMO_TAGGED_ENTRY_H__
#define __DEMO_TAGGED_ENTRY_H__
#include <gtk/gtk.h>
@@ -56,3 +57,5 @@ void demo_tagged_entry_tag_set_has_close_button (DemoTaggedEntryTag *
gboolean has_close_button);
G_END_DECLS
#endif /* __DEMO_TAGGED_ENTRY_H__ */

View File

@@ -34,7 +34,7 @@ transition (GtkWidget *widget,
{
DemoWidget *self = DEMO_WIDGET (widget);
DemoLayout *demo_layout = DEMO_LAYOUT (gtk_widget_get_layout_manager (widget));
gint64 now = gdk_frame_clock_get_frame_time (frame_clock);
gint64 now = g_get_monotonic_time ();
gtk_widget_queue_allocate (widget);
@@ -66,13 +66,11 @@ clicked (GtkGestureClick *gesture,
gpointer data)
{
DemoWidget *self = data;
GdkFrameClock *frame_clock;
if (self->tick_id != 0)
return;
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
self->start_time = gdk_frame_clock_get_frame_time (frame_clock);
self->start_time = g_get_monotonic_time ();
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self), transition, NULL, NULL);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -55,7 +55,7 @@ mode_switch_state_set (GtkSwitch *sw,
{
gtk_widget_set_visible (label, TRUE);
gtk_accessible_update_relation (GTK_ACCESSIBLE (sw),
GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE, label, NULL,
GTK_ACCESSIBLE_RELATION_ERROR_MESSAGE, label,
-1);
gtk_accessible_update_state (GTK_ACCESSIBLE (sw),
GTK_ACCESSIBLE_STATE_INVALID, GTK_ACCESSIBLE_INVALID_TRUE,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -9,9 +9,7 @@
#include "gtkfishbowl.h"
#include "gtkgears.h"
#include "nodewidget.h"
#include "graphwidget.h"
#include "gskshaderpaintable.h"
const char *const css =
".blurred-button {"
@@ -73,7 +71,14 @@ create_blurred_button (void)
static GtkWidget *
create_font_button (void)
{
return gtk_font_dialog_button_new (gtk_font_dialog_new ());
GtkFontDialog *dialog;
GtkWidget *button;
dialog = gtk_font_dialog_new ();
button = gtk_font_dialog_button_new (dialog);
g_object_unref (dialog);
return button;
}
static GtkWidget *
@@ -151,6 +156,38 @@ create_switch (void)
return w;
}
static gboolean
update_paintable (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GskShaderPaintable *paintable;
gint64 frame_time;
paintable = GSK_SHADER_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget)));
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
gsk_shader_paintable_update_time (paintable, 0, frame_time);
return G_SOURCE_CONTINUE;
}
static GtkWidget *
create_cogs (void)
{
GtkWidget *picture;
static GskGLShader *cog_shader = NULL;
GdkPaintable *paintable;
if (cog_shader == NULL)
cog_shader = gsk_gl_shader_new_from_resource ("/gltransition/cogs2.glsl");
paintable = gsk_shader_paintable_new (g_object_ref (cog_shader), NULL);
picture = gtk_picture_new_for_paintable (paintable);
gtk_widget_set_size_request (picture, 150, 75);
gtk_widget_add_tick_callback (picture, update_paintable, NULL, NULL);
return picture;
}
static void
mapped (GtkWidget *w)
{
@@ -171,54 +208,36 @@ create_menu_button (void)
return w;
}
static GtkWidget *
create_tiger (void)
{
return node_widget_new ("/fishbowl/tiger.node");
}
static GtkWidget *
create_graph (void)
{
return graph_widget_new ();
}
static const struct {
const char *name;
GtkWidget * (* create_func) (void);
gboolean (* check) (GtkFishbowl *fb);
GtkWidget * (*create_func) (void);
} widget_types[] = {
{ "Icon", create_icon, NULL },
{ "Button", create_button, NULL },
{ "Blurbutton", create_blurred_button, NULL },
{ "Fontbutton", create_font_button, NULL },
{ "Levelbar", create_level_bar, NULL },
{ "Label", create_label, NULL },
{ "Spinner", create_spinner, NULL },
{ "Spinbutton", create_spinbutton, NULL },
{ "Video", create_video, NULL },
{ "Gears", create_gears, NULL },
{ "Switch", create_switch, NULL },
{ "Menubutton", create_menu_button, NULL },
{ "Tiger", create_tiger, NULL },
{ "Graph", create_graph, NULL },
{ "Icon", create_icon },
{ "Button", create_button },
{ "Blurbutton", create_blurred_button },
{ "Fontbutton", create_font_button },
{ "Levelbar", create_level_bar },
{ "Label", create_label },
{ "Spinner", create_spinner },
{ "Spinbutton", create_spinbutton },
{ "Video", create_video },
{ "Gears", create_gears },
{ "Switch", create_switch },
{ "Menubutton", create_menu_button },
{ "Shader", create_cogs },
};
static int selected_widget_type = -1;
static const int N_WIDGET_TYPES = G_N_ELEMENTS (widget_types);
static gboolean
static void
set_widget_type (GtkFishbowl *fishbowl,
int widget_type_index)
{
GtkWidget *window;
if (widget_type_index == selected_widget_type)
return TRUE;
if (widget_types[widget_type_index].check != NULL &&
!widget_types[widget_type_index].check (fishbowl))
return FALSE;
return;
selected_widget_type = widget_type_index;
@@ -228,8 +247,6 @@ set_widget_type (GtkFishbowl *fishbowl,
window = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (fishbowl)));
gtk_window_set_title (GTK_WINDOW (window),
widget_types[selected_widget_type].name);
return TRUE;
}
G_MODULE_EXPORT void
@@ -237,17 +254,14 @@ fishbowl_next_button_clicked_cb (GtkButton *source,
gpointer user_data)
{
GtkFishbowl *fishbowl = user_data;
int new_index = selected_widget_type;
int new_index;
do
{
if (new_index + 1 >= N_WIDGET_TYPES)
new_index = 0;
else
new_index = new_index + 1;
if (selected_widget_type + 1 >= N_WIDGET_TYPES)
new_index = 0;
else
new_index = selected_widget_type + 1;
}
while (!set_widget_type (fishbowl, new_index));
set_widget_type (fishbowl, new_index);
}
G_MODULE_EXPORT void
@@ -255,18 +269,14 @@ fishbowl_prev_button_clicked_cb (GtkButton *source,
gpointer user_data)
{
GtkFishbowl *fishbowl = user_data;
int new_index = selected_widget_type;
int new_index;
do
{
if (new_index - 1 < 0)
new_index = N_WIDGET_TYPES - 1;
else
new_index = new_index - 1;
if (selected_widget_type - 1 < 0)
new_index = N_WIDGET_TYPES - 1;
else
new_index = selected_widget_type - 1;
}
while (!set_widget_type (fishbowl, new_index));
set_widget_type (fishbowl, new_index);
}
G_MODULE_EXPORT void

View File

@@ -600,8 +600,8 @@ update_display (void)
if (s->len > 0)
{
pango_font_description_set_variations (desc, s->str);
g_string_free (s, TRUE);
}
g_string_free (s, TRUE);
font_desc = pango_font_description_to_string (desc);
@@ -1586,7 +1586,7 @@ update_font_variations (void)
}
gtk_grid_attach (GTK_GRID (demo->variations_grid), combo, 1, -1, 3, 1);
g_signal_connect (combo, "notify::selected", G_CALLBACK (instance_changed), NULL);
g_signal_connect (combo, "notify::selecte", G_CALLBACK (instance_changed), NULL);
demo->instance_combo = combo;
}

View File

@@ -363,9 +363,7 @@ insert_markup_idle (gpointer data)
if (g_get_monotonic_time () - begin > G_TIME_SPAN_MILLISECOND)
{
guint id;
id = g_idle_add (insert_markup_idle, data);
g_source_set_name_by_id (id, "[gtk-demo] insert_markup_idle");
g_idle_add (insert_markup_idle, data);
return G_SOURCE_REMOVE;
}
@@ -400,9 +398,7 @@ parse_markup_idle (gpointer data)
do {
if (g_get_monotonic_time () - begin > G_TIME_SPAN_MILLISECOND)
{
guint id;
id = g_idle_add (parse_markup_idle, data);
g_source_set_name_by_id (id, "[gtk-demo] parse_markup_idle");
g_idle_add (parse_markup_idle, data);
return G_SOURCE_REMOVE;
}

View File

@@ -276,7 +276,7 @@ gtk_font_plane_class_init (GtkFontPlaneClass *class)
GtkWidget *
gtk_font_plane_new (GtkAdjustment *weight_adj,
GtkAdjustment *width_adj)
GtkAdjustment *width_adj)
{
return g_object_new (GTK_TYPE_FONT_PLANE,
"weight-adjustment", weight_adj,

View File

@@ -15,7 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GTK_FONT_PLANE_H__
#define __GTK_FONT_PLANE_H__
#include <gtk/gtk.h>
@@ -55,7 +56,9 @@ struct _GtkFontPlaneClass
GType gtk_font_plane_get_type (void) G_GNUC_CONST;
GtkWidget * gtk_font_plane_new (GtkAdjustment *weight_adj,
GtkAdjustment *width_adj);
GtkWidget * gtk_font_plane_new (GtkAdjustment *width_adj,
GtkAdjustment *weight_adj);
G_END_DECLS
#endif /* __GTK_FONT_PLANE_H__ */

View File

@@ -0,0 +1,362 @@
/* OpenGL/Transitions and Effects
* #Keywords: OpenGL, shader, effect
*
* Create transitions between pages using a custom fragment shader.
*
* The example transitions here are taken from gl-transitions.com, and you
* can edit the shader code itself on the last page of the stack.
*
* The transitions work with arbitrary content. We use images, shaders
* GL areas and plain old widgets to demonstrate this.
*
* The demo also shows some over-the-top effects like wobbly widgets,
* and animated backgrounds.
*/
#include <math.h>
#include <gtk/gtk.h>
#include "gtkshaderstack.h"
#include "gtkshaderbin.h"
#include "gtkshadertoy.h"
#include "gskshaderpaintable.h"
static GtkWidget *demo_window = NULL;
static void
close_window (GtkWidget *widget)
{
/* Reset the state */
demo_window = NULL;
}
static void
text_changed (GtkTextBuffer *buffer,
GtkWidget *button)
{
gtk_widget_set_visible (button, TRUE);
}
static void
apply_text (GtkWidget *button,
GtkTextBuffer *buffer)
{
GtkWidget *stack;
GskGLShader *shader;
GtkTextIter start, end;
char *text;
stack = g_object_get_data (G_OBJECT (button), "the-stack");
gtk_text_buffer_get_bounds (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
GBytes *bytes = g_bytes_new_take (text, strlen (text));
shader = gsk_gl_shader_new_from_bytes (bytes);
gtk_shader_stack_set_shader (GTK_SHADER_STACK (stack), shader);
g_object_unref (shader);
g_bytes_unref (bytes);
gtk_widget_set_visible (button, FALSE);
}
static void
go_back (GtkWidget *button,
GtkWidget *stack)
{
gtk_shader_stack_transition (GTK_SHADER_STACK (stack), FALSE);
}
static void
go_forward (GtkWidget *button,
GtkWidget *stack)
{
gtk_shader_stack_transition (GTK_SHADER_STACK (stack), TRUE);
}
static void
clicked_cb (GtkGestureClick *gesture,
guint n_pressed,
double x,
double y,
gpointer data)
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
}
static GtkWidget *
ripple_bin_new (void)
{
GtkWidget *bin = gtk_shader_bin_new ();
static GskGLShader *shader = NULL;
if (shader == NULL)
shader = gsk_gl_shader_new_from_resource ("/gltransition/ripple.glsl");
gtk_shader_bin_add_shader (GTK_SHADER_BIN (bin), shader, GTK_STATE_FLAG_PRELIGHT, GTK_STATE_FLAG_PRELIGHT, 20);
return bin;
}
static GtkWidget *
new_shadertoy (const char *path)
{
GBytes *shader;
GtkWidget *toy;
toy = gtk_shadertoy_new ();
shader = g_resources_lookup_data (path, 0, NULL);
gtk_shadertoy_set_image_shader (GTK_SHADERTOY (toy),
g_bytes_get_data (shader, NULL));
g_bytes_unref (shader);
return toy;
}
static gboolean
update_paintable (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GskShaderPaintable *paintable;
gint64 frame_time;
paintable = GSK_SHADER_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget)));
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
gsk_shader_paintable_update_time (paintable, 0, frame_time);
return G_SOURCE_CONTINUE;
}
static GtkWidget *
make_shader_stack (const char *name,
const char *resource_path,
int active_child,
GtkWidget *scale)
{
GtkWidget *stack, *child, *widget, *vbox, *hbox, *bin;
GtkWidget *label, *button, *tv;
GskGLShader *shader;
GObjectClass *class;
GParamSpecFloat *pspec;
GtkAdjustment *adjustment;
GtkTextBuffer *buffer;
GBytes *bytes;
GtkEventController *controller;
GdkPaintable *paintable;
stack = gtk_shader_stack_new ();
shader = gsk_gl_shader_new_from_resource (resource_path);
gtk_shader_stack_set_shader (GTK_SHADER_STACK (stack), shader);
g_object_unref (shader);
child = gtk_picture_new_for_resource ("/css_blendmodes/ducky.png");
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
shader = gsk_gl_shader_new_from_resource ("/gltransition/cogs2.glsl");
paintable = gsk_shader_paintable_new (shader, NULL);
child = gtk_picture_new_for_paintable (paintable);
gtk_widget_add_tick_callback (child, update_paintable, NULL, NULL);
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
child = gtk_picture_new_for_resource ("/transparent/portland-rose.jpg");
gtk_picture_set_can_shrink (GTK_PICTURE (child), TRUE);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
child = new_shadertoy ("/shadertoy/neon.glsl");
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
child = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
class = g_type_class_ref (GTK_TYPE_SHADER_STACK);
pspec = G_PARAM_SPEC_FLOAT (g_object_class_find_property (class, "duration"));
adjustment = gtk_range_get_adjustment (GTK_RANGE (scale));
if (gtk_adjustment_get_lower (adjustment) == 0.0 &&
gtk_adjustment_get_upper (adjustment) == 0.0)
{
gtk_adjustment_configure (adjustment,
pspec->default_value,
pspec->minimum,
pspec->maximum,
0.1, 0.5, 0);
}
g_type_class_unref (class);
g_object_bind_property (adjustment, "value",
stack, "duration",
G_BINDING_DEFAULT);
widget = gtk_scrolled_window_new ();
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (widget), TRUE);
gtk_widget_set_hexpand (widget, TRUE);
gtk_widget_set_vexpand (widget, TRUE);
controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ());
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (controller), 0);
g_signal_connect (controller, "released", G_CALLBACK (clicked_cb), NULL);
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_BUBBLE);
gtk_widget_add_controller (GTK_WIDGET (widget), controller);
tv = gtk_text_view_new ();
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (tv), 4);
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (tv), 4);
gtk_text_view_set_top_margin (GTK_TEXT_VIEW (tv), 4);
gtk_text_view_set_bottom_margin (GTK_TEXT_VIEW (tv), 4);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
bytes = g_resources_lookup_data (resource_path, 0, NULL);
gtk_text_buffer_set_text (buffer,
(const char *)g_bytes_get_data (bytes, NULL),
g_bytes_get_size (bytes));
g_bytes_unref (bytes);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (widget), tv);
gtk_box_append (GTK_BOX (child), widget);
gtk_shader_stack_add_child (GTK_SHADER_STACK (stack), child);
gtk_shader_stack_set_active (GTK_SHADER_STACK (stack), active_child);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
widget = gtk_center_box_new ();
label = gtk_label_new (name);
gtk_widget_add_css_class (label, "title-4");
gtk_widget_set_size_request (label, -1, 26);
gtk_center_box_set_center_widget (GTK_CENTER_BOX (widget), label);
button = gtk_button_new_from_icon_name ("view-refresh-symbolic");
g_signal_connect (buffer, "changed", G_CALLBACK (text_changed), button);
g_object_set_data (G_OBJECT (button), "the-stack", stack);
g_signal_connect (button, "clicked", G_CALLBACK (apply_text), buffer);
gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
gtk_widget_add_css_class (button, "small");
gtk_widget_set_visible (button, FALSE);
gtk_center_box_set_end_widget (GTK_CENTER_BOX (widget), button);
gtk_box_append (GTK_BOX (vbox), widget);
GtkWidget *bin2 = ripple_bin_new ();
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin2), stack);
gtk_box_append (GTK_BOX (vbox), bin2);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
gtk_box_append (GTK_BOX (vbox), hbox);
button = gtk_button_new_from_icon_name ("go-previous-symbolic");
g_signal_connect (button, "clicked", G_CALLBACK (go_back), stack);
bin = ripple_bin_new ();
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin), button);
gtk_box_append (GTK_BOX (hbox), bin);
button = gtk_button_new_from_icon_name ("go-next-symbolic");
g_signal_connect (button, "clicked", G_CALLBACK (go_forward), stack);
bin = ripple_bin_new ();
gtk_shader_bin_set_child (GTK_SHADER_BIN (bin), button);
gtk_box_append (GTK_BOX (hbox), bin);
return vbox;
}
static void
remove_provider (gpointer data)
{
GtkStyleProvider *provider = GTK_STYLE_PROVIDER (data);
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
g_object_unref (provider);
}
static GtkWidget *
create_gltransition_window (GtkWidget *do_widget)
{
GtkWidget *window, *headerbar, *scale, *outer_grid, *grid, *background;
GdkPaintable *paintable;
GtkCssProvider *provider;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Transitions and Effects");
headerbar = gtk_header_bar_new ();
scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, NULL);
gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
gtk_widget_set_size_request (scale, 100, -1);
gtk_widget_set_tooltip_text (scale, "Transition duration");
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), scale);
gtk_window_set_titlebar (GTK_WINDOW (window), headerbar);
gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
outer_grid = gtk_grid_new ();
gtk_window_set_child (GTK_WINDOW (window), outer_grid);
paintable = gsk_shader_paintable_new (gsk_gl_shader_new_from_resource ("/gltransition/background.glsl"), NULL);
background = gtk_picture_new_for_paintable (paintable);
gtk_widget_add_tick_callback (background, update_paintable, NULL, NULL);
gtk_grid_attach (GTK_GRID (outer_grid),
background,
0, 0, 1, 1);
grid = gtk_grid_new ();
gtk_grid_attach (GTK_GRID (outer_grid),
grid,
0, 0, 1, 1);
gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
gtk_widget_set_valign (grid, GTK_ALIGN_CENTER);
gtk_widget_set_margin_start (grid, 12);
gtk_widget_set_margin_end (grid, 12);
gtk_widget_set_margin_top (grid, 12);
gtk_widget_set_margin_bottom (grid, 12);
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Wind", "/gltransition/wind.glsl", 0, scale),
0, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Radial", "/gltransition/radial.glsl", 1, scale),
1, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Crosswarp", "/gltransition/crosswarp.glsl", 2, scale),
0, 1, 1, 1);
gtk_grid_attach (GTK_GRID (grid),
make_shader_stack ("Kaleidoscope", "/gltransition/kaleidoscope.glsl", 3, scale),
1, 1, 1, 1);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_string (provider, "button.small { padding: 0; }");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_set_data_full (G_OBJECT (window), "provider", provider, remove_provider);
return window;
}
GtkWidget *
do_gltransition (GtkWidget *do_widget)
{
if (!demo_window)
demo_window = create_gltransition_window (do_widget);
if (!gtk_widget_get_visible (demo_window))
gtk_widget_set_visible (demo_window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (demo_window));
return demo_window;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,153 +0,0 @@
#include "graphwidget.h"
struct _GraphWidget
{
GtkWidget parent_instance;
GskPath *path;
GskStroke *stroke;
GdkRGBA color;
guint tick_cb;
guint64 start_time;
double period;
double amplitude;
};
struct _GraphWidgetClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (GraphWidget, graph_widget, GTK_TYPE_WIDGET)
static void
update_path (GraphWidget *self,
float amplitude)
{
graphene_point_t p[20];
GskPathBuilder *builder;
g_clear_pointer (&self->path, gsk_path_unref);
for (int i = 0; i < 20; i++)
{
p[i].x = 10 * i;
p[i].y = 50;
if (i % 4 == 1 || i % 4 == 2)
{
if (i % 8 < 4)
p[i].y += amplitude;
else
p[i].y -= amplitude;
}
}
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder, p[0].x, p[0].y);
for (int i = 0; i < 20; i += 4)
gsk_path_builder_cubic_to (builder,
p[i+1].x, p[i+1].y,
p[i+2].x, p[i+2].y,
p[i+3].x, p[i+3].y);
self->path = gsk_path_builder_free_to_path (builder);
}
static gboolean
tick_cb (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GraphWidget *self = GRAPH_WIDGET (widget);
guint64 now;
double angle;
now = gdk_frame_clock_get_frame_time (frame_clock);
if (self->start_time == 0)
self->start_time = now;
angle = 360 * (now - self->start_time) / (double)(self->period * G_TIME_SPAN_MINUTE);
update_path (self, sin (angle) * self->amplitude);
gtk_widget_queue_draw (widget);
return G_SOURCE_CONTINUE;
}
static void
graph_widget_init (GraphWidget *self)
{
self->color.red = g_random_double_range (0, 1);
self->color.green = g_random_double_range (0, 1);
self->color.blue = g_random_double_range (0, 1);
self->color.alpha = 1;
self->period = g_random_double_range (0.5, 1);
self->amplitude = g_random_double_range (10, 25);
self->stroke = gsk_stroke_new (2);
update_path (self, 0);
self->start_time = 0;
self->tick_cb = gtk_widget_add_tick_callback (GTK_WIDGET (self), tick_cb, NULL, NULL);
}
static void
graph_widget_dispose (GObject *object)
{
GraphWidget *self = GRAPH_WIDGET (object);
g_clear_pointer (&self->path, gsk_path_unref);
gsk_stroke_free (self->stroke);
G_OBJECT_CLASS (graph_widget_parent_class)->dispose (object);
}
static void
graph_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GraphWidget *self = GRAPH_WIDGET (widget);
gtk_snapshot_append_stroke (snapshot, self->path, self->stroke, &self->color);
}
static void
graph_widget_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = 200;
else
*minimum = *natural = 100;
}
static void
graph_widget_class_init (GraphWidgetClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = graph_widget_dispose;
widget_class->snapshot = graph_widget_snapshot;
widget_class->measure = graph_widget_measure;
}
GtkWidget *
graph_widget_new (void)
{
return g_object_new (GRAPH_TYPE_WIDGET, NULL);
}

View File

@@ -1,8 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#define GRAPH_TYPE_WIDGET (graph_widget_get_type ())
G_DECLARE_FINAL_TYPE (GraphWidget, graph_widget, GRAPH, WIDGET, GtkWidget)
GtkWidget * graph_widget_new (void);

View File

@@ -0,0 +1,334 @@
/*
* Copyright © 2020 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Matthias Clasen <mclasen@redhat.com>
*/
#include "config.h"
#include <gtk/gtk.h>
#include "gskshaderpaintable.h"
/**
* GskShaderPaintable:
*
* `GskShaderPaintable` is an implementation of the `GdkPaintable` interface
* that uses a `GskGLShader` to create pixels.
*
* You can set the uniform data that the shader needs for rendering
* using gsk_shader_paintable_set_args(). This function can
* be called repeatedly to change the uniform data for the next
* snapshot.
*
* Commonly, time is passed to shaders as a float uniform containing
* the elapsed time in seconds. The convenience API
* gsk_shader_paintable_update_time() can be called from a `GtkTickCallback`
* to update the time based on the frame time of the frame clock.
*/
struct _GskShaderPaintable
{
GObject parent_instance;
GskGLShader *shader;
GBytes *args;
gint64 start_time;
};
struct _GskShaderPaintableClass
{
GObjectClass parent_class;
};
enum {
PROP_0,
PROP_SHADER,
PROP_ARGS,
N_PROPS,
};
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gsk_shader_paintable_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (paintable);
gtk_snapshot_push_gl_shader (snapshot, self->shader, &GRAPHENE_RECT_INIT(0, 0, width, height), g_bytes_ref (self->args));
gtk_snapshot_pop (snapshot);
}
static void
gsk_shader_paintable_paintable_init (GdkPaintableInterface *iface)
{
iface->snapshot = gsk_shader_paintable_paintable_snapshot;
}
G_DEFINE_TYPE_EXTENDED (GskShaderPaintable, gsk_shader_paintable, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gsk_shader_paintable_paintable_init))
static void
gsk_shader_paintable_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
switch (prop_id)
{
case PROP_SHADER:
gsk_shader_paintable_set_shader (self, g_value_get_object (value));
break;
case PROP_ARGS:
gsk_shader_paintable_set_args (self, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gsk_shader_paintable_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
switch (prop_id)
{
case PROP_SHADER:
g_value_set_object (value, self->shader);
break;
case PROP_ARGS:
g_value_set_boxed (value, self->args);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gsk_shader_paintable_finalize (GObject *object)
{
GskShaderPaintable *self = GSK_SHADER_PAINTABLE (object);
g_clear_pointer (&self->args, g_bytes_unref);
g_clear_object (&self->shader);
G_OBJECT_CLASS (gsk_shader_paintable_parent_class)->finalize (object);
}
static void
gsk_shader_paintable_class_init (GskShaderPaintableClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = gsk_shader_paintable_get_property;
gobject_class->set_property = gsk_shader_paintable_set_property;
gobject_class->finalize = gsk_shader_paintable_finalize;
properties[PROP_SHADER] =
g_param_spec_object ("shader", "Shader", "The shader",
GSK_TYPE_GL_SHADER,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_ARGS] =
g_param_spec_boxed ("args", "Arguments", "The uniform arguments",
G_TYPE_BYTES,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
gsk_shader_paintable_init (GskShaderPaintable *self)
{
}
/**
* gsk_shader_paintable_new:
* @shader: (transfer full) (nullable): the shader to use
* @data: (transfer full) (nullable): uniform data
*
* Creates a paintable that uses the @shader to create
* pixels. The shader must not require input textures.
* If @data is %NULL, all uniform values are set to zero.
*
* Returns: (transfer full): a new `GskShaderPaintable`
*/
GdkPaintable *
gsk_shader_paintable_new (GskGLShader *shader,
GBytes *data)
{
GdkPaintable *ret;
g_return_val_if_fail (shader == NULL || GSK_IS_GL_SHADER (shader), NULL);
if (shader && !data)
{
int size = gsk_gl_shader_get_args_size (shader);
data = g_bytes_new_take (g_new0 (guchar, size), size);
}
ret = g_object_new (GSK_TYPE_SHADER_PAINTABLE,
"shader", shader,
"args", data,
NULL);
g_clear_object (&shader);
g_clear_pointer (&data, g_bytes_unref);
return ret;
}
/**
* gsk_shader_paintable_set_shader:
* @self: a `GskShaderPaintable`
* @shader: the `GskGLShader` to use
*
* Sets the shader that the paintable will use
* to create pixels. The shader must not require
* input textures.
*/
void
gsk_shader_paintable_set_shader (GskShaderPaintable *self,
GskGLShader *shader)
{
g_return_if_fail (GSK_IS_SHADER_PAINTABLE (self));
g_return_if_fail (shader == NULL || GSK_IS_GL_SHADER (shader));
g_return_if_fail (shader == NULL || gsk_gl_shader_get_n_textures (shader) == 0);
if (!g_set_object (&self->shader, shader))
return;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SHADER]);
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
g_clear_pointer (&self->args, g_bytes_unref);
}
/**
* gsk_shader_paintable_get_shader:
* @self: a `GskShaderPaintable`
*
* Returns the shader that the paintable is using.
*
* Returns: (transfer none): the `GskGLShader` that is used
*/
GskGLShader *
gsk_shader_paintable_get_shader (GskShaderPaintable *self)
{
g_return_val_if_fail (GSK_IS_SHADER_PAINTABLE (self), NULL);
return self->shader;
}
/**
* gsk_shader_paintable_set_args:
* @self: a `GskShaderPaintable`
* @data: Data block with uniform data for the shader
*
* Sets the uniform data that will be passed to the
* shader when rendering. The @data will typically
* be produced by a `GskUniformDataBuilder`.
*
* Note that the @data should be considered immutable
* after it has been passed to this function.
*/
void
gsk_shader_paintable_set_args (GskShaderPaintable *self,
GBytes *data)
{
g_return_if_fail (GSK_IS_SHADER_PAINTABLE (self));
g_return_if_fail (data == NULL || g_bytes_get_size (data) == gsk_gl_shader_get_args_size (self->shader));
g_clear_pointer (&self->args, g_bytes_unref);
if (data)
self->args = g_bytes_ref (data);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ARGS]);
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
}
/**
* gsk_shader_paintable_get_args:
* @self: a `GskShaderPaintable`
*
* Returns the uniform data set with
* gsk_shader_paintable_get_args().
*
* Returns: (transfer none): the uniform data
*/
GBytes *
gsk_shader_paintable_get_args (GskShaderPaintable *self)
{
g_return_val_if_fail (GSK_IS_SHADER_PAINTABLE (self), NULL);
return self->args;
}
/**
* gsk_shader_paintable_update_time:
* @self: a `GskShaderPaintable`
* @time_idx: the index of the uniform for time in seconds as float
* @frame_time: the current frame time, as returned by `GdkFrameClock`
*
* This function is a convenience wrapper for
* gsk_shader_paintable_set_args() that leaves all
* uniform values unchanged, except for the uniform with
* index @time_idx, which will be set to the elapsed time
* in seconds, since the first call to this function.
*
* This function is usually called from a `GtkTickCallback`.
*/
void
gsk_shader_paintable_update_time (GskShaderPaintable *self,
int time_idx,
gint64 frame_time)
{
GskShaderArgsBuilder *builder;
GBytes *args;
float time;
if (self->start_time == 0)
self->start_time = frame_time;
time = (frame_time - self->start_time) / (float)G_TIME_SPAN_SECOND;
builder = gsk_shader_args_builder_new (self->shader, self->args);
gsk_shader_args_builder_set_float (builder, time_idx, time);
args = gsk_shader_args_builder_free_to_args (builder);
gsk_shader_paintable_set_args (self, args);
g_bytes_unref (args);
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright © 2020 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Matthias Clasen <mclasen@redhat.com>
*/
#ifndef __GSK_SHADER_PAINTABLE_H__
#define __GSK_SHADER_PAINTABLE_H__
#include <gdk/gdk.h>
#include <gsk/gsk.h>
G_BEGIN_DECLS
#define GSK_TYPE_SHADER_PAINTABLE (gsk_shader_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GskShaderPaintable, gsk_shader_paintable, GSK, SHADER_PAINTABLE, GObject)
GdkPaintable * gsk_shader_paintable_new (GskGLShader *shader,
GBytes *data);
GskGLShader * gsk_shader_paintable_get_shader (GskShaderPaintable *self);
void gsk_shader_paintable_set_shader (GskShaderPaintable *self,
GskGLShader *shader);
GBytes * gsk_shader_paintable_get_args (GskShaderPaintable *self);
void gsk_shader_paintable_set_args (GskShaderPaintable *self,
GBytes *data);
void gsk_shader_paintable_update_time (GskShaderPaintable *self,
int time_idx,
gint64 frame_time);
G_END_DECLS
#endif /* __GSK_SHADER_PAINTABLE_H__ */

View File

@@ -1,138 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128"
height="128"
id="svg6843"
sodipodi:version="0.32"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
version="1.0"
sodipodi:docname="gtk-logo.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
inkscape:export-filename="/home/ebassi/Pictures/gtk-logo-256.png"
inkscape:export-xdpi="192"
inkscape:export-ydpi="192">
<defs
id="defs6845">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="-50 : 600 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="700 : 600 : 1"
inkscape:persp3d-origin="300 : 400 : 1"
id="perspective13" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="2.8284271"
inkscape:cx="69.874353"
inkscape:cy="64.313526"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:document-units="px"
inkscape:grid-bbox="true"
width="128px"
height="128px"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid7947" />
</sodipodi:namedview>
<metadata
id="metadata6848">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:date />
<dc:creator>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:publisher>
<dc:identifier />
<dc:source />
<dc:relation />
<dc:language />
<dc:subject>
<rdf:Bag />
</dc:subject>
<dc:coverage />
<dc:description />
<dc:contributor>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:contributor>
<cc:license
rdf:resource="" />
</cc:Work>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
sodipodi:nodetypes="ccccc"
id="path6976"
d="M 20.88413,30.82696 L 53.816977,55.527708 L 107.33282,39.060543 L 70.587303,17.177763 L 20.88413,30.82696 z"
style="fill:#729fcf;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" />
<path
id="path6978"
d="M 22.94243,82.287118 L 20.88413,30.82696 L 53.816977,55.527708 L 53.816977,111.10486 L 22.94243,82.287118 z"
style="fill:#e40000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" />
<path
id="path6980"
d="M 53.816977,111.10486 L 103.21619,90.5207 L 107.33282,39.060543 L 53.816977,55.527708 L 53.816977,111.10486 z"
style="fill:#7fe719;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" />
<path
sodipodi:nodetypes="ccc"
id="path6982"
d="M 23.216626,81.319479 L 70.48573,67.361442 L 103.38422,90.444516"
style="opacity:1;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
id="path6984"
d="M 70.434539,17.875593 L 70.434539,66.984877"
style="opacity:1;fill:#babdb6;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -456,33 +456,43 @@ gtk_fishbowl_do_update (GtkFishbowl *fishbowl)
{
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
GdkFrameClock *frame_clock;
GdkFrameTimings *end;
gint64 end_counter;
double fps, expected_fps;
GdkFrameTimings *start, *end;
gint64 start_counter, end_counter;
gint64 n_frames, expected_frames;
gint64 start_timestamp, end_timestamp;
gint64 interval;
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (fishbowl));
if (frame_clock == NULL)
return;
fps = gdk_frame_clock_get_fps (frame_clock);
if (fps <= 0.0)
start_counter = gdk_frame_clock_get_history_start (frame_clock);
end_counter = gdk_frame_clock_get_frame_counter (frame_clock);
start = gdk_frame_clock_get_timings (frame_clock, start_counter);
for (end = gdk_frame_clock_get_timings (frame_clock, end_counter);
end_counter > start_counter && end != NULL && !gdk_frame_timings_get_complete (end);
end = gdk_frame_clock_get_timings (frame_clock, end_counter))
end_counter--;
if (end_counter - start_counter < 4)
return;
priv->framerate = fps;
start_timestamp = gdk_frame_timings_get_presentation_time (start);
end_timestamp = gdk_frame_timings_get_presentation_time (end);
if (start_timestamp == 0 || end_timestamp == 0)
{
start_timestamp = gdk_frame_timings_get_frame_time (start);
end_timestamp = gdk_frame_timings_get_frame_time (end);
}
n_frames = end_counter - start_counter;
priv->framerate = ((double) n_frames) * G_USEC_PER_SEC / (end_timestamp - start_timestamp);
priv->framerate = ((int)(priv->framerate * 100))/100.0;
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE]);
if (!priv->benchmark)
return;
end_counter = gdk_frame_clock_get_frame_counter (frame_clock);
for (end = gdk_frame_clock_get_timings (frame_clock, end_counter);
end != NULL && !gdk_frame_timings_get_complete (end);
end = gdk_frame_clock_get_timings (frame_clock, end_counter))
end_counter--;
if (end == NULL)
return;
interval = gdk_frame_timings_get_refresh_interval (end);
if (interval == 0)
{
@@ -490,16 +500,16 @@ gtk_fishbowl_do_update (GtkFishbowl *fishbowl)
if (interval == 0)
return;
}
expected_fps = (double) G_USEC_PER_SEC / interval;
expected_frames = round ((double) (end_timestamp - start_timestamp) / interval);
if (fps > (expected_fps - 1))
if (n_frames >= expected_frames)
{
if (priv->last_benchmark_change > 0)
priv->last_benchmark_change *= 2;
else
priv->last_benchmark_change = 1;
}
else if (0.95 * fps < expected_fps)
else if (n_frames + 1 < expected_frames)
{
if (priv->last_benchmark_change < 0)
priv->last_benchmark_change--;

View File

@@ -15,7 +15,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __GTK_FISHBOWL_H__
#define __GTK_FISHBOWL_H__
#include <gtk/gtk.h>
@@ -55,7 +56,7 @@ void gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
gboolean animating);
gboolean gtk_fishbowl_get_benchmark (GtkFishbowl *fishbowl);
void gtk_fishbowl_set_benchmark (GtkFishbowl *fishbowl,
gboolean benchmark);
gboolean animating);
double gtk_fishbowl_get_framerate (GtkFishbowl *fishbowl);
gint64 gtk_fishbowl_get_update_delay (GtkFishbowl *fishbowl);
void gtk_fishbowl_set_update_delay (GtkFishbowl *fishbowl,
@@ -64,3 +65,5 @@ void gtk_fishbowl_set_creation_func (GtkFishbowl *fishbowl,
GtkFishCreationFunc creation_func);
G_END_DECLS
#endif /* __GTK_FISHBOWL_H__ */

View File

@@ -840,24 +840,24 @@ gtk_gears_unrealize (GtkWidget *widget)
GtkGearsPrivate *priv = gtk_gears_get_instance_private ((GtkGears *) widget);
gtk_gl_area_make_current (glarea);
if (gtk_gl_area_get_error (glarea) == NULL)
{
/* Release the resources associated with OpenGL */
if (priv->gear_vbo[0] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[0]));
if (gtk_gl_area_get_error (glarea) != NULL)
return;
if (priv->gear_vbo[1] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[1]));
/* Release the resources associated with OpenGL */
if (priv->gear_vbo[0] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[0]));
if (priv->gear_vbo[2] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[2]));
if (priv->gear_vbo[1] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[1]));
if (priv->vao != 0)
glDeleteVertexArrays (1, &priv->vao);
if (priv->gear_vbo[2] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[2]));
if (priv->program != 0)
glDeleteProgram (priv->program);
}
if (priv->vao != 0)
glDeleteVertexArrays (1, &priv->vao);
if (priv->program != 0)
glDeleteProgram (priv->program);
priv->ModelViewProjectionMatrix_location = 0;
priv->NormalMatrix_location = 0;

View File

@@ -1,4 +1,5 @@
#pragma once
#ifndef __GTK_GEARS_H__
#define __GTK_GEARS_H__
#include <gtk/gtk.h>
@@ -43,3 +44,5 @@ void gtk_gears_set_fps_label (GtkGears *gears,
G_END_DECLS
#endif /* __GTK_GEARS_H__ */

View File

@@ -0,0 +1,264 @@
#include "gtkshaderbin.h"
typedef struct {
GskGLShader *shader;
GtkStateFlags state;
GtkStateFlags state_mask;
float extra_border;
gboolean compiled;
gboolean compiled_ok;
} ShaderInfo;
struct _GtkShaderBin
{
GtkWidget parent_instance;
GtkWidget *child;
ShaderInfo *active_shader;
GPtrArray *shaders;
guint tick_id;
float time;
float mouse_x, mouse_y;
gint64 first_frame_time;
};
struct _GtkShaderBinClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (GtkShaderBin, gtk_shader_bin, GTK_TYPE_WIDGET)
static void
shader_info_free (ShaderInfo *info)
{
g_object_unref (info->shader);
g_free (info);
}
static void
gtk_shader_bin_finalize (GObject *object)
{
GtkShaderBin *self = GTK_SHADER_BIN (object);
g_ptr_array_free (self->shaders, TRUE);
G_OBJECT_CLASS (gtk_shader_bin_parent_class)->finalize (object);
}
static void
gtk_shader_bin_dispose (GObject *object)
{
GtkShaderBin *self = GTK_SHADER_BIN (object);
g_clear_pointer (&self->child, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_shader_bin_parent_class)->dispose (object);
}
static gboolean
gtk_shader_bin_tick (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer unused)
{
GtkShaderBin *self = GTK_SHADER_BIN (widget);
gint64 frame_time;
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
if (self->first_frame_time == 0)
self->first_frame_time = frame_time;
self->time = (frame_time - self->first_frame_time) / (float)G_USEC_PER_SEC;
gtk_widget_queue_draw (widget);
return G_SOURCE_CONTINUE;
}
static void
motion_cb (GtkEventControllerMotion *controller,
double x,
double y,
GtkShaderBin *self)
{
self->mouse_x = x;
self->mouse_y = y;
}
static void
gtk_shader_bin_init (GtkShaderBin *self)
{
GtkEventController *controller;
self->shaders = g_ptr_array_new_with_free_func ((GDestroyNotify)shader_info_free);
controller = gtk_event_controller_motion_new ();
g_signal_connect (controller, "motion", G_CALLBACK (motion_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
}
void
gtk_shader_bin_update_active_shader (GtkShaderBin *self)
{
GtkStateFlags new_state = gtk_widget_get_state_flags (GTK_WIDGET (self));
ShaderInfo *new_shader = NULL;
for (int i = 0; i < self->shaders->len; i++)
{
ShaderInfo *info = g_ptr_array_index (self->shaders, i);
if ((info->state_mask & new_state) == info->state)
{
new_shader = info;
break;
}
}
if (self->active_shader == new_shader)
return;
self->active_shader = new_shader;
self->first_frame_time = 0;
if (self->active_shader)
{
if (self->tick_id == 0)
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self),
gtk_shader_bin_tick,
NULL, NULL);
}
else
{
if (self->tick_id != 0)
{
gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->tick_id);
self->tick_id = 0;
}
}
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
gtk_shader_bin_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state_flags)
{
GtkShaderBin *self = GTK_SHADER_BIN (widget);
gtk_shader_bin_update_active_shader (self);
}
void
gtk_shader_bin_add_shader (GtkShaderBin *self,
GskGLShader *shader,
GtkStateFlags state,
GtkStateFlags state_mask,
float extra_border)
{
ShaderInfo *info = g_new0 (ShaderInfo, 1);
info->shader = g_object_ref (shader);
info->state = state;
info->state_mask = state_mask;
info->extra_border = extra_border;
g_ptr_array_add (self->shaders, info);
gtk_shader_bin_update_active_shader (self);
}
void
gtk_shader_bin_set_child (GtkShaderBin *self,
GtkWidget *child)
{
if (self->child == child)
return;
g_clear_pointer (&self->child, gtk_widget_unparent);
if (child)
{
self->child = child;
gtk_widget_set_parent (child, GTK_WIDGET (self));
}
}
GtkWidget *
gtk_shader_bin_get_child (GtkShaderBin *self)
{
return self->child;
}
static void
gtk_shader_bin_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkShaderBin *self = GTK_SHADER_BIN (widget);
int width, height;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
if (self->active_shader)
{
if (!self->active_shader->compiled)
{
GtkNative *native = gtk_widget_get_native (widget);
GskRenderer *renderer = gtk_native_get_renderer (native);
GError *error = NULL;
self->active_shader->compiled = TRUE;
self->active_shader->compiled_ok =
gsk_gl_shader_compile (self->active_shader->shader,
renderer, &error);
if (!self->active_shader->compiled_ok)
{
g_warning ("GtkShaderBin failed to compile shader: %s", error->message);
g_error_free (error);
}
}
if (self->active_shader->compiled_ok)
{
float border = self->active_shader->extra_border;
graphene_vec2_t mouse;
graphene_vec2_init (&mouse, self->mouse_x + border, self->mouse_y + border);
gtk_snapshot_push_gl_shader (snapshot, self->active_shader->shader,
&GRAPHENE_RECT_INIT(-border, -border, width+2*border, height+2*border),
gsk_gl_shader_format_args (self->active_shader->shader,
"u_time", self->time,
"u_mouse", &mouse,
NULL));
gtk_widget_snapshot_child (widget, self->child, snapshot);
gtk_snapshot_gl_shader_pop_texture (snapshot);
gtk_snapshot_pop (snapshot);
return;
}
}
/* Non-shader fallback */
gtk_widget_snapshot_child (widget, self->child, snapshot);
}
static void
gtk_shader_bin_class_init (GtkShaderBinClass *class)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = gtk_shader_bin_finalize;
object_class->dispose = gtk_shader_bin_dispose;
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
widget_class->snapshot = gtk_shader_bin_snapshot;
widget_class->state_flags_changed = gtk_shader_bin_state_flags_changed;
}
GtkWidget *
gtk_shader_bin_new (void)
{
GtkShaderBin *self;
self = g_object_new (GTK_TYPE_SHADER_BIN, NULL);
return GTK_WIDGET (self);
}

View File

@@ -0,0 +1,23 @@
#ifndef __GTK_SHADER_BIN_H__
#define __GTK_SHADER_BIN_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GTK_TYPE_SHADER_BIN (gtk_shader_bin_get_type ())
G_DECLARE_FINAL_TYPE (GtkShaderBin, gtk_shader_bin, GTK, SHADER_BIN, GtkWidget)
GtkWidget *gtk_shader_bin_new (void);
void gtk_shader_bin_add_shader (GtkShaderBin *self,
GskGLShader *shader,
GtkStateFlags state,
GtkStateFlags state_mask,
float extra_border);
void gtk_shader_bin_set_child (GtkShaderBin *self,
GtkWidget *child);
GtkWidget *gtk_shader_bin_get_child (GtkShaderBin *self);
G_END_DECLS
#endif /* __GTK_SHADER_BIN_H__ */

View File

@@ -0,0 +1,361 @@
#include "gtkshaderstack.h"
struct _GtkShaderStack
{
GtkWidget parent_instance;
GskGLShader *shader;
GPtrArray *children;
int current;
int next;
gboolean backwards;
guint tick_id;
float time;
float duration;
gint64 start_time;
};
struct _GtkShaderStackClass
{
GtkWidgetClass parent_class;
};
enum {
PROP_DURATION = 1,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL };
G_DEFINE_TYPE (GtkShaderStack, gtk_shader_stack, GTK_TYPE_WIDGET)
static void
gtk_shader_stack_finalize (GObject *object)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
g_object_unref (self->shader);
G_OBJECT_CLASS (gtk_shader_stack_parent_class)->finalize (object);
}
static void
update_child_visible (GtkShaderStack *self)
{
int i;
for (i = 0; i < self->children->len; i++)
{
GtkWidget *child = g_ptr_array_index (self->children, i);
gtk_widget_set_child_visible (child,
i == self->current || i == self->next);
}
}
static gboolean
transition_cb (GtkWidget *widget,
GdkFrameClock *clock,
gpointer unused)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
gint64 frame_time;
frame_time = gdk_frame_clock_get_frame_time (clock);
if (self->start_time == 0)
self->start_time = frame_time;
self->time = (frame_time - self->start_time) / (float)G_USEC_PER_SEC;
gtk_widget_queue_draw (widget);
if (self->time >= self->duration)
{
self->current = self->next;
self->next = -1;
update_child_visible (self);
return G_SOURCE_REMOVE;
}
else
return G_SOURCE_CONTINUE;
}
static void
start_transition (GtkShaderStack *self)
{
self->start_time = 0;
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self),
transition_cb,
NULL, NULL);
}
static void
stop_transition (GtkShaderStack *self)
{
if (self->tick_id != 0)
{
gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->tick_id);
self->tick_id = 0;
}
if (self->next != -1)
self->current = self->next;
self->next = -1;
update_child_visible (self);
}
static void
gtk_shader_stack_dispose (GObject *object)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
stop_transition (self);
g_clear_pointer (&self->children, g_ptr_array_unref);
G_OBJECT_CLASS (gtk_shader_stack_parent_class)->dispose (object);
}
void
gtk_shader_stack_transition (GtkShaderStack *self,
gboolean forward)
{
stop_transition (self);
self->backwards = !forward;
if (self->backwards)
self->next = (self->current + self->children->len - 1) % self->children->len;
else
self->next = (self->current + 1) % self->children->len;
update_child_visible (self);
start_transition (self);
}
static void
gtk_shader_stack_init (GtkShaderStack *self)
{
self->children = g_ptr_array_new_with_free_func ((GDestroyNotify)gtk_widget_unparent);
self->current = -1;
self->next = -1;
self->backwards = FALSE;
self->duration = 1.0;
}
static void
gtk_shader_stack_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
int i;
*minimum = 0;
*natural = 0;
for (i = 0; i < self->children->len; i++)
{
GtkWidget *child = g_ptr_array_index (self->children, i);
int child_min, child_nat;
if (gtk_widget_get_visible (child))
{
gtk_widget_measure (child, orientation, for_size, &child_min, &child_nat, NULL, NULL);
*minimum = MAX (*minimum, child_min);
*natural = MAX (*natural, child_nat);
}
}
}
static void
gtk_shader_stack_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
GtkAllocation child_allocation;
GtkWidget *child;
int i;
child_allocation.x = 0;
child_allocation.y = 0;
child_allocation.width = width;
child_allocation.height = height;
for (i = 0; i < self->children->len; i++)
{
child = g_ptr_array_index (self->children, i);
if (gtk_widget_get_visible (child))
gtk_widget_size_allocate (child, &child_allocation, -1);
}
}
static void
gtk_shader_stack_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkShaderStack *self = GTK_SHADER_STACK (widget);
int width, height;
GtkWidget *current, *next;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
current = g_ptr_array_index (self->children, self->current);
if (self->next == -1)
{
gtk_widget_snapshot_child (widget, current, snapshot);
}
else
{
GtkNative *native = gtk_widget_get_native (widget);
GskRenderer *renderer = gtk_native_get_renderer (native);
float progress;
next = g_ptr_array_index (self->children, self->next);
progress = self->time / self->duration;
if (self->backwards)
{
GtkWidget *tmp = next;
next = current;
current = tmp;
progress = 1. - progress;
}
if (gsk_gl_shader_compile (self->shader, renderer, NULL))
{
gtk_snapshot_push_gl_shader (snapshot,
self->shader,
&GRAPHENE_RECT_INIT(0, 0, width, height),
gsk_gl_shader_format_args (self->shader,
"progress", progress,
NULL));
gtk_widget_snapshot_child (widget, current, snapshot);
gtk_snapshot_gl_shader_pop_texture (snapshot); /* current child */
gtk_widget_snapshot_child (widget, next, snapshot);
gtk_snapshot_gl_shader_pop_texture (snapshot); /* next child */
gtk_snapshot_pop (snapshot);
}
else
{
/* Non-shader fallback */
gtk_widget_snapshot_child (widget, current, snapshot);
}
}
}
static void
gtk_shader_stack_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
switch (prop_id)
{
case PROP_DURATION:
g_value_set_float (value, self->duration);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_shader_stack_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkShaderStack *self = GTK_SHADER_STACK (object);
switch (prop_id)
{
case PROP_DURATION:
self->duration = g_value_get_float (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_shader_stack_class_init (GtkShaderStackClass *class)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = gtk_shader_stack_finalize;
object_class->dispose = gtk_shader_stack_dispose;
object_class->get_property = gtk_shader_stack_get_property;
object_class->set_property = gtk_shader_stack_set_property;
widget_class->snapshot = gtk_shader_stack_snapshot;
widget_class->measure = gtk_shader_stack_measure;
widget_class->size_allocate = gtk_shader_stack_size_allocate;
properties[PROP_DURATION] =
g_param_spec_float ("duration", "Duration", "Duration",
0.1, 3.0, 1.0,
G_PARAM_READWRITE);
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
}
GtkWidget *
gtk_shader_stack_new (void)
{
return g_object_new (GTK_TYPE_SHADER_STACK, NULL);
}
void
gtk_shader_stack_set_shader (GtkShaderStack *self,
GskGLShader *shader)
{
g_set_object (&self->shader, shader);
}
void
gtk_shader_stack_add_child (GtkShaderStack *self,
GtkWidget *child)
{
g_ptr_array_add (self->children, child);
gtk_widget_set_parent (child, GTK_WIDGET (self));
gtk_widget_queue_resize (GTK_WIDGET (self));
if (self->current == -1)
self->current = 0;
else
gtk_widget_set_child_visible (child, FALSE);
}
void
gtk_shader_stack_set_active (GtkShaderStack *self,
int index)
{
stop_transition (self);
self->current = MIN (index, self->children->len);
update_child_visible (self);
}

View File

@@ -0,0 +1,23 @@
#ifndef __GTK_SHADER_STACK_H__
#define __GTK_SHADER_STACK_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GTK_TYPE_SHADER_STACK (gtk_shader_stack_get_type ())
G_DECLARE_FINAL_TYPE (GtkShaderStack, gtk_shader_stack, GTK, SHADER_STACK, GtkWidget)
GtkWidget * gtk_shader_stack_new (void);
void gtk_shader_stack_set_shader (GtkShaderStack *self,
GskGLShader *shader);
void gtk_shader_stack_add_child (GtkShaderStack *self,
GtkWidget *child);
void gtk_shader_stack_transition (GtkShaderStack *self,
gboolean forward);
void gtk_shader_stack_set_active (GtkShaderStack *self,
int index);
G_END_DECLS
#endif /* __GTK_SHADER_STACK_H__ */

View File

@@ -116,9 +116,7 @@ static gboolean gtk_shadertoy_tick (GtkWidget *widget,
GtkWidget *
gtk_shadertoy_new (void)
{
return g_object_new (gtk_shadertoy_get_type (),
"allowed-apis", GDK_GL_API_GL,
NULL);
return g_object_new (gtk_shadertoy_get_type (), NULL);
}
static void

View File

@@ -1,4 +1,5 @@
#pragma once
#ifndef __GTK_SHADERTOY_H__
#define __GTK_SHADERTOY_H__
#include <gtk/gtk.h>
@@ -29,3 +30,5 @@ void gtk_shadertoy_set_image_shader (GtkShadertoy *shadertoy,
const char *shader);
G_END_DECLS
#endif /* __GTK_SHADERTOY_H__ */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,7 +1,5 @@
#pragma once
#include <gdk/gdk.h>
typedef struct _GdkHSLA GdkHSLA;
struct _GdkHSLA {

View File

@@ -13,7 +13,7 @@ static GtkWidget *window = NULL;
static GtkWidget *scrolledwindow;
static int selected;
#define N_WIDGET_TYPES 9
#define N_WIDGET_TYPES 8
static int hincrement = 5;
@@ -73,77 +73,30 @@ populate_icons (void)
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolledwindow), grid);
}
static char *content;
static gsize content_len;
extern void fontify (const char *format, GtkTextBuffer *buffer);
enum {
PLAIN_TEXT,
HIGHLIGHTED_TEXT,
UNDERLINED_TEXT,
};
static void
underlinify (GtkTextBuffer *buffer)
{
GtkTextTagTable *tags;
GtkTextTag *tag[3];
GtkTextIter start, end;
tags = gtk_text_buffer_get_tag_table (buffer);
tag[0] = gtk_text_tag_new ("error");
tag[1] = gtk_text_tag_new ("strikeout");
tag[2] = gtk_text_tag_new ("double");
g_object_set (tag[0], "underline", PANGO_UNDERLINE_ERROR, NULL);
g_object_set (tag[1], "strikethrough", TRUE, NULL);
g_object_set (tag[2],
"underline", PANGO_UNDERLINE_DOUBLE,
"underline-rgba", &(GdkRGBA){0., 1., 1., 1. },
NULL);
gtk_text_tag_table_add (tags, tag[0]);
gtk_text_tag_table_add (tags, tag[1]);
gtk_text_tag_table_add (tags, tag[2]);
gtk_text_buffer_get_start_iter (buffer, &end);
while (TRUE)
{
gtk_text_iter_forward_word_end (&end);
start = end;
gtk_text_iter_backward_word_start (&start);
gtk_text_buffer_apply_tag (buffer, tag[g_random_int_range (0, 3)], &start, &end);
if (!gtk_text_iter_forward_word_ends (&end, 3))
break;
}
}
static void
populate_text (const char *resource, int kind)
populate_text (gboolean highlight)
{
GtkWidget *textview;
GtkTextBuffer *buffer;
char *content;
gsize content_len;
GBytes *bytes;
bytes = g_resources_lookup_data (resource, 0, NULL);
content = g_bytes_unref_to_data (bytes, &content_len);
if (!content)
{
GBytes *bytes;
bytes = g_resources_lookup_data ("/sources/font_features.c", 0, NULL);
content = g_bytes_unref_to_data (bytes, &content_len);
}
buffer = gtk_text_buffer_new (NULL);
gtk_text_buffer_set_text (buffer, content, (int)content_len);
switch (kind)
{
case HIGHLIGHTED_TEXT:
fontify ("c", buffer);
break;
case UNDERLINED_TEXT:
underlinify (buffer);
break;
case PLAIN_TEXT:
default:
break;
}
if (highlight)
fontify ("c", buffer);
textview = gtk_text_view_new ();
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
@@ -202,6 +155,14 @@ populate_image (void)
{
GtkWidget *image;
if (!content)
{
GBytes *bytes;
bytes = g_resources_lookup_data ("/sources/font_features.c", 0, NULL);
content = g_bytes_unref_to_data (bytes, &content_len);
}
image = gtk_picture_new_for_resource ("/sliding_puzzle/portland-rose.jpg");
gtk_picture_set_can_shrink (GTK_PICTURE (image), FALSE);
@@ -294,40 +255,35 @@ set_widget_type (int type)
case 1:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling plain text");
populate_text ("/sources/font_features.c", PLAIN_TEXT);
populate_text (FALSE);
break;
case 2:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling colored text");
populate_text ("/sources/font_features.c", HIGHLIGHTED_TEXT);
gtk_window_set_title (GTK_WINDOW (window), "Scrolling complex text");
populate_text (TRUE);
break;
case 3:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling text with underlines");
populate_text ("/org/gtk/Demo4/Moby-Dick.txt", UNDERLINED_TEXT);
break;
case 4:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling text with Emoji");
populate_emoji_text ();
break;
case 5:
case 4:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a big image");
populate_image ();
break;
case 6:
case 5:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a list");
populate_list ();
break;
case 7:
case 6:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a columned list");
populate_list2 ();
break;
case 8:
case 7:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a grid");
populate_grid ();
break;

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="resizable">1</property>
<property name="resizable">0</property>
<property name="default-width">500</property>
<property name="default-height">500</property>
<child type="titlebar">

View File

@@ -14,103 +14,6 @@
#include <gtk/gtk.h>
#include "demo3widget.h"
static GtkWidget *window = NULL;
static GCancellable *cancellable = NULL;
static void
load_texture (GTask *task,
gpointer source_object,
gpointer task_data,
GCancellable *cable)
{
GFile *file = task_data;
GdkTexture *texture;
GError *error = NULL;
texture = gdk_texture_new_from_file (file, &error);
if (texture)
g_task_return_pointer (task, texture, g_object_unref);
else
g_task_return_error (task, error);
}
static void
set_wait_cursor (GtkWidget *widget)
{
gtk_widget_set_cursor_from_name (GTK_WIDGET (gtk_widget_get_root (widget)), "wait");
}
static void
unset_wait_cursor (GtkWidget *widget)
{
gtk_widget_set_cursor (GTK_WIDGET (gtk_widget_get_root (widget)), NULL);
}
static void
texture_loaded (GObject *source,
GAsyncResult *result,
gpointer data)
{
GdkTexture *texture;
GError *error = NULL;
texture = g_task_propagate_pointer (G_TASK (result), &error);
if (!texture)
{
g_print ("%s\n", error->message);
g_error_free (error);
return;
}
if (!window)
{
g_object_unref (texture);
return;
}
unset_wait_cursor (GTK_WIDGET (data));
g_object_set (G_OBJECT (data), "texture", texture, NULL);
}
static void
open_file_async (GFile *file,
GtkWidget *demo)
{
GTask *task;
set_wait_cursor (demo);
task = g_task_new (demo, cancellable, texture_loaded, demo);
g_task_set_task_data (task, g_object_ref (file), g_object_unref);
g_task_run_in_thread (task, load_texture);
g_object_unref (task);
}
static void
open_portland_rose (GtkWidget *button,
GtkWidget *demo)
{
GFile *file;
file = g_file_new_for_uri ("resource:///transparent/portland-rose.jpg");
open_file_async (file, demo);
g_object_unref (file);
}
static void
open_large_image (GtkWidget *button,
GtkWidget *demo)
{
GFile *file;
file = g_file_new_for_uri ("resource:///org/gtk/Demo4/large-image.png");
open_file_async (file, demo);
g_object_unref (file);
}
static void
file_opened (GObject *source,
GAsyncResult *result,
@@ -118,6 +21,7 @@ file_opened (GObject *source,
{
GFile *file;
GError *error = NULL;
GdkTexture *texture;
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
@@ -128,9 +32,17 @@ file_opened (GObject *source,
return;
}
open_file_async (file, data);
texture = gdk_texture_new_from_file (file, &error);
g_object_unref (file);
if (!texture)
{
g_print ("%s\n", error->message);
g_error_free (error);
return;
}
g_object_set (G_OBJECT (data), "texture", texture, NULL);
g_object_unref (texture);
}
static void
@@ -204,26 +116,11 @@ transform_from (GBinding *binding,
return TRUE;
}
static void
free_cancellable (gpointer data)
{
g_cancellable_cancel (cancellable);
g_clear_object (&cancellable);
}
static gboolean
cancel_load (GtkWidget *widget,
GVariant *args,
gpointer data)
{
unset_wait_cursor (widget);
g_cancellable_cancel (G_CANCELLABLE (data));
return TRUE;
}
GtkWidget *
do_image_scaling (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *box;
@@ -233,7 +130,6 @@ do_image_scaling (GtkWidget *do_widget)
GtkWidget *scale;
GtkWidget *dropdown;
GtkWidget *button;
GtkEventController *controller;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Image Scaling");
@@ -242,20 +138,6 @@ do_image_scaling (GtkWidget *do_widget)
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
cancellable = g_cancellable_new ();
g_object_set_data_full (G_OBJECT (window), "cancellable",
cancellable, free_cancellable);
controller = gtk_shortcut_controller_new ();
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (
gtk_keyval_trigger_new (GDK_KEY_Escape, 0),
gtk_callback_action_new (cancel_load, cancellable, NULL)
));
gtk_shortcut_controller_set_scope (GTK_SHORTCUT_CONTROLLER (controller),
GTK_SHORTCUT_SCOPE_GLOBAL);
gtk_widget_add_controller (window, controller);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_window_set_child (GTK_WINDOW (window), box);
@@ -274,22 +156,6 @@ do_image_scaling (GtkWidget *do_widget)
g_signal_connect (button, "clicked", G_CALLBACK (open_file), widget);
gtk_box_append (GTK_BOX (box2), button);
button = gtk_button_new ();
gtk_button_set_child (GTK_BUTTON (button),
gtk_image_new_from_resource ("/org/gtk/Demo4/portland-rose-thumbnail.png"));
gtk_widget_add_css_class (button, "image-button");
gtk_widget_set_tooltip_text (button, "Portland Rose");
g_signal_connect (button, "clicked", G_CALLBACK (open_portland_rose), widget);
gtk_box_append (GTK_BOX (box2), button);
button = gtk_button_new ();
gtk_button_set_child (GTK_BUTTON (button),
gtk_image_new_from_resource ("/org/gtk/Demo4/large-image-thumbnail.png"));
gtk_widget_add_css_class (button, "image-button");
gtk_widget_set_tooltip_text (button, "Large image");
g_signal_connect (button, "clicked", G_CALLBACK (open_large_image), widget);
gtk_box_append (GTK_BOX (box2), button);
button = gtk_button_new_from_icon_name ("object-rotate-right-symbolic");
gtk_widget_set_tooltip_text (button, "Rotate");
g_signal_connect (button, "clicked", G_CALLBACK (rotate), widget);
@@ -325,9 +191,7 @@ do_image_scaling (GtkWidget *do_widget)
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
else
{
gtk_window_destroy (GTK_WINDOW (window));
}
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -354,7 +354,6 @@ do_images (GtkWidget *do_widget)
gicon = g_themed_icon_new_with_default_fallbacks ("battery-caution-charging-symbolic");
image = gtk_image_new_from_gicon (gicon);
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
g_object_unref (gicon);
gtk_frame_set_child (GTK_FRAME (frame), image);

View File

@@ -0,0 +1,41 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/kaleidoscope
// Author: nwoeanhinnogaehr
// License: MIT
const float speed = 1.0;
const float angle = 1.0;
const float power = 1.5;
vec4 transition(vec2 uv) {
vec2 p = uv.xy / vec2(1.0).xy;
vec2 q = p;
float t = pow(progress, power)*speed;
p = p -0.5;
for (int i = 0; i < 7; i++) {
p = vec2(sin(t)*p.x + cos(t)*p.y, sin(t)*p.y - cos(t)*p.x);
t += angle;
p = abs(mod(p, 2.0) - 1.0);
}
abs(mod(p, 1.0));
return mix(
mix(getFromColor(q), getToColor(q), progress),
mix(getFromColor(p), getToColor(p), progress), 1.0 - 2.0*abs(progress - 0.5));
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}

View File

@@ -40,7 +40,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
{
wchar_t *langname_w = NULL;
wchar_t locale_abbrev_w[9];
gchar *langname, *locale_abbrev, *locale;
gchar *langname, *locale_abbrev, *locale, *p;
gint i;
const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 };
GHashTable *ht_scripts_langs = (GHashTable *) param;
@@ -59,6 +59,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, langname_size);
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
p = strchr (locale, '-');
lang = pango_language_from_string (locale);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);

View File

@@ -1,4 +1,5 @@
#pragma once
#ifndef LANGUAGE_NAMES_H
#define LANGUAGE_NAMES_H
#include <pango/pango.h>
@@ -8,3 +9,5 @@ const char * get_language_name (PangoLanguage *language);
const char * get_language_name_for_tag (guint32 tag);
G_END_DECLS
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 622 KiB

View File

@@ -355,28 +355,28 @@ create_clocks_model (void)
g_list_store_append (result, clock);
g_object_unref (clock);
/* A bunch of timezones with GTK hackers */
clock = gtk_clock_new ("San Francisco", g_time_zone_new_identifier ("America/Los_Angeles"));
clock = gtk_clock_new ("San Francisco", g_time_zone_new ("America/Los_Angeles"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Xalapa", g_time_zone_new_identifier ("America/Mexico_City"));
clock = gtk_clock_new ("Xalapa", g_time_zone_new ("America/Mexico_City"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Boston", g_time_zone_new_identifier ("America/New_York"));
clock = gtk_clock_new ("Boston", g_time_zone_new ("America/New_York"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("London", g_time_zone_new_identifier ("Europe/London"));
clock = gtk_clock_new ("London", g_time_zone_new ("Europe/London"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Berlin", g_time_zone_new_identifier ("Europe/Berlin"));
clock = gtk_clock_new ("Berlin", g_time_zone_new ("Europe/Berlin"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Moscow", g_time_zone_new_identifier ("Europe/Moscow"));
clock = gtk_clock_new ("Moscow", g_time_zone_new ("Europe/Moscow"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("New Delhi", g_time_zone_new_identifier ("Asia/Kolkata"));
clock = gtk_clock_new ("New Delhi", g_time_zone_new ("Asia/Kolkata"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Shanghai", g_time_zone_new_identifier ("Asia/Shanghai"));
clock = gtk_clock_new ("Shanghai", g_time_zone_new ("Asia/Shanghai"));
g_list_store_append (result, clock);
g_object_unref (clock);

View File

@@ -1,5 +1,4 @@
/* Lists/Selections
* #Keywords: suggestion, completion
*
* The GtkDropDown widget is a modern alternative to GtkComboBox.
* It uses list models instead of tree models, and the content is

View File

@@ -20,12 +20,11 @@
#include "config.h"
#include <gtk/gtk.h>
#include <glib/gstdio.h>
#include <glib/gi18n.h>
#include "demos.h"
#include "fontify.h"
#include "profile_conf.h"
#include "demo_conf.h"
static GtkWidget *info_view;
static GtkWidget *source_view;
@@ -156,6 +155,11 @@ gtk_demo_run (GtkDemo *self,
if (result == NULL)
return FALSE;
if (GTK_IS_WINDOW (result))
{
gtk_window_set_transient_for (GTK_WINDOW (result), GTK_WINDOW (window));
gtk_window_set_modal (GTK_WINDOW (result), TRUE);
}
return TRUE;
}
@@ -823,22 +827,13 @@ demo_search_changed_cb (GtkSearchEntry *entry,
gtk_filter_changed (filter, GTK_FILTER_CHANGE_DIFFERENT);
}
static gboolean
demo_can_run (GtkWidget *window,
const char *name)
{
return TRUE;
}
static GListModel *
create_demo_model (GtkWidget *window)
create_demo_model (void)
{
GListStore *store = g_list_store_new (GTK_TYPE_DEMO);
DemoData *demo = gtk_demos;
GtkDemo *d;
gtk_widget_realize (window);
d = GTK_DEMO (g_object_new (GTK_TYPE_DEMO, NULL));
d->name = "main";
d->title = "GTK Demo";
@@ -850,20 +845,16 @@ create_demo_model (GtkWidget *window)
while (demo->title)
{
DemoData *children = demo->children;
d = GTK_DEMO (g_object_new (GTK_TYPE_DEMO, NULL));
DemoData *children = demo->children;
if (demo_can_run (window, demo->name))
{
d = GTK_DEMO (g_object_new (GTK_TYPE_DEMO, NULL));
d->name = demo->name;
d->title = demo->title;
d->keywords = demo->keywords;
d->filename = demo->filename;
d->func = demo->func;
d->name = demo->name;
d->title = demo->title;
d->keywords = demo->keywords;
d->filename = demo->filename;
d->func = demo->func;
g_list_store_append (store, d);
}
g_list_store_append (store, d);
if (children)
{
@@ -871,19 +862,15 @@ create_demo_model (GtkWidget *window)
while (children->title)
{
if (demo_can_run (window, children->name))
{
GtkDemo *child = GTK_DEMO (g_object_new (GTK_TYPE_DEMO, NULL));
GtkDemo *child = GTK_DEMO (g_object_new (GTK_TYPE_DEMO, NULL));
child->name = children->name;
child->title = children->title;
child->keywords = children->keywords;
child->filename = children->filename;
child->func = children->func;
g_list_store_append (G_LIST_STORE (d->children_model), child);
}
child->name = children->name;
child->title = children->title;
child->keywords = children->keywords;
child->filename = children->filename;
child->func = children->func;
g_list_store_append (G_LIST_STORE (d->children_model), child);
children++;
}
}
@@ -916,34 +903,6 @@ clear_search (GtkSearchBar *bar)
}
}
static void
search_results_update (GObject *filter_model,
GParamSpec *pspec,
GtkEntry *entry)
{
gsize n_items = g_list_model_get_n_items (G_LIST_MODEL (filter_model));
if (strlen (gtk_editable_get_text (GTK_EDITABLE (entry))) > 0)
{
char *text;
if (n_items > 0)
text = g_strdup_printf (ngettext ("%ld search result", "%ld search results", (long) n_items), (long) n_items);
else
text = g_strdup (_("No search results"));
gtk_accessible_update_property (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_PROPERTY_DESCRIPTION, text,
-1);
g_free (text);
}
else
{
gtk_accessible_reset_property (GTK_ACCESSIBLE (entry), GTK_ACCESSIBLE_PROPERTY_DESCRIPTION);
}
}
static void
activate (GApplication *app)
{
@@ -977,7 +936,7 @@ activate (GApplication *app)
search_bar = GTK_WIDGET (gtk_builder_get_object (builder, "searchbar"));
g_signal_connect (search_bar, "notify::search-mode-enabled", G_CALLBACK (clear_search), NULL);
listmodel = create_demo_model (window);
listmodel = create_demo_model ();
treemodel = gtk_tree_list_model_new (G_LIST_MODEL (listmodel),
FALSE,
TRUE,
@@ -991,7 +950,6 @@ activate (GApplication *app)
search_entry = GTK_WIDGET (gtk_builder_get_object (builder, "search-entry"));
g_signal_connect (search_entry, "search-changed", G_CALLBACK (demo_search_changed_cb), filter);
g_signal_connect (filter_model, "notify::n-items", G_CALLBACK (search_results_update), search_entry);
selection = gtk_single_selection_new (G_LIST_MODEL (filter_model));
g_signal_connect (selection, "notify::selected-item", G_CALLBACK (selection_cb), NULL);
@@ -1060,8 +1018,6 @@ command_line (GApplication *app,
window = gtk_application_get_windows (GTK_APPLICATION (app))->data;
gtk_window_set_icon_name (GTK_WINDOW (window), "org.gtk.Demo4");
if (name == NULL)
goto out;

View File

@@ -2,7 +2,7 @@
<interface>
<menu id="menubar">
<submenu>
<attribute name="label" translatable="yes">_File</attribute>
<attribute name="label" translatable="yes">_Application</attribute>
<section>
<item>
<attribute name="label" translatable="yes">_New</attribute>
@@ -33,7 +33,7 @@
</section>
</submenu>
<submenu>
<attribute name="label" translatable="yes">_Preferences</attribute>
<attribute name="label" translatable="yes">_File</attribute>
<section>
<item>
<attribute name="label" translatable="yes">_Prefer Dark Theme</attribute>

View File

@@ -33,6 +33,7 @@ demos = files([
'gears.c',
'gestures.c',
'glarea.c',
'gltransition.c',
'headerbar.c',
'hypertext.c',
'iconscroll.c',
@@ -72,9 +73,6 @@ demos = files([
'panes.c',
'password_entry.c',
'path_fill.c',
'path_maze.c',
'path_spinner.c',
'path_walk.c',
'path_text.c',
'peg_solitaire.c',
'pickers.c',
@@ -116,7 +114,10 @@ extra_demo_sources = files([
'gtkfishbowl.c',
'fontplane.c',
'gtkgears.c',
'gtkshaderbin.c',
'gtkshadertoy.c',
'gtkshaderstack.c',
'gskshaderpaintable.c',
'hsla.c',
'puzzlepiece.c',
'bluroverlay.c',
@@ -137,8 +138,6 @@ extra_demo_sources = files([
'unicode-names.c',
'suggestionentry.c',
'language-names.c',
'nodewidget.c',
'graphwidget.c',
])
if os_unix
@@ -232,7 +231,7 @@ foreach flag: common_cflags
endif
endforeach
gtkdemo_deps += [ profile_conf_h ]
gtkdemo_deps += [ demo_conf_h ]
executable('gtk4-demo',
sources: [demos, demos_h, extra_demo_sources, gtkdemo_resources],

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,76 +0,0 @@
#include "nodewidget.h"
struct _NodeWidget
{
GtkWidget parent_instance;
GskRenderNode *node;
};
struct _NodeWidgetClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (NodeWidget, node_widget, GTK_TYPE_WIDGET)
static void
node_widget_init (NodeWidget *self)
{
}
static void
node_widget_dispose (GObject *object)
{
NodeWidget *self = NODE_WIDGET (object);
gsk_render_node_unref (self->node);
G_OBJECT_CLASS (node_widget_parent_class)->dispose (object);
}
static void
node_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
NodeWidget *self = NODE_WIDGET (widget);
gtk_snapshot_append_node (snapshot, self->node);
}
static void
node_widget_class_init (NodeWidgetClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = node_widget_dispose;
widget_class->snapshot = node_widget_snapshot;
}
GtkWidget *
node_widget_new (const char *resource)
{
NodeWidget *self;
GBytes *bytes;
GskRenderNode *node;
graphene_rect_t bounds;
float scale;
GskTransform *transform;
self = g_object_new (NODE_TYPE_WIDGET, NULL);
bytes = g_resources_lookup_data (resource, 0, NULL);
node = gsk_render_node_deserialize (bytes, NULL, NULL);
g_bytes_unref (bytes);
gsk_render_node_get_bounds (node, &bounds);
scale = MIN (100.0/bounds.size.width, 100.0/bounds.size.height);
transform = gsk_transform_scale (NULL, scale, scale);
self->node = gsk_transform_node_new (node, transform);
gsk_transform_unref (transform);
gsk_render_node_unref (node);
return GTK_WIDGET (self);
}

View File

@@ -1,8 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#define NODE_TYPE_WIDGET (node_widget_get_type ())
G_DECLARE_FINAL_TYPE (NodeWidget, node_widget, NODE, WIDGET, GtkWidget)
GtkWidget * node_widget_new (const char *resource);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -53,9 +53,7 @@ gtk_nuclear_snapshot (GtkSnapshot *snapshot,
double rotation)
{
#define RADIUS 0.3
GskPathBuilder *builder;
GskPath *path;
GskStroke *stroke;
cairo_t *cr;
double size;
gtk_snapshot_append_color (snapshot,
@@ -63,29 +61,24 @@ gtk_nuclear_snapshot (GtkSnapshot *snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height));
size = MIN (width, height);
cr = gtk_snapshot_append_cairo (snapshot,
&GRAPHENE_RECT_INIT ((width - size) / 2.0,
(height - size) / 2.0,
size, size));
gdk_cairo_set_source_rgba (cr, foreground);
cairo_translate (cr, width / 2.0, height / 2.0);
cairo_scale (cr, size, size);
cairo_rotate (cr, rotation);
gtk_snapshot_save (snapshot);
cairo_arc (cr, 0, 0, 0.1, - G_PI, G_PI);
cairo_fill (cr);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (width / 2.0, height / 2.0));
gtk_snapshot_scale (snapshot, size, size);
gtk_snapshot_rotate (snapshot, rotation);
cairo_set_line_width (cr, RADIUS);
cairo_set_dash (cr, (double[1]) { RADIUS * G_PI / 3 }, 1, 0.0);
cairo_arc (cr, 0, 0, RADIUS, - G_PI, G_PI);
cairo_stroke (cr);
builder = gsk_path_builder_new ();
gsk_path_builder_add_circle (builder, graphene_point_zero (), 0.1);
path = gsk_path_builder_free_to_path (builder);
gtk_snapshot_append_fill (snapshot, path, GSK_FILL_RULE_WINDING, foreground);
gsk_path_unref (path);
stroke = gsk_stroke_new (RADIUS);
gsk_stroke_set_dash (stroke, (float[1]) { RADIUS * G_PI / 3 }, 1);
builder = gsk_path_builder_new ();
gsk_path_builder_add_circle (builder, graphene_point_zero(), RADIUS);
path = gsk_path_builder_free_to_path (builder);
gtk_snapshot_append_stroke (snapshot, path, stroke, foreground);
gsk_path_unref (path);
gsk_stroke_free (stroke);
gtk_snapshot_restore (snapshot);
cairo_destroy (cr);
}
/* Here, we implement the functionality required by the GdkPaintable interface */

View File

@@ -1,4 +1,5 @@
#pragma once
#ifndef __PAINTABLE_H__
#define __PAINTABLE_H__
#include <gtk/gtk.h>
@@ -12,3 +13,5 @@ void gtk_nuclear_snapshot (GtkSnapshot *snapshot,
GdkPaintable * gtk_nuclear_icon_new (double rotation);
GdkPaintable * gtk_nuclear_animation_new (gboolean draw_background);
GtkMediaStream *gtk_nuclear_media_stream_new (void);
#endif /* __PAINTABLE_H__ */

View File

@@ -70,7 +70,7 @@ gtk_nuclear_animation_snapshot (GdkPaintable *paintable,
? &(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 } /* yellow */
: &(GdkRGBA) { 0, 0, 0, 0 }, /* transparent */
width, height,
360 * nuclear->progress / MAX_PROGRESS);
2 * G_PI * nuclear->progress / MAX_PROGRESS);
}
static GdkPaintable *
@@ -85,7 +85,7 @@ gtk_nuclear_animation_get_current_image (GdkPaintable *paintable)
* Luckily we added the rotation property to the nuclear icon
* object previously, so we can just return an instance of that one.
*/
return gtk_nuclear_icon_new (360 * nuclear->progress / MAX_PROGRESS);
return gtk_nuclear_icon_new (2 * G_PI * nuclear->progress / MAX_PROGRESS);
}
static GdkPaintableFlags

View File

@@ -76,7 +76,7 @@ gtk_nuclear_media_stream_snapshot (GdkPaintable *paintable,
&(GdkRGBA) { 0, 0, 0, 1 }, /* black */
&(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 }, /* yellow */
width, height,
360 * nuclear->progress / DURATION);
2 * G_PI * nuclear->progress / DURATION);
}
static GdkPaintable *
@@ -85,7 +85,7 @@ gtk_nuclear_media_stream_get_current_image (GdkPaintable *paintable)
GtkNuclearMediaStream *nuclear = GTK_NUCLEAR_MEDIA_STREAM (paintable);
/* Same thing as with the animation */
return gtk_nuclear_icon_new (360 * nuclear->progress / DURATION);
return gtk_nuclear_icon_new (2 * G_PI * nuclear->progress / DURATION);
}
static GdkPaintableFlags

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