Compare commits

..

1 Commits

Author SHA1 Message Date
Matthias Clasen
39d689a170 Add a reverse list model
This is a simple wrapper list model that reverses
the order of items in the child model.
2020-09-07 22:05:11 -04:00
2946 changed files with 343940 additions and 391892 deletions

View File

@@ -1,13 +1,8 @@
include:
- project: 'gnome/citemplates'
file: 'flatpak/flatpak_ci_initiative.yml'
stages:
- build
- analysis
- docs
- flatpak
- publish
- deploy
.cache-paths: &cache-paths
@@ -21,12 +16,13 @@ stages:
# Common variables
variables:
COMMON_MESON_FLAGS: "-Dwerror=true -Dglib:werror=false -Dpango:werror=false -Dgtk-doc:werror=false -Dwayland-protocols:werror=false -Dsysprof:werror=false"
COMMON_MESON_FLAGS: "--fatal-meson-warnings -Dgtk:werror=true"
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v34"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v22"
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v19"
.only-default:
only:
@@ -43,7 +39,6 @@ style-check-diff:
- .gitlab-ci/run-style-check-diff.sh
.build-fedora-default:
extends: .only-default
image: $FEDORA_IMAGE
artifacts:
when: always
@@ -58,10 +53,8 @@ style-check-diff:
- "${CI_PROJECT_DIR}/_build/report*.xml"
- "${CI_PROJECT_DIR}/_build/report*.html"
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.png"
- "${CI_PROJECT_DIR}/_build/testsuite/tools/output/*/*"
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
- "${CI_PROJECT_DIR}/_build_hello/meson-logs"
cache:
key: "$CI_JOB_NAME"
paths:
@@ -79,16 +72,11 @@ fedora-x86_64:
variables:
EXTRA_MESON_FLAGS: "--buildtype=debug --default-library=both"
script:
- .gitlab-ci/show-info-linux.sh
- meson subprojects update
- mkdir _install
- meson --prefix=${CI_PROJECT_DIR}/_install
${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
-Dsysprof=enabled
_build
- meson compile -C _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
- meson compile -C _build_hello
- ninja -C _build
- .gitlab-ci/run-tests.sh _build x11
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build broadway
@@ -100,7 +88,6 @@ release-build:
variables:
EXTRA_MESON_FLAGS: "--buildtype=release"
script:
- .gitlab-ci/show-info-linux.sh
- meson subprojects update
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
_build
@@ -113,9 +100,7 @@ installed-tests:
needs: []
variables:
EXTRA_MESON_FLAGS: "--prefix=/usr --libdir=/usr/lib64 -Dinstall-tests=true"
G_TEST_ACCESSIBLE: 1
script:
- .gitlab-ci/show-info-linux.sh
- meson subprojects update
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
_build
@@ -132,7 +117,6 @@ installed-tests:
.mingw-defaults:
extends: .only-default
stage: build
tags:
- win32-ps
@@ -156,51 +140,6 @@ msys2-mingw64:
MSYSTEM: "MINGW64"
CHERE_INVOKING: "yes"
macos:
extends: .only-default
only:
- branches@GNOME/gtk
stage: build
tags:
- macos
needs: []
before_script:
- bash .gitlab-ci/show-info-osx.sh
- pip3 install --user meson==0.56
- pip3 install --user ninja
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
- export MESON_FORCE_BACKTRACE=1
script:
- meson -Dx11-backend=false
-Dbroadway-backend=true
-Dmacos-backend=true
-Dmedia-gstreamer=disabled
-Dintrospection=disabled
-Dcpp_std=c++11
-Dpixman:tests=disabled
_build
- ninja -C _build
artifacts:
when: always
paths:
- "${CI_PROJECT_DIR}/_build/meson-logs"
vs2017-x64:
extends: .only-default
# TODO: Uncomment this when ready to merge.
#only:
# - branches@GNOME/gtk
stage: build
tags:
- win32-ps
needs: []
script:
- .gitlab-ci/test-msvc.bat
artifacts:
when: always
paths:
- "${CI_PROJECT_DIR}/_build/meson-logs"
.flatpak-defaults:
image: $FLATPAK_IMAGE
stage: flatpak
@@ -210,7 +149,6 @@ vs2017-x64:
artifacts:
paths:
- "${APPID}-dev.flatpak"
- 'repo.tar'
expire_in: 1 day
script:
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
@@ -262,24 +200,6 @@ flatpak-master:icon-browser:
variables:
APPID: org.gtk.IconBrowser4
# Publish the demo apps to the GNOME Nightly repo
# https://wiki.gnome.org/Apps/Nightly
# https://gitlab.gnome.org/GNOME/Initiatives/-/wikis/DevOps-with-Flatpak
nightly demo:
extends: '.publish_nightly'
dependencies: ['flatpak-master:demo']
needs: ['flatpak-master:demo']
nightly factory:
extends: '.publish_nightly'
dependencies: ['flatpak-master:widget-factory']
needs: ['flatpak-master:widget-factory']
nightly icon-browser:
extends: '.publish_nightly'
dependencies: ['flatpak-master:icon-browser']
needs: ['flatpak-master:icon-browser']
static-scan:
image: $FEDORA_IMAGE
stage: analysis
@@ -303,7 +223,7 @@ asan-build:
needs: []
variables:
script:
- CC=clang meson --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=disabled _build
- CC=clang meson --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=false _build
- ninja -C _build
- .gitlab-ci/run-tests.sh _build wayland
artifacts:
@@ -312,37 +232,29 @@ asan-build:
allow_failure: true
reference:
image: $FEDORA_IMAGE
image: $DOCS_IMAGE
stage: docs
needs: []
variables:
EXTRA_MESON_FLAGS: "--buildtype=release --force-fallback-for=gdk-pixbuf,pango"
EXTRA_MESON_FLAGS: "--buildtype=release"
script:
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} -Dgtk_doc=true -Dgdk-pixbuf:gtk_doc=true -Dpango:gtk_doc=true _build
- meson compile -C _build
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} -Dgtk_doc=true _build
- ninja -C _build gdk4-doc gsk4-doc gtk4-doc
- mkdir -p _reference/
- mv _build/docs/reference/gdk/gdk4/ _reference/gdk4/
- mv _build/docs/reference/gdk/gdk4-x11/ _reference/gdk4-x11/
- 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/subprojects/pango/docs/Pango/ _reference/Pango/
- mv _build/subprojects/pango/docs/PangoCairo/ _reference/PangoCairo/
- mv _build/subprojects/pango/docs/PangoFc/ _reference/PangoFc/
- mv _build/subprojects/pango/docs/PangoFT2/ _reference/PangoFT2/
- mv _build/subprojects/pango/docs/PangoOT/ _reference/PangoOT/
- mv _build/subprojects/pango/docs/PangoXft/ _reference/PangoXft/
- mv _build/subprojects/gdk-pixbuf/docs/gdk-pixbuf/ _reference/gdk-pixbuf/
- mv _build/subprojects/gdk-pixbuf/docs/gdk-pixdata/ _reference/gdk-pixdata/
- mv _build/docs/reference/gdk/html/ _reference/gdk/
- mv _build/docs/reference/gsk/html/ _reference/gsk/
- mv _build/docs/reference/gtk/html/ _reference/gtk/
artifacts:
paths:
- _reference
publish-docs:
stage: publish
pages:
stage: deploy
needs: ['reference']
script:
- "curl -X POST -F token=${PAGES_TRIGGER_TOKEN} -F ref=docs-gtk-org https://gitlab.gnome.org/api/v4/projects/665/trigger/pipeline"
- mv _reference/ public/
artifacts:
paths:
- public
only:
refs:
- master
- master

View File

@@ -17,8 +17,8 @@ branch, as well as their available versions.
### Checklist for Updating a CI image
- [ ] Update the `${image}.Dockerfile` file with the dependencies
- [ ] Run `./run-docker.sh build --base ${image} --version ${number}`
- [ ] Run `./run-docker.sh push --base ${image} --version ${number}`
- [ ] Run `./run-docker.sh build --base ${image} --base-version ${number}`
- [ ] Run `./run-docker.sh push --base ${image} --base-version ${number}`
once the Docker image is built; you may need to log in by using
`docker login` or `podman login`
- [ ] Update the `image` keys in the `.gitlab-ci.yml` file with the new
@@ -30,8 +30,8 @@ branch, as well as their available versions.
- [ ] Write a new `${image}.Dockerfile` with the instructions to set up
a build environment
- [ ] Add the `pip3 install meson` incantation
- [ ] Run `./run-docker.sh build --base ${image} --version ${number}`
- [ ] Run `./run-docker.sh push --base ${image} --version ${number}`
- [ ] Run `./run-docker.sh build --base ${image} --base-version ${number}`
- [ ] Run `./run-docker.sh push --base ${image} --base-version ${number}`
- [ ] Add the new job to `.gitlab-ci.yml` referencing the image
- [ ] Open a merge request with your changes and let it run

View File

@@ -0,0 +1,90 @@
FROM fedora:31
RUN dnf -y install \
adwaita-icon-theme \
atk-devel \
at-spi2-atk-devel \
avahi-gobject-devel \
cairo-devel \
cairo-gobject-devel \
ccache \
clang \
clang-analyzer \
colord-devel \
cups-devel \
dbus-daemon \
dbus-x11 \
dejavu-sans-mono-fonts \
desktop-file-utils \
diffutils \
elfutils-libelf-devel \
fribidi-devel \
gcc \
gcc-c++ \
gdk-pixbuf2-devel \
gdk-pixbuf2-modules \
gettext \
git \
glib2-devel \
glib2-static \
glibc-devel \
glibc-headers \
gnome-desktop-testing \
gobject-introspection-devel \
graphene-devel \
gstreamer1-devel \
gstreamer1-plugins-good \
gstreamer1-plugins-bad-free-devel \
gstreamer1-plugins-base-devel \
gtk-doc \
hicolor-icon-theme \
iso-codes \
itstool \
json-glib-devel \
lcov \
libasan \
libattr-devel \
libepoxy-devel \
libffi-devel \
libmount-devel \
librsvg2 \
libselinux-devel \
libubsan \
libXcomposite-devel \
libXcursor-devel \
libXcursor-devel \
libXdamage-devel \
libXfixes-devel \
libXi-devel \
libXinerama-devel \
libxkbcommon-devel \
libXrandr-devel \
libXrender-devel \
libXtst-devel \
libxslt \
mesa-dri-drivers \
mesa-libEGL-devel \
mesa-libwayland-egl-devel \
ninja-build \
pango-devel \
pcre-devel \
pcre-static \
python3 \
python3-jinja2 \
python3-pip \
python3-pygments \
python3-wheel \
redhat-rpm-config \
sassc \
systemtap-sdt-devel \
vulkan-devel \
wayland-devel \
wayland-protocols-devel \
weston \
weston-libs \
which \
xorg-x11-server-Xvfb \
&& dnf clean all
RUN pip3 install meson==0.53.1

View File

@@ -0,0 +1,12 @@
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v19
RUN dnf -y install pandoc
ARG HOST_USER_ID=5555
ENV HOST_USER_ID ${HOST_USER_ID}
RUN useradd -u $HOST_USER_ID -ms /bin/bash user
USER user
WORKDIR /home/user
ENV LANG C.UTF-8

View File

@@ -1,100 +1,4 @@
FROM fedora:34
RUN dnf -y install \
adwaita-icon-theme \
atk-devel \
at-spi2-atk-devel \
avahi-gobject-devel \
cairo-devel \
cairo-gobject-devel \
ccache \
clang \
clang-analyzer \
clang-tools-extra \
colord-devel \
cups-devel \
dbus-daemon \
dbus-x11 \
dejavu-sans-mono-fonts \
desktop-file-utils \
diffutils \
elfutils-libelf-devel \
fribidi-devel \
gcc \
gcc-c++ \
gdk-pixbuf2-devel \
gdk-pixbuf2-modules \
gettext \
git \
glib2-devel \
glib2-static \
glibc-devel \
glibc-headers \
gnome-desktop-testing \
gobject-introspection-devel \
graphene-devel \
graphviz \
gstreamer1-devel \
gstreamer1-plugins-good \
gstreamer1-plugins-bad-free-devel \
gstreamer1-plugins-base-devel \
hicolor-icon-theme \
iso-codes \
itstool \
json-glib-devel \
lcov \
libasan \
libattr-devel \
libcloudproviders-devel \
libepoxy-devel \
libffi-devel \
libjpeg-turbo-devel \
libmount-devel \
libpng-devel \
librsvg2 \
libselinux-devel \
libtiff-devel \
libubsan \
libXcomposite-devel \
libXcursor-devel \
libXcursor-devel \
libXdamage-devel \
libXfixes-devel \
libXi-devel \
libXinerama-devel \
libxkbcommon-devel \
libXrandr-devel \
libXrender-devel \
libXtst-devel \
libxslt \
mesa-dri-drivers \
mesa-libEGL-devel \
mesa-libGLES-devel \
meson \
ninja-build \
pango-devel \
pcre-devel \
pcre-static \
python3 \
python3-gobject \
python3-jinja2 \
python3-markdown \
python3-pip \
python3-pygments \
python3-toml \
python3-typogrify \
python3-wheel \
redhat-rpm-config \
sassc \
systemtap-sdt-devel \
vulkan-devel \
wayland-devel \
wayland-protocols-devel \
weston \
weston-libs \
which \
xorg-x11-server-Xvfb \
&& dnf clean all
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v21
# Enable sudo for wheel users
RUN sed -i -e 's/# %wheel/%wheel/' -e '0,/%wheel/{s/%wheel/# %wheel/}' /etc/sudoers

View File

@@ -22,9 +22,8 @@ flatpak build ${builddir} meson \
-Dprint-backends=file \
-Dbuild-tests=false \
-Dbuild-examples=false \
-Dintrospection=disabled \
-Dintrospection=false \
-Ddemos=true \
-Dprofile=devel \
_flatpak_build
flatpak build ${builddir} ninja -C _flatpak_build install
@@ -41,8 +40,3 @@ flatpak build-bundle \
${appid}-dev.flatpak \
--runtime-repo=https://nightly.gnome.org/gnome-nightly.flatpakrepo \
${appid}
# to be consumed by the nightly publish jobs
if [[ $CI_COMMIT_BRANCH == master ]]; then
tar cf repo.tar ${repodir}
fi

View File

@@ -1,154 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021 GNOME Foundation
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
/**
* RedHat Fonts taken from https://github.com/RedHatOfficial/RedHatFont
* License: SIL Open Font License 1.1 http://scripts.sil.org/OFL
*/
@import url('https://fonts.googleapis.com/css2?family=Noto+Serif:ital,wght@0,400;0,700;1,400;1,700&family=Red+Hat+Display:ital,wght@0,400;0,500;0,700;0,900;1,400;1,500;1,700;1,900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Noto+Serif:ital,wght@0,400;0,700;1,400;1,700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600&display=swap');
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-Regular.woff2") format("woff2"),
url("RedHatDisplay-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
font-display: fallback;
}
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-RegularItalic.woff2") format("woff2"),
url("RedHatDisplay-RegularItalic.woff") format("woff");
font-style: italic;
font-weight: 400;
font-display: fallback;
}
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-Medium.woff2") format("woff2"),
url("RedHatDisplay-Medium.woff") format("woff");
font-style: normal;
font-weight: 500;
font-display: fallback;
}
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-MediumItalic.woff2") format("woff2"),
url("RedHatDisplay-MediumItalic.woff") format("woff");
font-style: italic;
font-weight: 500;
font-display: fallback;
}
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-Bold.woff2") format("woff2"),
url("RedHatDisplay-Bold.woff") format("woff");
font-style: normal;
font-weight: 700;
font-display: fallback;
}
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-BoldItalic.woff2") format("woff2"),
url("RedHatDisplay-BoldItalic.woff") format("woff");
font-style: italic;
font-weight: 700;
font-display: fallback;
}
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-Black.woff2") format("woff2"),
url("RedHatDisplay-Black.woff") format("woff");
font-style: normal;
font-weight: 900;
font-display: fallback;
}
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-BlackItalic.woff2") format("woff2"),
url("RedHatDisplay-BlackItalic.woff") format("woff");
font-style: italic;
font-weight: 900;
font-display: fallback;
}
@font-face {
font-family: "RedHatTextWeb";
src: local('RedHatTextWeb'),
url("RedHatText-Regular.woff2") format("woff2"),
url("RedHatText-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
font-display: fallback;
}
@font-face {
font-family: "RedHatTextWeb";
src: local('RedHatTextWeb'),
url("RedHatText-RegularItalic.woff2") format("woff2"),
url("RedHatText-RegularItalic.woff") format("woff");
font-style: italic;
font-weight: 400;
font-display: fallback;
}
@font-face {
font-family: "RedHatTextWeb";
src: local('RedHatTextWeb'),
url("RedHatText-Medium.woff2") format("woff2"),
url("RedHatText-Medium.woff") format("woff");
font-style: normal;
font-weight: 700;
font-display: fallback;
}
@font-face {
font-family: "RedHatTextWeb";
src: local('RedHatTextWeb'),
url("RedHatText-MediumItalic.woff2") format("woff2"),
url("RedHatText-MediumItalic.woff") format("woff");
font-style: italic;
font-weight: 700;
font-display: fallback;
}
@font-face {
font-family: "RedHatTextWeb";
src: local('RedHatTextWeb'),
url("RedHatText-Bold.woff2") format("woff2"),
url("RedHatText-Bold.woff") format("woff");
font-style: normal;
font-weight: 900;
font-display: fallback;
}
@font-face {
font-family: "RedHatTextWeb";
src: local('RedHatTextWeb'),
url("RedHatText-BoldItalic.woff2") format("woff2"),
url("RedHatText-BoldItalic.woff") format("woff");
font-style: italic;
font-weight: 900;
font-display: fallback;
}

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

@@ -1,149 +0,0 @@
<!--
SPDX-FileCopyrightText: 2021 GNOME Foundation
SPDX-License-Identifier: LGPL-2.1-or-later
-->
<!DOCTYPE html>
<html lang="en">
<head>
<title>GTK Documentation</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8" />
<meta property="og:site_name" content="https://docs.gtk.org"/>
<meta property="og:title" content="GTK Documentation"/>
<meta property="og:url" content="https://docs.gtk.org"/>
<meta property="og:type" content="website"/>
<meta property="og:description" content="API reference for GTK"/>
<meta name="twitter:title" content="GTK Documentation"/>
<meta name="twitter:url" content="https://docs.gtk.org"/>
<meta name="twitter:card" content="summary"/>
<link rel="canonical" href="https://docs.gtk.org"/>
<link rel="stylesheet" href="style.css" type="text/css" />
<script src="main.js"></script>
<!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
</head>
<body>
<div id="body-wrapper" tabindex="-1">
<nav class="sidebar">
<div class="section">
<img src="gtk-logo.svg" class="logo"/>
</div>
<div class="section">
<h5>Sections</h5>
<div class="links">
<a href="#user-interface">User interface</a>
<a href="#core-libraries">Core libraries</a>
</div>
</div>
</nav>
<button id="btn-to-top" class="hidden"><span class="up-arrow"></span></button>
<section id="main" class="content">
<header>
<h1>GTK Documentation</h1>
</header>
<div class="toggle-wrapper">
<h4 id="user-interface">
User interface
<a href="#user-interface" class="anchor"></a>
</h4>
<div class="docblock">
<h5 id="gdk">GTK</h5>
<p>GTK is the primary library used to construct user interfaces. It
provides user interface controls and signal callbacks to respond to
user actions.</p>
<p><a href="https://docs.gtk.org/gtk4/">GTK API reference</a></p>
</div>
<div class="docblock">
<h5 id="gdk">GSK</h5>
<p>An intermediate layer which provides a rendering API implemented using Cairo, OpenGL or Vulkan.</p>
<p><a href="https://docs.gtk.org/gsk4/">GSK API reference</a></p>
</div>
<div class="docblock">
<h5 id="gdk">GDK</h5>
<p>An intermediate layer which isolates GTK from the details of the windowing system.</p>
<p><a href="https://docs.gtk.org/gdk4/">GDK API reference</a></p>
</div>
<div class="docblock">
<h5 id="pango">Pango</h5>
<p>Pango is the core text and font handling library used in GTK
applications. It has extensive support for the different writing
systems used throughout the world.</p>
<p><a href="https://docs.gtk.org/Pango/">Pango API reference</a></p>
</div>
<div class="docblock">
<h5 id="gdk-pixbuf">GdkPixbuf</h5>
<p>GdkPixbuf is a library for image loading and manipulation.</p>
<p><a href="https://docs.gtk.org/gdk-pixbuf/">GdkPixbuf API reference</a></p>
</div>
<div class="docblock">
<h5 id="cairo">Cairo</h5>
<p>Cairo is a 2D graphics library with support for multiple output
devices. It is designed to produce consistent, high quality output
on all media.</p>
<p><a href="https://www.cairographics.org/manual/" class="external">Cairo API reference</a></p>
</div>
</div>
<div class="toggle-wrapper">
<h4 id="core-libraries" style="display:flex;">
Core libraries
<a href="#core-libraries" class="anchor"></a>
</h4>
<div class="docblock">
<h5 id="glib">GLib</h5>
<p>GLib provides the core application building blocks for libraries
and applications written in C. It provides common data types
used in GTK, the main loop implementation, and a large set of
utility functions for strings and general portability across
different platforms.</p>
<p><a href="https://developer.gnome.org/glib/" class="external">GLib API reference</a></p>
</div>
<div class="docblock">
<h5 id="gobject">GObject</h5>
<p>GObject provides the object system used by GTK.</p>
<p><a href="https://developer.gnome.org/gobject/" class="external">GObject API reference</a></p>
</div>
<div class="docblock">
<h5 id="gio">GIO</h5>
<p>GIO provides a portable, modern and easy-to-use file system
abstraction API for accessing local and remote files; a set of
low and high level abstractions over the <a href="https://www.freedesktop.org/wiki/Software/dbus/" class="external">DBus</a>
IPC specification; an application settings API; portable networking
abstractions; and additional utilities for writing asynchronous
operations without blocking the user interface of your application.</p>
<p><a href="https://developer.gnome.org/gio/" class="external">GIO API reference</a></p>
</div>
</div>
</section>
<footer>
</footer>
</div>
</body>
</html>

View File

@@ -1,140 +0,0 @@
// SPDX-FileCopyrightText: 2021 GNOME Foundation
//
// SPDX-License-Identifier: LGPL-2.1-or-later
// eslint-disable-next-line no-unused-vars
function hasClass(elem, className) {
return elem && elem.classList && elem.classList.contains(className);
}
// eslint-disable-next-line no-unused-vars
function addClass(elem, className) {
if (!elem || !elem.classList) {
return;
}
elem.classList.add(className);
}
// eslint-disable-next-line no-unused-vars
function removeClass(elem, className) {
if (!elem || !elem.classList) {
return;
}
elem.classList.remove(className);
}
function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
function onEach(arr, func, reversed) {
if (arr && arr.length > 0 && func) {
var length = arr.length;
var i;
if (reversed !== true) {
for (i = 0; i < length; ++i) {
if (func(arr[i]) === true) {
return true;
}
}
} else {
for (i = length - 1; i >= 0; --i) {
if (func(arr[i]) === true) {
return true;
}
}
}
}
return false;
}
function onEachLazy(lazyArray, func, reversed) {
return onEach(
Array.prototype.slice.call(lazyArray),
func,
reversed);
}
// eslint-disable-next-line no-unused-vars
function hasOwnProperty(obj, property) {
return Object.prototype.hasOwnProperty.call(obj, property);
}
window.addEventListener("load", function() {
"use strict;"
var main = document.getElementById("main");
var btnToTop = document.getElementById("btn-to-top");
function labelForToggleButton(isCollapsed) {
if (isCollapsed) {
return "+";
}
return "\u2212";
}
function createToggle(isCollapsed) {
var toggle = document.createElement("a");
toggle.href = "javascript:void(0)";
toggle.className = "collapse-toggle";
toggle.innerHTML = "[<span class=\"inner\">"
+ labelForToggleButton(isCollapsed)
+ "</span>]";
return toggle;
}
function toggleClicked() {
if (hasClass(this, "collapsed")) {
removeClass(this, "collapsed");
this.innerHTML = "[<span class=\"inner\">"
+ labelForToggleButton(false)
+ "</span>]";
onEachLazy(this.parentNode.getElementsByClassName("docblock"), function(e) {
removeClass(e, "hidden");
});
} else {
addClass(this, "collapsed");
this.innerHTML = "[<span class=\"inner\">"
+ labelForToggleButton(true)
+ "</span>]";
onEachLazy(this.parentNode.getElementsByClassName("docblock"), function(e) {
addClass(e, "hidden");
});
}
}
onEachLazy(document.getElementsByClassName("toggle-wrapper"), function(e) {
let sectionHeader = e.querySelector(".section-header");
let fragmentMatches = sectionHeader !== null && location.hash === "#" + sectionHeader.getAttribute('id');
collapsedByDefault = hasClass(e, "default-hide") && !fragmentMatches;
var toggle = createToggle(collapsedByDefault);
toggle.onclick = toggleClicked;
e.insertBefore(toggle, e.firstChild);
if (collapsedByDefault) {
addClass(toggle, "collapsed");
onEachLazy(e.getElementsByClassName("docblock"), function(d) {
addClass(d, "hidden");
});
}
});
function scrollBackTop(e) {
e.preventDefault();
window.scroll({
top: 0,
behavior: 'smooth',
});
}
function toggleScrollButton() {
if (window.scrollY < 400) {
addClass(btnToTop, "hidden");
} else {
removeClass(btnToTop, "hidden");
}
}
window.onscroll = toggleScrollButton;
btnToTop.onclick = scrollBackTop;
}, false);

View File

@@ -1,747 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021 GNOME Foundation
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
@import url("fonts.css");
/*********************************
* LIGHT THEME
*********************************/
:root {
/* colors */
--text-color: #333;
--text-color-muted: #999;
--primary: rgb(28, 118, 228);
--body-bg: #fff;
--sidebar-primary: rgb(144, 194, 255);
--sidebar-bg: #151515;
--sidebar-selected-bg: var(--primary);
--sidebar-text-color: #fafafa;
--sidebar-padding: 1.5em;
/* boxes, e.g. code blocks */
--box-bg: rgba(135, 135, 135, 0.085);
--box-radius: 0.35rem;
--box-padding: 0.75rem;
--box-margin: 0.75rem 0;
--box-text-color: #111;
/* typography */
--body-font-family: "Noto Serif",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
--body-font-scale: 0.95;
--body-font-size: calc(var(--body-font-scale) * clamp(16px, 1vw, 20px));
--body-font-weight: normal;
--monospace-font-family: "Source Code Pro", monospace;
--monospace-font-size: calc(0.86 * var(--body-font-size)); /* Monospace fonts are very different in terms of font-sizes. Adjust this value to scale it */
--heading-font-family: "Red Hat Display", var(--body-font-family);
--heading-weight: 900;
--heading-font-scale: 1.05;
--heading-small-font-family: var(--heading-font-family);
--heading-small-weight: 600;
--heading-small-font-scale: 1;
--heading-table-font-family: var(--heading-font-family);
--heading-table-weight: 600;
--heading-docblock-color: #6d6d6d; /* docblocks have headings from source comments. we want them to differ.*/
--heading-docblock-scale: 0.9; /* docblocks have headings from source comments. we want them to differ.*/
--symbol-font-family: var(--heading-font-family);
--symbol-font-weight: 500;
--symbol-font-scale: 1;
--table-font-size: 0.92em; /* Tables often contain lots information. It's better to scale them down a big to get more sutff fitted inside */
/* misc */
--prefered-content-width: 90ch; /* The preferred width for the readable content */
--anchor-sign: "#";
}
/*********************************
* DARK THEME (overrides)
*********************************/
@media (prefers-color-scheme: dark) {
:root {
--primary: rgb(144, 194, 255);
--text-color: #f6f6f6;
--text-color-muted: #686868;
--body-bg: #121212;
--sidebar-primary: rgb(144, 194, 255);
--sidebar-bg: #1e1e1e;
--sidebar-selected-bg: rgb(17, 112, 228);
--sidebar-text-color: #fafafa;
--box-bg: rgba(135, 135, 135, 0.1);
--box-text-color: #fff;
--heading-docblock-color: #b7b7b7;
}
/* fix dark theme syntax highlighting with a filter (for now) */
.highlight pre span {
filter: brightness(6);
}
}
/*********************************
* GENERAL STYLING
*********************************/
*,
*:before,
*:after {
box-sizing: border-box;
}
::-moz-selection {
color: white;
background: var(--primary);
}
::selection {
color: white;
background: var(--primary);
}
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background: rgba(128, 128, 128, 0.6);
}
::-webkit-scrollbar-thumb:hover {
background: rgba(128, 128, 128, 1);
}
::-webkit-scrollbar-track {
background: rgba(128, 128, 128, 0.15);
}
* {
scrollbar-width: initial;
}
body {
font: 16px/1.5 var(--body-font-family);
font-weight: var(--body-font-weight);
font-size: var(--body-font-size);
margin: 0;
padding: 0;
position: relative;
-webkit-font-feature-settings: "kern", "liga";
-moz-font-feature-settings: "kern", "liga";
font-feature-settings: "kern", "liga";
color: var(--text-color);
background: var(--body-bg);
}
h1, h2, h3, h4, h5, h6 {
font-family: var(--heading-font-family);
font-weight: var(--heading-weight);
margin: 1.75em 0 0.75em 0;
display: flex;
align-items: center;
}
h1 {
font-size: calc(1.75em * var(--heading-font-scale));
}
header h1 {
margin-top: 0;
}
h2 {
font-size: calc(1.4em * var(--heading-font-scale));
}
h3 {
font-size: calc(1.2em * var(--heading-font-scale));
}
header h3 {
color: var(--text-color-muted);
margin-bottom: 0;
}
h4, h5 {
font-size: calc(1em * var(--heading-font-scale));
}
h6 {
font-size: calc(1em * var(--heading-small-font-scale));
font-family: var(--heading-small-font-family);
font-weight: var(--heading-small-weight);
}
ol, ul {
padding-left: 1rem;
}
ul ul, ol ul, ul ol, ol ol {
margin-bottom: .6em;
}
p {
margin: 0 0 .6em 0;
}
a {
color: var(--primary);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
summary {
outline: none;
}
blockquote {
border-left: 3px solid var(--primary);
background: var(--box-bg);
padding: var(--box-padding);
border-radius: var(--box-radius);
margin: var(--box--margin);
}
code,
pre {
font-family: var(--monospace-font-family);
font-size: var(--monospace-font-size);
color: var(--box-text-color);
}
pre {
background: var(--box-bg);
padding: var(--box-padding);
border-radius: var(--box-radius);
overflow: auto;
}
code {
background: var(--box-bg);
padding: 0 0.35em;
border-radius: 0.35rem;
word-break: break-word;
}
a > code {
color: var(--primary);
}
pre pre,
pre code {
padding: 0;
margin: 0;
font-size: 1em;
background: none;
color: inherit;
}
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
font-family: inherit;
font-weight: inherit;
font-size: 0.85em;
}
strong, b {
font-weight: 600;
}
/* fix unwanted margins in tables, code, lists and blockquotes */
li > *:first-child,
li > *:first-child > *:first-child,
li > *:first-child > *:first-child > *:first-child,
td > *:first-child,
td > *:first-child > *:first-child,
td > *:first-child > *:first-child > *:first-child,
pre > *:first-child,
pre > *:first-child > *:first-child,
pre > *:first-child > *:first-child > *:first-child,
blockquote > *:first-child,
blockquote > *:first-child > *:first-child,
blockquote > *:first-child > *:first-child > *:first-child {
margin-top: 0;
}
li > *:last-child,
li > *:last-child > *:last-child,
li > *:last-child > *:last-child > *:last-child,
td > *:last-child,
td > *:last-child > *:last-child,
td > *:last-child > *:last-child > *:last-child,
pre > *:last-child,
pre > *:last-child > *:last-child,
pre > *:last-child > *:last-child > *:last-child,
blockquote > *:last-child,
blockquote > *:last-child > *:last-child,
blockquote > *:last-child > *:last-child > *:last-child {
margin-bottom: 0;
}
/*********************************
* PAGE STRUCTURE
*********************************/
#body-wrapper {
display: flex;
flex-wrap: nowrap;
flex-direction: row;
}
#body-wrapper:focus {
outline: none;
}
#main {
position: relative;
flex-grow: 1;
min-width: 0;
box-shadow: 0 0 134px rgba(0, 0, 0, 0.1);
}
footer {
width: 100%;
display: none;
}
/*********************************
* Button
*********************************/
#btn-to-top {
position: fixed;
bottom: 12px;
right: 32px;
z-index: 1000;
border-radius: 50%;
width: 42px;
height: 42px;
border: 1px solid var(--primary);
background: var(--box-bg);
color: var(--text-color);
cursor: pointer;
text-transform: none;
}
#btn-to-top > .up-arrow:after {
content: "🡅"
}
/*********************************
* SIDEBAR
*********************************/
.sidebar {
scrollbar-width: thin;
background: var(--sidebar-bg);
border-right: 1px solid var(--sidebar-bg);
min-width: 40ch;
padding: var(--sidebar-padding);
color: var(--sidebar-text-color);
position: sticky;
top: 0;
z-index: 2;
height: 100vh;
overflow-y: auto;
}
.sidebar a,
.sidebar a:hover {
text-decoration: none;
}
.sidebar .logo {
display: block;
margin: 2rem auto 0 auto;
width: 70%;
}
.sidebar .section > ul > li {
margin-right: -10px;
}
.sidebar .section h3, .sidebar .section h5 {
text-align: left;
padding-left: 0.5rem;
padding-right: 0.5rem;
font-weight: var(--heading-weight);
}
.sidebar .section h5 {
font-size: 1em;
margin-bottom: 0.5em;
}
.sidebar .namespace > h3 {
margin-bottom: 0;
padding: 0;
font-size: 1.5em;
text-transform: uppercase;
font-weight: 900;
}
.sidebar .namespace > p {
font-size: 0.9em;
opacity: 0.8;
padding-left: 0.5rem;
}
.sidebar .section {
padding-left: 0.5rem;
padding-right: 0.5rem;
}
.sidebar .links {
margin-bottom: 1rem;
}
.sidebar .section a {
display: block;
text-overflow: ellipsis;
overflow: hidden;
transition: background-color 150ms ease;
color: var(--sidebar-primary);
border-radius: var(--box-radius);
padding: 0.2rem 0.5rem;
margin-bottom: 0.15rem;
}
.sidebar .section a:hover {
background-color: rgba(127, 127, 127, 0.2);
color: var(--sidebar-text-color);
}
.sidebar .section a.current {
background-color: var(--sidebar-selected-bg);
color: white;
}
.sidebar .search {
box-sizing: border-box;
text-align: center;
}
.sidebar .search input[type="text"] {
border-color: transparent;
width: 100%;
border: 1px solid #ccc;
border-radius: 50px;
padding: 6px 12px;
display: inline-block;
font-size: 80%;
box-shadow: inset 0 1px 3px #ddd;
transition: border .3s linear;
}
/*********************************
* ANCHORS & TOGGLERS
*********************************/
.anchor,
.md-anchor {
position: relative;
z-index: 1;
text-decoration: none;
padding: 0 0.5em;
color: var(--text-color-muted);
}
.anchor:hover,
.md-anchor:hover {
color: var(--primary);
}
.anchor:not([href]),
.md-anchor:not([href]) {
display: none;
}
.anchor:before,
.md-anchor:before {
content: var(--anchor-sign); /*'§'*/
}
.toggle-wrapper {
position: relative;
}
.collapse-toggle {
position: absolute;
right: 0;
left: -2em;
white-space: nowrap;
text-decoration: none;
font-size: 0.8em;
color: transparent;
}
.collapse-toggle > .inner {
width: 1rem;
height: 1rem;
border-radius: calc(0.75 * var(--box-radius));
display: inline-flex;
justify-content: center;
align-items: center;
text-align: center;
vertical-align: middle;
color: var(--box-text-color);
position: relative;
left: -0.25rem;
font-family: monospace;
font-size: 0.7rem;
font-weight: bold;
background: var(--box-bg);
}
/*********************************
* UTILITY
*********************************/
.deprecated > h6 > a {
opacity: 0.65;
}
.hidden {
display: none !important;
}
/*********************************
* CONTENT STYLING
*********************************/
.content {
padding: 2em 4em;
overflow: visible;
max-width: calc(var(--prefered-content-width) + 8em);
}
.content table:not(.table-display) {
border-spacing: 0 0.25rem;
}
.content td {
vertical-align: top;
}
.content td:first-child {
padding-right: 1rem;
}
.content td p:first-child {
margin-top: 0;
}
.content td h1, .content td h2 {
margin-left: 0;
font-size: 1.1em;
}
.content tr:first-child td {
border-top: 0;
}
kbd {
display: inline-block;
padding: 3px 5px;
font: 15px monospace;
line-height: 10px;
vertical-align: middle;
border: solid 1px;
border-radius: 3px;
box-shadow: inset 0 -1px 0;
cursor: default;
}
.content tr:first-child {
border-bottom: 1px solid rgba(0, 0, 0, 0.35);
}
.content td {
vertical-align: top;
}
.content td:first-child {
padding-right: 1rem;
}
.content td p:first-child {
margin-top: 0;
}
.content td h4, .content td h5 {
margin-left: 0;
font-size: 1.1em;
}
.content tr:first-child td {
border-top: 0;
}
.srclink {
color: var(--text-color-muted);
font-size: 1rem;
font-weight: var(--body-font-weight);
flex-grow: 0;
text-decoration: none;
margin-left: auto;
position: relative;
z-index: 1;
}
.meta tr > td:not(:first-child) {
width: 100%;
}
.meta tr > td:first-child {
white-space: nowrap;
}
/*********************************
* DOCBLOCK STYLING
*********************************/
.docblock {
position: relative;
text-align: left;
}
.docblock h1 {
font-size: calc(1.3em * var(--heading-docblock-scale) * var(--heading-font-scale));
}
.docblock h2 {
font-size: calc(1.2em * var(--heading-docblock-scale) * var(--heading-font-scale));
}
.docblock h3 {
font-size: calc(1.1em * var(--heading-docblock-scale) * var(--heading-font-scale));
}
.docblock h4 {
font-size: calc(1.05em * var(--heading-docblock-scale) * var(--heading-font-scale));
}
.docblock h1,
.docblock h2,
.docblock h3,
.docblock h4,
.docblock h5,
.docblock h6 {
color: var(--heading-docblock-color)
}
.docblock table {
margin: .25em 0;
max-width: 100%;
font-size: var(--table-font-size);
}
.docblock table td {
padding: .25em;
}
.docblock table th {
padding: .25em;
text-align: left;
font-family: var(--heading-table-font-family);
font-weight: var(--heading-table-weight);
}
.docblock table tr th:first-child,
.docblock table tr td:first-child {
padding-left: 0;
}
.docblock table tr th:last-child,
.docblock table tr td:last-child {
padding-right: 0;
}
table.enum-members,
table.results {
border-radius: var(--box-radius);
border: 1px solid var(--text-color-muted);
border-spacing: 0 0 !important;
font-size: 80%;
}
table.enum-members tr th,
table.results tr th {
border-top-color: var(--body-bg);
background-color: var(--box-bg);
border-bottom: 1px solid var(--text-color-muted);
}
table.enum-members tr th:first-child,
table.enum-members tr td:first-child {
min-width: 25em;
padding-left: .5em;
}
table.results tr th:first-child,
table.results tr td:first-child {
padding-left: .5em;
}
table.enum-members tr th:last-child,
table.enum-members tr td:last-child,
table.results tr th:last-child,
table.results tr td:last-child {
max-width: 35em;
padding-right: .5em;
}
table.results tr td code {
font-size: 100%;
}
.docblock ul li,
.docblock ol li {
padding-top: 0.15rem;
padding-bottom: 0.15rem;
}
.docblock ul.type {
list-style: none;
}
.docblock ul.type li::before {
content: "»";
color: var(--text-color);
display: inline-block;
width: 1em;
margin-left: -1em;
}
/**************************
RESPONSIVENESS
**************************/
@media (max-width: 700px) {
body {
padding-top: 0px;
}
#body-wrapper {
flex-direction: column;
overflow: hidden;
}
#main {
width: 100%;
padding: 2rem;
}
.sidebar {
position: static;
height: initial;
order: 1;
}
}

View File

@@ -32,7 +32,7 @@ while (($# > 0)); do
list) list=1;;
help) print_help=1;;
--base|-b) read_arg base "$@" || shift;;
--version|-v) read_arg base_version "$@" || shift;;
--base-version) read_arg base_version "$@" || shift;;
--no-login) no_login=1;;
*) echo -e "\e[1;31mERROR\e[0m: Unknown option '$1'"; exit 1;;
esac

View File

@@ -8,8 +8,7 @@ builddir=$1
backend=$2
# Ignore memory leaks lower in dependencies
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0
export G_SLICE=always-malloc
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp
case "${backend}" in
x11)

View File

@@ -1,5 +0,0 @@
#! /bin/sh
. /etc/os-release
echo $PRETTY_NAME

View File

@@ -1,8 +0,0 @@
#!/bin/bash
set -eux -o pipefail
xcodebuild -version || :
xcodebuild -showsdks || :
system_profiler SPSoftwareDataType || :

View File

@@ -15,7 +15,7 @@ meson \
-Dx11-backend=true \
-Dwayland-backend=true \
-Dbroadway-backend=true \
-Dvulkan=enabled \
-Dvulkan=yes \
-Dprofiler=true \
--werror \
${EXTRA_MESON_FLAGS:-} \

View File

@@ -1,14 +0,0 @@
@echo on
:: vcvarsall.bat sets various env vars like PATH, INCLUDE, LIB, LIBPATH for the
:: specified build architecture
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x64
@echo on
:: FIXME: make warnings fatal
pip3 install --upgrade --user meson==0.56.2 || goto :error
meson -Dmedia-gstreamer=disabled _build || goto :error
ninja -C _build || goto :error
goto :EOF
:error
exit /b 1

View File

@@ -40,7 +40,7 @@ export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
# https://gitlab.gnome.org/GNOME/gtk/-/issues/2243
# https://gitlab.gnome.org/GNOME/gtk/-/issues/3002
if ! pkg-config --atleast-version=2.66.0 glib-2.0; then
if ! pkg-config --atleast-version=2.65.0 glib-2.0; then
git clone https://gitlab.gnome.org/GNOME/glib.git _glib
meson setup _glib_build _glib
meson compile -C _glib_build
@@ -48,7 +48,7 @@ if ! pkg-config --atleast-version=2.66.0 glib-2.0; then
fi
pkg-config --modversion glib-2.0
if ! pkg-config --atleast-version=1.49.1 pango; then
if ! pkg-config --atleast-version=1.45.4 pango; then
git clone https://gitlab.gnome.org/GNOME/pango.git _pango
meson setup _pango_build _pango
meson compile -C _pango_build
@@ -60,12 +60,14 @@ pkg-config --modversion pango
ccache --zero-stats
ccache --show-stats
export CCACHE_DISABLE=true
# FIXME: introspection disabled for now because of
# https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/340
meson \
-Dx11-backend=false \
-Dwayland-backend=false \
-Dwin32-backend=true \
-Dvulkan=disabled \
-Dintrospection=enabled \
-Dintrospection=false \
-Dgtk:werror=true \
_build
unset CCACHE_DISABLE

View File

@@ -1,13 +1,4 @@
<!--
Please, read the CONTRIBUTING.md guide on how to file a new issue.
https://gitlab.gnome.org/GNOME/gtk/-/blob/master/CONTRIBUTING.md
-->
## Steps to reproduce
<!--
Please, explain the sequence of actions necessary to reproduce the
bug
-->
1. ...
2. ...
@@ -41,8 +32,5 @@
## Additional information
<!--
- Screenshots or screen recordings are useful for visual errors
- Attaching a screenshot or a video without explaining the current
behavior and the actions necessary to reproduce the bug will lead
to the bug being closed
- Please report any warning or message printed on the terminal
-->

View File

@@ -1,14 +1,4 @@
<!--
Please, read the CONTRIBUTING.md guide on how to file a new issue.
https://gitlab.gnome.org/GNOME/gtk/-/blob/master/CONTRIBUTING.md
-->
## Steps to reproduce
<!--
Please, explain the sequence of actions necessary to reproduce the
crash
-->
1. ...
2. ...

30
AUTHORS
View File

@@ -1,5 +1,5 @@
Please do not mail any of the authors listed here
asking questions about this version of GTK.
Please do not mail any of the authors listed here
asking questions about this version of GTK+.
Original Authors
----------------
@@ -7,8 +7,8 @@ Peter Mattis <petm@xcf.berkeley.edu>
Spencer Kimball <spencer@xcf.berkeley.edu>
Josh MacDonald <jmacd@xcf.berkeley.edu>
The Team that build GTK 2 (in alphabetical order)
-------------------------------------------------
The GTK+ Team (in alphabetical order)
-------------------------------------
Shawn T. Amundson <amundson@gtk.org>
Jerome Bolliet <bolliet@gtk.org>
Damon Chaplin <damon@gtk.org>
@@ -28,24 +28,11 @@ Jay Painter <jpaint@gtk.org>
Manish Singh <manish@gtk.org>
Owen Taylor <otaylor@gtk.org>
The current team (GTK 3 and 4)
------------------------------
Jonas Ådahl <jadahl@gmail.com>
Tim Bäder <mail@baedert.org>
Emmanuele Bassi <ebassi@gnome.org>
Chun-wei Fan <fanchunwei@src.gnome.org>
Matthias Clasen <mclasen@redhat.com>
Carlos Garnacho <mrgarnacho@gmail.com>
Alexander Larsson <alexl@redhat.com>
Benjamin Otte <otte@gnome.org>
There are many others who have contributed patches; we thank them,
GTK is much better because of them.
GTK+ is much better because of them.
Over time, GTK has incorporated some pieces of software which
Over time, GTK+ has incorporated some pieces of software which
started as independent projects. We list the original authors here:
@@ -76,8 +63,3 @@ DirectFB backend
Denis Oliver Kropp
Sven Neumann
Mike Emmel
gtkparasite
-----------
Christian Hammond

View File

@@ -56,12 +56,6 @@ If the issue includes a crash, you should also include:
0. the eventual warnings printed on the terminal
0. a backtrace, obtained with tools such as GDB or LLDB
It is fine to include screenshots of screen recordings to demonstrate
an issue that is best to understand visually, but please don't just
dump screen recordings without further details into issues. It is
essential that the problem is described in enough detail to reproduce
it without watching a video.
For small issues, such as:
- spelling/grammar fixes in the documentation

9296
NEWS

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -10,16 +10,14 @@ GTK is a multi-platform toolkit for creating graphical user interfaces.
Offering a complete set of widgets, GTK is suitable for projects ranging
from small one-off projects to complete application suites.
GTK is a free and open-source software project. The licensing terms
for GTK, the GNU LGPL, allow it to be used by all developers, including those
developing proprietary software, without any license fees or royalties.
GTK is hosted by the GNOME project (thanks!) and used by a wide variety
of applications and projects.
GTK is free software and part of the GNU Project. However, the
licensing terms for GTK, the GNU LGPL, allow it to be used by all
developers, including those developing proprietary software, without any
license fees or royalties.
The official download location
- https://download.gnome.org/sources/gtk/
- https://download.gnome.org/sources/gtk+
The official web site
@@ -34,16 +32,9 @@ Discussion forum
- https://discourse.gnome.org/c/platform/core/
Nightly documentation can be found at
- Gtk: https://gnome.pages.gitlab.gnome.org/gtk/gtk4/
- Gdk: https://gnome.pages.gitlab.gnome.org/gtk/gdk4/
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk4/
Nightly flatpaks of our demos can be installed from the
[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`
- Gtk: https://gnome.pages.gitlab.gnome.org/gtk/gtk/
- Gdk: https://gnome.pages.gitlab.gnome.org/gtk/gdk/
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk/
Building and installing
-----------------------
@@ -58,11 +49,11 @@ In order to build GTK you will need:
You will also need various dependencies, based on the platform you are
building for:
- [GLib](https://download.gnome.org/sources/glib/)
- [GdkPixbuf](https://download.gnome.org/sources/gdk-pixbuf/)
- [GObject-Introspection](https://download.gnome.org/sources/gobject-introspection/)
- [Cairo](https://www.cairographics.org/)
- [Pango](https://download.gnome.org/sources/pango/)
- [GLib](https://download.gnome.org/sources/glib)
- [GdkPixbuf](https://download.gnome.org/sources/gdk-pixbuf)
- [GObject-Introspection](https://download.gnome.org/sources/gobject-introspection)
- [Cairo](https://www.cairographics.org)
- [Pango](https://download.gnome.org/sources/pango)
- [Epoxy](https://github.com/anholt/libepoxy)
- [Graphene](https://github.com/ebassi/graphene)
- [Xkb-common](https://github.com/xkbcommon/libxkbcommon)
@@ -153,17 +144,14 @@ Contributing to GTK
Please, follow the [contribution guide](./CONTRIBUTING.md) to know how to
start contributing to GTK.
If you want to support GTK financially, please consider donating to
the GNOME project, which runs the infrastructure hosting GTK.
Release notes
-------------
The release notes for GTK are part of the migration guide in the API
reference. See:
- [3.x release notes](https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html)
- [4.x release notes](https://docs.gtk.org/gtk4/migrating-3to4.html)
- [3.x release notes](https://developer.gnome.org/gtk3/unstable/gtk-migrating-2-to-3.html)
- [4.x release notes](https://developer.gnome.org/gtk4/unstable/gtk-migrating-3-to-4.html)
Licensing terms
---------------

View File

@@ -1,43 +0,0 @@
diff -ur lua-5.1.4/src/Makefile lua-5.1.4-new/src/Makefile
--- lua-5.1.4/src/Makefile 2008-01-19 20:37:58.000000000 +0100
+++ lua-5.1.4-new/src/Makefile 2012-02-23 18:26:43.000000000 +0100
@@ -23,6 +23,7 @@
PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris
LUA_A= liblua.a
+LUA_SO= liblua.so
CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
lundump.o lvm.o lzio.o
@@ -36,7 +37,7 @@
LUAC_O= luac.o print.o
ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O)
-ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
+ALL_T= $(LUA_A) $(LUA_SO) $(LUA_T) $(LUAC_T)
ALL_A= $(LUA_A)
default: $(PLAT)
@@ -51,6 +52,11 @@
$(AR) $@ $?
$(RANLIB) $@
+$(LUA_SO): $(CORE_O) $(LIB_O)
+ $(CC) -shared -ldl -Wl,-soname,$(LUA_SO).$(V) -o $@.$(R) $? -lm $(MYLDFLAGS)
+ ln -sf $(LUA_SO).$(R) $(LUA_SO).$(V)
+ ln -sf $(LUA_SO).$(R) $(LUA_SO)
+
$(LUA_T): $(LUA_O) $(LUA_A)
$(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
--- lua-5.1.4/Makefile 2008-08-12 02:40:48.000000000 +0200
+++ lua-5.1.4-new/Makefile 2012-02-23 19:06:32.000000000 +0100
@@ -53,7 +53,7 @@
all: $(PLAT)
$(PLATS) clean:
- cd src && $(MAKE) $@
+ cd src && $(MAKE) $@ V=$(V) R=$(R)
test: dummy
src/lua test/hello.lua

View File

@@ -35,15 +35,15 @@
"modules" : [
{
"name" : "wayland",
"buildsystem" : "meson",
"buildsystem" : "autotools",
"builddir" : true,
"config-opts" : [
"-Ddocumentation=false"
"--disable-documentation"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
"url" : "https://github.com/wayland-project/wayland.git"
}
]
},
@@ -93,77 +93,6 @@
}
]
},
{
"name": "boost",
"buildsystem": "simple",
"build-commands": [
"./bootstrap.sh --prefix=/app --with-libraries=date_time,filesystem,iostreams,locale,regex,system,thread,python,program_options,test,serialization",
"./b2 --build-type=minimal link=shared -j $FLATPAK_BUILDER_N_JOBS",
"./b2 --build-type=minimal link=shared install"
],
"sources": [
{
"type": "archive",
"url": "https://boostorg.jfrog.io/artifactory/main/release/1.69.0/source/boost_1_69_0.tar.bz2",
"sha256": "8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406"
}
]
},
{
"name": "lua-5.1",
"buildsystem": "simple",
"build-commands": [
"make -j $FLATPAK_BUILDER_N_JOBS CFLAGS=\"$CFLAGS -fPIC -DLUA_USE_LINUX\" linux",
"make INSTALL_TOP=$FLATPAK_DEST TO_LIB='liblua.a liblua.so.5.1.5' install",
"ln -sf liblua.so.5.1.5 $FLATPAK_DEST/lib/liblua.so",
"ln -sf liblua.so.5.1.5 $FLATPAK_DEST/lib/liblua.so.5.1",
"install -Dm0644 etc/lua.pc $FLATPAK_DEST/lib/pkgconfig/lua.pc",
"ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua51.pc",
"ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua5.1.pc",
"ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua-5.1.pc"
],
"sources": [
{
"type": "archive",
"url": "https://www.lua.org/ftp/lua-5.1.5.tar.gz",
"sha256": "2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333"
},
{
"type": "patch",
"path": "lua-5.1.5-so.patch"
},
{
"type": "shell",
"commands": [
"sed -i \"s|/usr/local|$FLATPAK_DEST|\" etc/lua.pc src/luaconf.h"
]
}
],
"cleanup": [
"*.a",
"/bin",
"/include",
"/lib/pkgconfig",
"/man"
]
},
{
"name" : "highlight",
"buildsystem" : "simple",
"builddir" : true,
"build-commands" : [
"sed -i -e 's#^PREFIX = /usr#PREFIX = /app#' makefile",
"make",
"make install"
],
"sources" : [
{
"type" : "archive",
"url" : "http://www.andre-simon.de/zip/highlight-4.0.tar.bz2",
"sha256" : "f40dcba26e011a2c67df874f4d9b0238c2c6b065163ce8de3d8371b9dfce864d"
}
]
},
{
"name" : "gtk",
"buildsystem" : "meson",
@@ -171,8 +100,7 @@
"config-opts" : [
"--libdir=/app/lib",
"-Denable_vulkan=no",
"-Dbuildtype=debugoptimized",
"-Dprofile=devel"
"-Dbuildtype=debugoptimized"
],
"sources" : [
{

View File

@@ -35,15 +35,15 @@
"modules" : [
{
"name" : "wayland",
"buildsystem" : "meson",
"buildsystem" : "autotools",
"builddir" : true,
"config-opts" : [
"-Ddocumentation=false"
"--disable-documentation"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
"url" : "https://github.com/wayland-project/wayland.git"
}
]
},
@@ -100,8 +100,7 @@
"config-opts" : [
"--libdir=/app/lib",
"-Denable_vulkan=no",
"-Dbuildtype=debugoptimized",
"-Dprofile=devel"
"-Dbuildtype=debugoptimized"
],
"sources" : [
{

View File

@@ -35,15 +35,15 @@
"modules" : [
{
"name" : "wayland",
"buildsystem" : "meson",
"buildsystem" : "autotools",
"builddir" : true,
"config-opts" : [
"-Ddocumentation=false"
"--disable-documentation"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git"
"url" : "https://github.com/wayland-project/wayland.git"
}
]
},
@@ -100,8 +100,7 @@
"config-opts" : [
"--libdir=/app/lib",
"-Denable_vulkan=no",
"-Dbuildtype=debugoptimized",
"-Dprofile=devel"
"-Dbuildtype=debugoptimized"
],
"sources" : [
{

View File

@@ -1,39 +0,0 @@
#!/usr/bin/env python3
import os
import shutil
import subprocess
from pathlib import PurePath
stylesheets = [
'gtk/theme/Default/Default-light.css',
'gtk/theme/Default/Default-dark.css',
'gtk/theme/Default/Default-hc.css',
'gtk/theme/Default/Default-hc-dark.css',
]
references = [
'docs/reference/gtk/gtk4',
'docs/reference/gsk/gsk4',
'docs/reference/gdk/gdk4',
'docs/reference/gdk/gdk4-wayland',
'docs/reference/gdk/gdk4-x11',
]
sourceroot = os.environ.get('MESON_SOURCE_ROOT')
buildroot = os.environ.get('MESON_BUILD_ROOT')
distroot = os.environ.get('MESON_DIST_ROOT')
for stylesheet in stylesheets:
stylesheet_path = PurePath(stylesheet)
src = PurePath(sourceroot, stylesheet_path.with_suffix('.scss'))
dst = PurePath(distroot, stylesheet_path)
subprocess.call(['sassc', '-a', '-M', '-t', 'compact', src, dst])
for reference in references:
src_path = os.path.join(buildroot, reference)
if os.path.isdir(src_path):
dst_path = os.path.join(distroot, reference)
shutil.copytree(src_path, dst_path)

View File

@@ -1,26 +0,0 @@
#!/usr/bin/env python3
import os
import subprocess
import sys
repodir = sys.argv[1]
profile = sys.argv[2]
sys.stdout.write("/* This file is auto-generated. Do not edit. */\n")
sys.stdout.write("#pragma once\n")
sys.stdout.write("\n")
sys.stdout.write(f"#define PROFILE \"{profile}\"\n")
short_sha = os.environ.get('CI_COMMIT_SHORT_SHA')
if short_sha is None:
cmd = ["git", "-C", repodir, "rev-parse", "--short", "HEAD"]
try:
with subprocess.Popen(cmd, stdout=subprocess.PIPE) as p:
short_sha = p.stdout.read().decode('utf-8').rstrip("\n")
except FileNotFoundError:
short_sha = ''
if profile != 'default':
short_sha = 'devel'
sys.stdout.write(f"#define VCS_TAG \"{short_sha}\"\n")

View File

@@ -1,21 +1,20 @@
#!/usr/bin/env python3
import os
import sys
import subprocess
if 'DESTDIR' not in os.environ:
gtk_api_version = sys.argv[1]
gtk_abi_version = sys.argv[2]
import os
import sys
import subprocess
if 'DESTDIR' not in os.environ:
gtk_api_version = sys.argv[1]
gtk_abi_version = sys.argv[2]
gtk_libdir = sys.argv[3]
gtk_datadir = sys.argv[4]
gtk_bindir = sys.argv[5]
gtk_moduledir = os.path.join(gtk_libdir, 'gtk-' + gtk_api_version, gtk_abi_version)
gtk_printmodule_dir = os.path.join(gtk_moduledir, 'printbackends')
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
print('Compiling GSettings schemas...')
gtk_moduledir = os.path.join(gtk_libdir, 'gtk-' + gtk_api_version, gtk_abi_version)
gtk_printmodule_dir = os.path.join(gtk_moduledir, 'printbackends')
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
print('Compiling GSettings schemas...')
glib_compile_schemas = subprocess.check_output(['pkg-config',
'--variable=glib_compile_schemas',
'gio-2.0']).strip()
@@ -23,14 +22,13 @@ if 'DESTDIR' not in os.environ:
# pkg-config variables only available since GLib 2.62.0.
glib_compile_schemas = 'glib-compile-schemas'
subprocess.call([glib_compile_schemas,
os.path.join(gtk_datadir, 'glib-2.0', 'schemas')])
print('Updating icon cache...')
update_icon_cache = os.path.join(gtk_bindir, 'gtk4-update-icon-cache')
subprocess.call([update_icon_cache, '-q', '-t' ,'-f',
os.path.join(gtk_datadir, 'icons', 'hicolor')])
print('Updating module cache for print backends...')
os.path.join(gtk_datadir, 'glib-2.0', 'schemas')])
print('Updating icon cache...')
subprocess.call(['gtk4-update-icon-cache', '-q', '-t' ,'-f',
os.path.join(gtk_datadir, 'icons', 'hicolor')])
print('Updating module cache for print backends...')
os.makedirs(gtk_printmodule_dir, exist_ok=True)
gio_querymodules = subprocess.check_output(['pkg-config',
'--variable=gio_querymodules',
@@ -39,7 +37,7 @@ if 'DESTDIR' not in os.environ:
# pkg-config variables only available since GLib 2.62.0.
gio_querymodules = 'gio-querymodules'
subprocess.call([gio_querymodules, gtk_printmodule_dir])
print('Updating module cache for input methods...')
print('Updating module cache for input methods...')
os.makedirs(gtk_immodule_dir, exist_ok=True)
subprocess.call([gio_querymodules, gtk_immodule_dir])

277
config.h.meson Normal file
View File

@@ -0,0 +1,277 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* always defined to indicate that i18n is enabled */
#define ENABLE_NLS 1
/* The prefix for our gettext translation domains. */
#mesondefine GETTEXT_PACKAGE
/* Disable deprecation warnings from glib */
#mesondefine GLIB_DISABLE_DEPRECATION_WARNINGS
/* Define the location where the catalogs will be installed */
#mesondefine GTK_LOCALEDIR
/* Define to 1 if you have the `bind_textdomain_codeset' function. */
#mesondefine HAVE_BIND_TEXTDOMAIN_CODESET
/* Have the cloudproviders library */
#mesondefine HAVE_CLOUDPROVIDERS
/* define if we have colord */
#mesondefine HAVE_COLORD
/* Define to 1 if you have the <crt_externs.h> header file. */
#mesondefine HAVE_CRT_EXTERNS_H
/* Define to 1 if you have the `dcgettext' function. */
#mesondefine HAVE_DCGETTEXT
/* Define to 1 if you have the <dlfcn.h> header file. */
#mesondefine HAVE_DLFCN_H
/* Have the ffmpeg library */
#mesondefine HAVE_FFMPEG
/* Define to 1 if you have the <ftw.h> header file. */
#mesondefine HAVE_FTW_H
/* Define to 1 if you have the `getpagesize' function. */
#mesondefine HAVE_GETPAGESIZE
/* Define to 1 if you have the `getresuid' function. */
#mesondefine HAVE_GETRESUID
/* Define if gio-unix is available */
#mesondefine HAVE_GIO_UNIX
/* Define if GStreamer support is available */
#mesondefine HAVE_GSTREAMER
/* Define to 1 if you have the <inttypes.h> header file. */
#mesondefine HAVE_INTTYPES_H
/* Define to 1 if the system has the type `IPrintDialogCallback'. */
#mesondefine HAVE_IPRINTDIALOGCALLBACK
/* Define to 1 if you have the <locale.h> header file. */
#mesondefine HAVE_LOCALE_H
/* Define to 1 if you have the `lstat' function. */
#mesondefine HAVE_LSTAT
/* Define to 1 if you have the `mallinfo' function. */
#mesondefine HAVE_MALLINFO
/* Define to 1 if you have the <memory.h> header file. */
#mesondefine HAVE_MEMORY_H
/* Define to 1 if you have the `mkstemp' function. */
#mesondefine HAVE_MKSTEMP
/* Define to 1 if you have a working `mmap' system call. */
#mesondefine HAVE_MMAP
/* Define to 1 if you have the `posix_fallocate' function. */
#mesondefine HAVE_POSIX_FALLOCATE
/* Have the Xrandr extension library */
#mesondefine HAVE_RANDR
/* Have the Xrandr 1.5 extension library */
#mesondefine HAVE_RANDR15
/* Define to 1 if you have the `sincos' function. */
#mesondefine HAVE_SINCOS
/* Define to 1 if you have the <stdint.h> header file. */
#mesondefine HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#mesondefine HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#mesondefine HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#mesondefine HAVE_STRING_H
/* Define to 1 if you have the <sys/mman.h> header file. */
#mesondefine HAVE_SYS_MMAN_H
/* Define to 1 if you have the <sys/param.h> header file. */
#mesondefine HAVE_SYS_PARAM_H
/* Have the sysprof-capture library */
#mesondefine HAVE_SYSPROF
/* Define to 1 if you have the <sys/stat.h> header file. */
#mesondefine HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#mesondefine HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#mesondefine HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#mesondefine HAVE_UNISTD_H
/* Have the XCOMPOSITE X extension */
#mesondefine HAVE_XCOMPOSITE
/* Have the Xcursor library */
#mesondefine HAVE_XCURSOR
/* Have the XDAMAGE X extension */
#mesondefine HAVE_XDAMAGE
/* Have the XFIXES X extension */
#mesondefine HAVE_XFIXES
/* Define to 1 if XFree Xinerama is available */
#mesondefine HAVE_XFREE_XINERAMA
/* Have XGenericEvent */
#mesondefine HAVE_XGENERICEVENTS
/* Define to use XKB extension */
#mesondefine HAVE_XKB
/* Have the SYNC extension library */
#mesondefine HAVE_XSYNC
/* Define to 1 if you have the `_lock_file' function */
#mesondefine HAVE__LOCK_FILE
/* Define to 1 if you have the `flockfile' function */
#mesondefine HAVE_FLOCKFILE
/* Define if _NL_MEASUREMENT_MEASUREMENT is available */
#mesondefine HAVE__NL_MEASUREMENT_MEASUREMENT
/* Define if _NL_PAPER_HEIGHT is available */
#mesondefine HAVE__NL_PAPER_HEIGHT
/* Define if _NL_PAPER_WIDTH is available */
#mesondefine HAVE__NL_PAPER_WIDTH
/* Define if _NL_TIME_FIRST_WEEKDAY is available */
#mesondefine HAVE__NL_TIME_FIRST_WEEKDAY
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#mesondefine LT_OBJDIR
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
#mesondefine NO_MINUS_C_MINUS_O
/* Define to the address where bug reports for this package should be sent. */
#mesondefine PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#mesondefine PACKAGE_NAME
/* Define to the full name and version of this package. */
#mesondefine PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#mesondefine PACKAGE_TARNAME
/* Define to the home page for this package. */
#mesondefine PACKAGE_URL
/* Define to the version of this package. */
#mesondefine PACKAGE_VERSION
/* Use NSBundle functions to determine load paths for libraries, translations,
etc. */
#mesondefine QUARTZ_RELOCATION
/* Define to 1 if you have the ANSI C header files. */
#mesondefine STDC_HEADERS
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
/* Define to 1 if XInput 2.2 is available */
#mesondefine XINPUT_2_2
/* Define to 1 if the X Window System is missing or not being used. */
#mesondefine X_DISPLAY_MISSING
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#mesondefine _FILE_OFFSET_BITS
/* defines how to decorate public symbols while building */
#mesondefine _GDK_EXTERN
/* Define for large files, on AIX-style hosts. */
#mesondefine _LARGE_FILES
/* Define to 1 if on MINIX. */
#mesondefine _MINIX
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#mesondefine _POSIX_1_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#mesondefine _POSIX_SOURCE
/* Define to `int' if <sys/types.h> doesn't define. */
#mesondefine gid_t
/* Define to `int' if <sys/types.h> doesn't define. */
#mesondefine uid_t
/* Define to 1 if linux/memfd.h exists */
#mesondefine HAVE_LINUX_MEMFD_H
#mesondefine HAVE_LINUX_INPUT_H
#mesondefine HAVE_DEV_EVDEV_INPUT_H
#mesondefine GTK_SYSCONFDIR
#mesondefine GTK_LOCALEDIR
#mesondefine GTK_DATADIR
#mesondefine GTK_LIBDIR
#mesondefine GTK_PRINT_BACKENDS
#mesondefine HAVE_CAIRO_SCRIPT_INTERPRETER
#mesondefine HAVE_HARFBUZZ
#mesondefine HAVE_PANGOFT
#mesondefine ISO_CODES_PREFIX
/* Define if tracker3 is available */
#mesondefine HAVE_TRACKER3

View File

@@ -36,7 +36,7 @@ struct _ConstraintEditorWindow
G_DEFINE_TYPE(ConstraintEditorWindow, constraint_editor_window, GTK_TYPE_APPLICATION_WINDOW);
static GtkConstraintTarget *
find_target (GListModel *model,
find_target (GListModel *model,
GtkConstraintTarget *orig)
{
const char *name;
@@ -163,30 +163,20 @@ constraint_editor_window_load (ConstraintEditorWindow *self,
GtkConstraint *clone;
GtkConstraintTarget *target;
GtkConstraintTarget *source;
GtkConstraintAttribute source_attr;
item = g_list_model_get_item (list, i);
constraint = GTK_CONSTRAINT (item);
target = gtk_constraint_get_target (constraint);
source = gtk_constraint_get_source (constraint);
source_attr = gtk_constraint_get_source_attribute (constraint);
if (source == NULL && source_attr == GTK_CONSTRAINT_ATTRIBUTE_NONE)
clone = gtk_constraint_new_constant (find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), target),
clone = gtk_constraint_new (find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), target),
gtk_constraint_get_target_attribute (constraint),
gtk_constraint_get_relation (constraint),
find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), source),
gtk_constraint_get_target_attribute (constraint),
gtk_constraint_get_multiplier (constraint),
gtk_constraint_get_constant (constraint),
gtk_constraint_get_strength (constraint));
else
clone = gtk_constraint_new (find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), target),
gtk_constraint_get_target_attribute (constraint),
gtk_constraint_get_relation (constraint),
find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), source),
source_attr,
gtk_constraint_get_multiplier (constraint),
gtk_constraint_get_constant (constraint),
gtk_constraint_get_strength (constraint));
constraint_view_add_constraint (CONSTRAINT_VIEW (self->view), clone);
@@ -310,7 +300,7 @@ save_response_cb (GtkNativeDialog *dialog,
model = constraint_view_get_model (CONSTRAINT_VIEW (self->view));
text = serialize_model (model);
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
g_file_replace_contents (file, text, strlen (text),
g_file_replace_contents (file, text, -1,
NULL, FALSE,
G_FILE_CREATE_NONE,
NULL,

View File

@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ConstraintEditorWindow" parent="GtkApplicationWindow">
<style>
<class name="devel"/>
</style>
<property name="title" translatable="yes">GTK Constraint Editor</property>
<property name="default-width">1024</property>
<property name="default-height">768</property>

View File

@@ -142,9 +142,6 @@ get_target (GListModel *model,
{
int i;
if (id == NULL)
return NULL;
if (strcmp ("super", id) == 0)
return NULL;
@@ -215,22 +212,6 @@ get_relation_nick (GtkConstraintRelation relation)
return nick;
}
static const char *
get_relation_display_name (GtkConstraintRelation relation)
{
switch (relation)
{
case GTK_CONSTRAINT_RELATION_LE:
return "";
case GTK_CONSTRAINT_RELATION_EQ:
return "=";
case GTK_CONSTRAINT_RELATION_GE:
return "";
default:
return "?";
}
}
static GtkConstraintStrength
get_strength (const char *id)
{
@@ -350,7 +331,6 @@ source_attr_changed (ConstraintEditor *editor)
{
gtk_widget_set_sensitive (editor->source, TRUE);
gtk_widget_set_sensitive (editor->multiplier, TRUE);
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "1");
}
}
@@ -367,7 +347,7 @@ constraint_editor_constraint_to_string (GtkConstraint *constraint)
name = get_target_name (gtk_constraint_get_target (constraint));
attr = get_attr_nick (gtk_constraint_get_target_attribute (constraint));
relation = get_relation_display_name (gtk_constraint_get_relation (constraint));
relation = get_relation_nick (gtk_constraint_get_relation (constraint));
if (name == NULL)
name = "[ ]";
@@ -461,12 +441,8 @@ update_preview (ConstraintEditor *editor)
static void
update_button (ConstraintEditor *editor)
{
const char *target = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target));
const char *source = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
const char *source_attr = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
if (target &&
(source || (source_attr && get_target_attr (source_attr) == GTK_CONSTRAINT_ATTRIBUTE_NONE)))
if (gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target)) != NULL &&
gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source)) != NULL)
gtk_widget_set_sensitive (editor->button, TRUE);
else
gtk_widget_set_sensitive (editor->button, FALSE);

View File

@@ -78,7 +78,6 @@
<object class="GtkComboBoxText" id="source_attr">
<signal name="changed" handler="update_preview" swapped="yes"/>
<signal name="changed" handler="source_attr_changed" swapped="yes"/>
<signal name="changed" handler="update_button" swapped="yes"/>
<layout>
<property name="column">2</property>
<property name="row">3</property>

View File

@@ -177,11 +177,11 @@ constraint_view_init (ConstraintView *self)
guides = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (manager));
all_constraints = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (manager));
filter = GTK_FILTER (gtk_custom_filter_new (omit_internal, NULL, NULL));
filter = gtk_custom_filter_new (omit_internal, NULL, NULL);
constraints = (GListModel *)gtk_filter_list_model_new (all_constraints, filter);
all_children = gtk_widget_observe_children (GTK_WIDGET (self));
filter = GTK_FILTER (gtk_custom_filter_new (omit_internal, NULL, NULL));
filter = gtk_custom_filter_new (omit_internal, NULL, NULL);
children = (GListModel *)gtk_filter_list_model_new (all_children, filter);
list = g_list_store_new (G_TYPE_LIST_MODEL);

View File

@@ -8,16 +8,14 @@ constraint_editor_sources = [
]
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
'constraint-editor.gresource.xml',
source_dir: '.',
)
'constraint-editor.gresource.xml',
source_dir: '.')
executable('gtk4-constraint-editor',
sources: [ constraint_editor_sources, constraint_editor_resources, ],
c_args: common_cflags,
dependencies: libgtk_dep,
include_directories: confinc,
gui_app: true,
link_args: extra_demo_ldflags,
install: false,
)
constraint_editor_sources, constraint_editor_resources,
c_args: common_cflags,
dependencies: libgtk_dep,
include_directories: confinc,
gui_app: true,
link_args: extra_demo_ldflags,
install: false)

View File

@@ -1,345 +0,0 @@
// Originally from: https://www.shadertoy.com/view/wsjBD3
// License CC0: A battered alien planet
// Been experimenting with space inspired shaders
#define PI 3.141592654
#define TAU (2.0*PI)
#define TOLERANCE 0.00001
#define MAX_ITER 65
#define MIN_DISTANCE 0.01
#define MAX_DISTANCE 9.0
const vec3 skyCol1 = vec3(0.35, 0.45, 0.6);
const vec3 skyCol2 = vec3(0.4, 0.7, 1.0);
const vec3 skyCol3 = pow(skyCol1, vec3(0.25));
const vec3 sunCol1 = vec3(1.0,0.6,0.4);
const vec3 sunCol2 = vec3(1.0,0.9,0.7);
const vec3 smallSunCol1 = vec3(1.0,0.5,0.25)*0.5;
const vec3 smallSunCol2 = vec3(1.0,0.5,0.25)*0.5;
const vec3 mountainColor = 1.0*sqrt(vec3(0.95, 0.65, 0.45));
const float cellWidth = 1.0;
const vec4 planet = vec4(80.0, -20.0, 100.0, 50.0)*1000.0;
void rot(inout vec2 p, float a) {
float c = cos(a);
float s = sin(a);
p = vec2(p.x*c + p.y*s, -p.x*s + p.y*c);
}
vec2 mod2(inout vec2 p, vec2 size) {
vec2 c = floor((p + size*0.5)/size);
p = mod(p + size*0.5,size) - size*0.5;
return c;
}
float circle(vec2 p, float r) {
return length(p) - r;
}
float egg(vec2 p, float ra, float rb) {
const float k = sqrt(3.0);
p.x = abs(p.x);
float r = ra - rb;
return ((p.y<0.0) ? length(vec2(p.x, p.y )) - r :
(k*(p.x+r)<p.y) ? length(vec2(p.x, p.y-k*r)) :
length(vec2(p.x+r,p.y )) - 2.0*r) - rb;
}
vec2 hash(vec2 p) {
p = vec2(dot (p, vec2 (127.1, 311.7)), dot (p, vec2 (269.5, 183.3)));
return -1. + 2.*fract (sin (p)*43758.5453123);
}
vec2 raySphere(vec3 ro, vec3 rd, vec4 sphere) {
vec3 center = sphere.xyz;
float radius = sphere.w;
vec3 m = ro - center.xyz;
float b = dot(m, rd);
float c = dot(m, m) - radius*radius;
if(c > 0.0 && b > 0.0) return vec2(-1.0, -1.0);
float discr = b * b - c;
if(discr < 0.0) return vec2(-1.0);
float normalMultiplier = 1.0;
float s = sqrt(discr);
float t0 = -b - s;
float t1 = -b + s;;
return vec2(t0, t1);
}
float noize1(vec2 p) {
vec2 n = mod2(p, vec2(cellWidth));
vec2 hh = hash(sqrt(2.0)*(n+1000.0));
hh.x *= hh.y;
float r = 0.225*cellWidth;
float d = circle(p, 2.0*r);
float h = hh.x*smoothstep(0.0, r, -d);
return h*0.25;
}
float noize2(vec2 p) {
vec2 n = mod2(p, vec2(cellWidth));
vec2 hh = hash(sqrt(2.0)*(n+1000.0));
hh.x *= hh.y;
rot(p, TAU*hh.y);
float r = 0.45*cellWidth;
// float d = circle(p, 1.0*r);
float d = egg(p, 0.75*r, 0.5*r*abs(hh.y));
float h = (hh.x)*smoothstep(0.0, r, -2.0*d);
return h*0.275;
}
float height(vec2 p, float dd, int mx) {
const float aa = 0.45;
const float ff = 2.03;
const float tt = 1.2;
const float oo = 3.93;
const float near = 0.25;
const float far = 0.65;
float a = 1.0;
float o = 0.2;
float s = 0.0;
float d = 0.0;
int i = 0;
for (; i < 4;++i) {
float nn = a*noize2(p);
s += nn;
d += abs(a);
p += o;
a *= aa;
p *= ff;
o *= oo;
rot(p, tt);
}
float lod = s/d;
float rdd = dd/MAX_DISTANCE;
mx = int(mix(float(4), float(mx), step(rdd, far)));
for (; i < mx; ++i) {
float nn = a*noize1(p);
s += nn;
d += abs(a);
p += o;
a *= aa;
p *= ff;
o *= oo;
rot(p, tt);
}
float hid = (s/d);
return mix(hid, lod, smoothstep(near, far, rdd));
}
float loheight(vec2 p, float d) {
return height(p, d, 0);
}
float height(vec2 p, float d) {
return height(p, d, 6);
}
float hiheight(vec2 p, float d) {
return height(p, d, 8);
}
vec3 normal(vec2 p, float d) {
vec2 eps = vec2(0.00125, 0.0);
vec3 n;
n.x = (hiheight(p - eps.xy, d) - hiheight(p + eps.xy, d));
n.y = 2.0*eps.x;
n.z = (hiheight(p - eps.yx, d) - hiheight(p + eps.yx, d));
return normalize(n);
}
const float stepLength[] = float[](0.9, 0.25);
float march(vec3 ro, vec3 rd, out int max_iter) {
float dt = 0.1;
float d = MIN_DISTANCE;
int currentStep = 0;
float lastd = d;
for (int i = 0; i < MAX_ITER; ++i)
{
vec3 p = ro + d*rd;
float h = height(p.xz, d);
if (d > MAX_DISTANCE) {
max_iter = i;
return MAX_DISTANCE;
}
float hd = p.y - h;
if (hd < TOLERANCE) {
++currentStep;
if (currentStep >= stepLength.length()) {
max_iter = i;
return d;
}
d = lastd;
continue;
}
float sl = stepLength[currentStep];
dt = max(hd, TOLERANCE)*sl + 0.0025*d;
lastd = d;
d += dt;
}
max_iter = MAX_ITER;
return MAX_DISTANCE;
}
vec3 sunDirection() {
return normalize(vec3(-0.5, 0.085, 1.0));
}
vec3 smallSunDirection() {
return normalize(vec3(-0.2, -0.05, 1.0));
}
float psin(float f) {
return 0.5 + 0.5*sin(f);
}
vec3 skyColor(vec3 ro, vec3 rd) {
vec3 sunDir = sunDirection();
vec3 smallSunDir = smallSunDirection();
float sunDot = max(dot(rd, sunDir), 0.0);
float smallSunDot = max(dot(rd, smallSunDir), 0.0);
float angle = atan(rd.y, length(rd.xz))*2.0/PI;
vec3 skyCol = mix(mix(skyCol1, skyCol2, max(0.0, angle)), skyCol3, clamp(-angle*2.0, 0.0, 1.0));
vec3 sunCol = 0.5*sunCol1*pow(sunDot, 20.0) + 8.0*sunCol2*pow(sunDot, 2000.0);
vec3 smallSunCol = 0.5*smallSunCol1*pow(smallSunDot, 200.0) + 8.0*smallSunCol2*pow(smallSunDot, 20000.0);
vec3 dust = pow(sunCol2*mountainColor, vec3(1.75))*smoothstep(0.05, -0.1, rd.y)*0.5;
vec2 si = raySphere(ro, rd, planet);
vec3 planetSurface = ro + si.x*rd;
vec3 planetNormal = normalize(planetSurface - planet.xyz);
float planetDiff = max(dot(planetNormal, sunDir), 0.0);
float planetBorder = max(dot(planetNormal, -rd), 0.0);
float planetLat = (planetSurface.x+planetSurface.y)*0.0005;
vec3 planetCol = mix(1.3*vec3(0.9, 0.8, 0.7), 0.3*vec3(0.9, 0.8, 0.7), pow(psin(planetLat+1.0)*psin(sqrt(2.0)*planetLat+2.0)*psin(sqrt(3.5)*planetLat+3.0), 0.5));
vec3 final = vec3(0.0);
final += step(0.0, si.x)*pow(planetDiff, 0.75)*planetCol*smoothstep(-0.075, 0.0, rd.y)*smoothstep(0.0, 0.1, planetBorder);
final += skyCol + sunCol + smallSunCol + dust;
return final;
}
vec3 getColor(vec3 ro, vec3 rd) {
int max_iter = 0;
vec3 skyCol = skyColor(ro, rd);
vec3 col = vec3(0);
float d = march(ro, rd, max_iter);
if (d < MAX_DISTANCE) {
vec3 sunDir = sunDirection();
vec3 osunDir = sunDir*vec3(-1.0, .0, -1.0);
vec3 p = ro + d*rd;
vec3 normal = normal(p.xz, d);
float amb = 0.2;
float dif1 = max(0.0, dot(sunDir, normal));
vec3 shd1 = sunCol2*mix(amb, 1.0, pow(dif1, 0.75));
float dif2 = max(0.0, dot(osunDir, normal));
vec3 shd2 = sunCol1*mix(amb, 1.0, pow(dif2, 0.75));
vec3 ref = reflect(rd, normal);
vec3 rcol = skyColor(p, ref);
col = mountainColor*amb*skyCol3;
col += mix(shd1, shd2, -0.5)*mountainColor;
float fre = max(dot(normal, -rd), 0.0);
fre = pow(1.0 - fre, 5.0);
col += rcol*fre*0.5;
col += (1.0*p.y);
col = tanh(col);
col = mix(col, skyCol, smoothstep(0.5*MAX_DISTANCE, 1.0*MAX_DISTANCE, d));
} else {
col = skyCol;
}
// col += vec3(1.1, 0.0, 0.0)* smoothstep(0.25, 1.0,(float(max_iter)/float(MAX_ITER)));
return col;
}
vec3 getSample1(vec2 p, float time) {
float off = 0.5*iTime;
vec3 ro = vec3(0.5, 1.0-0.25, -2.0 + off);
vec3 la = ro + vec3(0.0, -0.30, 2.0);
vec3 ww = normalize(la - ro);
vec3 uu = normalize(cross(vec3(0.0,1.0,0.0), ww));
vec3 vv = normalize(cross(ww, uu));
vec3 rd = normalize(p.x*uu + p.y*vv + 2.0*ww);
vec3 col = getColor(ro, rd) ;
return col;
}
vec3 getSample2(vec2 p, float time) {
p.y-=time*0.25;
float h = height(p, 0.0);
vec3 n = normal(p, 0.0);
vec3 lp = vec3(10.0, -1.2, 0.0);
vec3 ld = normalize(vec3(p.x, h, p.y)- lp);
float d = max(dot(ld, n), 0.0);
vec3 col = vec3(0.0);
col = vec3(1.0)*(h+0.1);
col += vec3(1.5)*pow(d, 0.75);
return col;
}
void mainImage(out vec4 fragColor, vec2 fragCoord) {
vec2 q = fragCoord.xy/iResolution.xy;
vec2 p = -1.0 + 2.0*q;
p.x *= iResolution.x/iResolution.y;
vec3 col = getSample1(p, iTime);
fragColor = vec4(col, 1.0);
}

View File

@@ -465,18 +465,18 @@ demo_application_window_size_allocate (GtkWidget *widget,
baseline);
if (!window->maximized && !window->fullscreen)
gtk_window_get_default_size (GTK_WINDOW (window), &window->width, &window->height);
gtk_window_get_size (GTK_WINDOW (window), &window->width, &window->height);
}
static void
surface_state_changed (GtkWidget *widget)
{
DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
GdkToplevelState new_state;
GdkSurfaceState new_state;
new_state = gdk_toplevel_get_state (GDK_TOPLEVEL (gtk_native_get_surface (GTK_NATIVE (widget))));
window->maximized = (new_state & GDK_TOPLEVEL_STATE_MAXIMIZED) != 0;
window->fullscreen = (new_state & GDK_TOPLEVEL_STATE_FULLSCREEN) != 0;
window->maximized = (new_state & GDK_SURFACE_STATE_MAXIMIZED) != 0;
window->fullscreen = (new_state & GDK_SURFACE_STATE_FULLSCREEN) != 0;
}
static void

View File

@@ -1,8 +1,8 @@
/* Assistant
*
* Demonstrates a sample multi-step assistant with GtkAssistant. Assistants
* are used to divide an operation into several simpler sequential steps,
* and to guide the user through these steps.
* Demonstrates a sample multi-step assistant. Assistants are used to divide
* an operation into several simpler sequential steps, and to guide the user
* through these steps.
*/
#include <gtk/gtk.h>
@@ -98,9 +98,6 @@ create_page1 (GtkWidget *assistant)
gtk_box_append (GTK_BOX (box), label);
entry = gtk_entry_new ();
gtk_accessible_update_relation (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
gtk_widget_set_valign (entry, GTK_ALIGN_CENTER);
gtk_box_append (GTK_BOX (box), entry);

View File

@@ -1,26 +0,0 @@
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;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="window">
<property name="resizable">0</property>
<property name="title">CSS Blend Modes</property>

View File

@@ -1,8 +1,6 @@
/* Builder
* #Keywords: GMenu, GtkPopoverMenuBar, GtkBuilder, GtkStatusBar, GtkShortcutController, toolbar
*
* Demonstrates a traditional interface, loaded from a XML description,
* and shows how to connect actions to the menu items and toolbar buttons.
* Demonstrates an interface loaded from a XML description.
*/
#include <gtk/gtk.h>
@@ -106,7 +104,6 @@ do_builder (GtkWidget *do_widget)
GtkBuilder *builder;
GtkWidget *about;
GtkWidget *status;
GtkEventController *controller;
builder = gtk_builder_new_from_resource ("/builder/demo.ui");
@@ -120,44 +117,10 @@ do_builder (GtkWidget *do_widget)
window);
gtk_widget_insert_action_group (window, "win", actions);
controller = gtk_shortcut_controller_new ();
gtk_shortcut_controller_set_scope (GTK_SHORTCUT_CONTROLLER (controller),
GTK_SHORTCUT_SCOPE_GLOBAL);
gtk_widget_add_controller (window, controller);
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_n, GDK_CONTROL_MASK),
gtk_named_action_new ("win.new")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_o, GDK_CONTROL_MASK),
gtk_named_action_new ("win.open")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_s, GDK_CONTROL_MASK),
gtk_named_action_new ("win.save")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_s, GDK_CONTROL_MASK|GDK_SHIFT_MASK),
gtk_named_action_new ("win.save-as")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_q, GDK_CONTROL_MASK),
gtk_named_action_new ("win.quit")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_c, GDK_CONTROL_MASK),
gtk_named_action_new ("win.copy")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_x, GDK_CONTROL_MASK),
gtk_named_action_new ("win.cut")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_v, GDK_CONTROL_MASK),
gtk_named_action_new ("win.paste")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_F1, 0),
gtk_named_action_new ("win.help")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_F7, 0),
gtk_named_action_new ("win.about")));
about = GTK_WIDGET (gtk_builder_get_object (builder, "aboutdialog1"));
gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (window));
gtk_window_set_hide_on_close (GTK_WINDOW (about), TRUE);
g_signal_connect (about, "response", G_CALLBACK (gtk_widget_hide), NULL);
g_object_set_data_full (G_OBJECT (window), "about",
about, (GDestroyNotify)gtk_window_destroy);

View File

@@ -1,224 +0,0 @@
// 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, vec2 fragCoord) {
vec2 q = fragCoord/iResolution.xy;
vec2 p = -1.0 + 2.0*q;
p.x *= iResolution.x/iResolution.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 / iResolution.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);
}

View File

@@ -1,226 +0,0 @@
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);
}

View File

@@ -1,5 +1,4 @@
/* Combo Boxes
* #Keywords: GtkCellRenderer
*
* The GtkComboBox widget allows to select one option out of a list.
* The GtkComboBoxEntry additionally allows the user to enter a value

View File

@@ -1,16 +1,8 @@
/* Constraints/Simple Constraints
* #Keywords: GtkLayoutManager
/* Constraints/Simple
*
* GtkConstraintLayout provides a layout manager that uses relations
* between widgets (also known as constraints) to compute the position
* between widgets (also known as "constraints") to compute the position
* and size of each child.
*
* In addition to child widgets, the constraints can involve spacer
* objects (also known as “guides”). This example has a guide between
* the two buttons in the top row.
*
* Try resizing the window to see how the constraints react to update
* the layout.
*/
#include <glib/gi18n.h>
@@ -241,12 +233,15 @@ simple_grid_init (SimpleGrid *self)
self->button1 = gtk_button_new_with_label ("Child 1");
gtk_widget_set_parent (self->button1, widget);
gtk_widget_set_name (self->button1, "button1");
self->button2 = gtk_button_new_with_label ("Child 2");
gtk_widget_set_parent (self->button2, widget);
gtk_widget_set_name (self->button2, "button2");
self->button3 = gtk_button_new_with_label ("Child 3");
gtk_widget_set_parent (self->button3, widget);
gtk_widget_set_name (self->button3, "button3");
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
@@ -263,8 +258,7 @@ do_constraints (GtkWidget *do_widget)
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Simple Constraints");
gtk_window_set_default_size (GTK_WINDOW (window), 260, -1);
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);

View File

@@ -1,7 +1,6 @@
/* Constraints/Interactive Constraints
* #Keywords: GtkConstraintLayout
/* Constraints/Interactive
*
* This example shows how constraints can be updated during user interaction.
* Demonstrate how constraints can be updates during user interaction.
* The vertical edge between the buttons can be dragged with the mouse.
*/
@@ -205,7 +204,7 @@ interactive_grid_init (InteractiveGrid *self)
}
GtkWidget *
do_constraints_interactive (GtkWidget *do_widget)
do_constraints2 (GtkWidget *do_widget)
{
static GtkWidget *window;
@@ -215,8 +214,7 @@ do_constraints_interactive (GtkWidget *do_widget)
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Interactive Constraints");
gtk_window_set_default_size (GTK_WINDOW (window), 260, -1);
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);

View File

@@ -2,10 +2,6 @@
*
* GtkConstraintLayout allows defining constraints using a
* compact syntax called Visual Format Language, or VFL.
*
* A typical example of a VFL specification looks like this:
*
* H:|-[button1(==button2)]-12-[button2]-|
*/
#include <glib/gi18n.h>
@@ -128,7 +124,7 @@ vfl_grid_init (VflGrid *self)
}
GtkWidget *
do_constraints_vfl (GtkWidget *do_widget)
do_constraints3 (GtkWidget *do_widget)
{
static GtkWidget *window;
@@ -138,8 +134,7 @@ do_constraints_vfl (GtkWidget *do_widget)
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "ConstraintsVFL");
gtk_window_set_default_size (GTK_WINDOW (window), 260, -1);
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);

View File

@@ -1,74 +0,0 @@
/* Constraints/Builder
*
* GtkConstraintLayouts can be created in .ui files, and constraints can
* be set up at that time as well, as this example demonstrates. It shows
* various ways to do spacing and sizing with constraints.
*
* Make the window wider to see the rows react differently
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE (ConstraintsGrid, constraints_grid, CONSTRAINTS, GRID, GtkWidget)
struct _ConstraintsGrid
{
GtkWidget parent_instance;
};
G_DEFINE_TYPE (ConstraintsGrid, constraints_grid, GTK_TYPE_WIDGET)
static void
constraints_grid_init (ConstraintsGrid *grid)
{
}
static void
constraints_grid_dispose (GObject *object)
{
GtkWidget *widget = GTK_WIDGET (object);
GtkWidget *child;
while ((child = gtk_widget_get_first_child (widget)))
gtk_widget_unparent (child);
G_OBJECT_CLASS (constraints_grid_parent_class)->dispose (object);
}
static void
constraints_grid_class_init (ConstraintsGridClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = constraints_grid_dispose;
}
GtkWidget *
do_constraints_builder (GtkWidget *do_widget)
{
static GtkWidget *window;
if (!window)
{
GtkBuilder *builder;
g_type_ensure (constraints_grid_get_type ());
builder = gtk_builder_new_from_resource ("/constraints_builder/constraints_builder.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,460 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window1">
<property name="title" translatable="yes">ConstraintsBuilder</property>
<property name="default-width">260</property>
<child>
<object class="ConstraintsGrid">
<property name="halign">fill</property>
<property name="valign">fill</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="layout-manager">
<object class="GtkConstraintLayout">
<constraints>
<guide name="guide1" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide2" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide3" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide4" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide5" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide6" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide7" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide8" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide9" min-width="0" nat-width="200" strength="weak"/>
<guide name="guide10" min-width="0" nat-width="200" strength="weak"/>
<guide name="barrier1" min-height="10"/>
<guide name="barrier2" min-height="10"/>
<guide name="barrier3" min-height="10"/>
<guide name="barrier4" min-height="10"/>
<!-- Spread Chain -->
<constraint target="super" target-attribute="top"
relation="eq"
source="button1" source-attribute="top"
strength="required"/>
<constraint target="super" target-attribute="top"
relation="eq"
source="button2" source-attribute="top"
strength="required"/>
<constraint target="super" target-attribute="top"
relation="eq"
source="button3" source-attribute="top"
strength="required"/>
<constraint target="super" target-attribute="left"
relation="eq"
source="guide1" source-attribute="left"
strength="required"/>
<constraint target="button1" target-attribute="left"
relation="eq"
source="guide1" source-attribute="right"
strength="required"/>
<constraint target="guide2" target-attribute="left"
relation="eq"
source="button1" source-attribute="right"
strength="required"/>
<constraint target="button2" target-attribute="left"
relation="eq"
source="guide2" source-attribute="right"
strength="required"/>
<constraint target="guide3" target-attribute="left"
relation="eq"
source="button2" source-attribute="right"
strength="required"/>
<constraint target="button3" target-attribute="left"
relation="eq"
source="guide3" source-attribute="right"
strength="required"/>
<constraint target="guide4" target-attribute="left"
relation="eq"
source="button3" source-attribute="right"
strength="required"/>
<constraint target="super" target-attribute="right"
relation="eq"
source="guide4" source-attribute="right"
strength="required"/>
<constraint target="guide1" target-attribute="width"
relation="eq"
source="guide2" source-attribute="width"
strength="required"/>
<constraint target="guide2" target-attribute="width"
relation="eq"
source="guide3" source-attribute="width"
strength="required"/>
<constraint target="guide3" target-attribute="width"
relation="eq"
source="guide4" source-attribute="width"
strength="required"/>
<constraint target="button1" target-attribute="width"
relation="eq"
source="button2" source-attribute="width"
strength="required"/>
<constraint target="button2" target-attribute="width"
relation="eq"
source="button3" source-attribute="width"
strength="required"/>
<constraint target="button1" target-attribute="bottom"
relation="eq"
source="barrier1" source-attribute="top"
strength="required"/>
<constraint target="button2" target-attribute="bottom"
relation="eq"
source="barrier1" source-attribute="top"
strength="required"/>
<constraint target="button3" target-attribute="bottom"
relation="eq"
source="barrier1" source-attribute="top"
strength="required"/>
<!-- Spread Inside Chain -->
<constraint target="super" target-attribute="left"
relation="eq"
source="button4" source-attribute="left"
strength="required"/>
<constraint target="guide5" target-attribute="left"
relation="eq"
source="button4" source-attribute="right"
strength="required"/>
<constraint target="button5" target-attribute="left"
relation="eq"
source="guide5" source-attribute="right"
strength="required"/>
<constraint target="guide6" target-attribute="left"
relation="eq"
source="button5" source-attribute="right"
strength="required"/>
<constraint target="button6" target-attribute="left"
relation="eq"
source="guide6" source-attribute="right"
strength="required"/>
<constraint target="super" target-attribute="right"
relation="eq"
source="button6" source-attribute="right"
strength="required"/>
<constraint target="guide5" target-attribute="width"
relation="eq"
source="guide6" source-attribute="width"
strength="required"/>
<constraint target="button4" target-attribute="width"
relation="eq"
source="button5" source-attribute="width"
strength="required"/>
<constraint target="button5" target-attribute="width"
relation="eq"
source="button6" source-attribute="width"
strength="required"/>
<constraint target="button4" target-attribute="top"
relation="eq"
source="barrier1" source-attribute="bottom"
strength="required"/>
<constraint target="button5" target-attribute="top"
relation="eq"
source="barrier1" source-attribute="bottom"
strength="required"/>
<constraint target="button6" target-attribute="top"
relation="eq"
source="barrier1" source-attribute="bottom"
strength="required"/>
<constraint target="button4" target-attribute="bottom"
relation="eq"
source="barrier2" source-attribute="top"
strength="required"/>
<constraint target="button5" target-attribute="bottom"
relation="eq"
source="barrier2" source-attribute="top"
strength="required"/>
<constraint target="button6" target-attribute="bottom"
relation="eq"
source="barrier2" source-attribute="top"
strength="required"/>
<!-- Weighted Chain -->
<constraint target="super" target-attribute="left"
relation="eq"
source="button7" source-attribute="left"
strength="required"/>
<constraint target="button8" target-attribute="left"
relation="eq"
source="button7" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="button9" target-attribute="left"
relation="eq"
source="button8" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="super" target-attribute="right"
relation="eq"
source="button9" source-attribute="right"
strength="required"/>
<constraint target="button8" target-attribute="width"
relation="eq"
source="button7" source-attribute="width"
multiplier="2"
strength="required"/>
<constraint target="button9" target-attribute="width"
relation="eq"
source="button7" source-attribute="width"
multiplier="3"
strength="required"/>
<constraint target="button7" target-attribute="top"
relation="eq"
source="barrier2" source-attribute="bottom"
strength="required"/>
<constraint target="button8" target-attribute="top"
relation="eq"
source="barrier2" source-attribute="bottom"
strength="required"/>
<constraint target="button9" target-attribute="top"
relation="eq"
source="barrier2" source-attribute="bottom"
strength="required"/>
<constraint target="button7" target-attribute="bottom"
relation="eq"
source="barrier3" source-attribute="top"
strength="required"/>
<constraint target="button8" target-attribute="bottom"
relation="eq"
source="barrier3" source-attribute="top"
strength="required"/>
<constraint target="button9" target-attribute="bottom"
relation="eq"
source="barrier3" source-attribute="top"
strength="required"/>
<!-- Packed Chain -->
<constraint target="super" target-attribute="left"
relation="eq"
source="guide7" source-attribute="left"
strength="required"/>
<constraint target="button10" target-attribute="left"
relation="eq"
source="guide7" source-attribute="right"
strength="required"/>
<constraint target="button11" target-attribute="left"
relation="eq"
source="button10" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="button12" target-attribute="left"
relation="eq"
source="button11" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="guide8" target-attribute="left"
relation="eq"
source="button12" source-attribute="right"
strength="required"/>
<constraint target="super" target-attribute="right"
relation="eq"
source="guide8" source-attribute="right"
strength="required"/>
<constraint target="guide7" target-attribute="width"
relation="eq"
source="guide8" source-attribute="width"
strength="required"/>
<constraint target="button10" target-attribute="width"
relation="eq"
source="button11" source-attribute="width"
strength="required"/>
<constraint target="button11" target-attribute="width"
relation="eq"
source="button12" source-attribute="width"
strength="required"/>
<constraint target="button10" target-attribute="top"
relation="eq"
source="barrier3" source-attribute="bottom"
strength="required"/>
<constraint target="button11" target-attribute="top"
relation="eq"
source="barrier3" source-attribute="bottom"
strength="required"/>
<constraint target="button12" target-attribute="top"
relation="eq"
source="barrier3" source-attribute="bottom"
strength="required"/>
<constraint target="button10" target-attribute="bottom"
relation="eq"
source="barrier4" source-attribute="top"
strength="required"/>
<constraint target="button11" target-attribute="bottom"
relation="eq"
source="barrier4" source-attribute="top"
strength="required"/>
<constraint target="button12" target-attribute="bottom"
relation="eq"
source="barrier4" source-attribute="top"
strength="required"/>
<!-- Packed Chain with Bias -->
<constraint target="super" target-attribute="left"
relation="eq"
source="guide9" source-attribute="left"
strength="required"/>
<constraint target="button13" target-attribute="left"
relation="eq"
source="guide9" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="button14" target-attribute="left"
relation="eq"
source="button13" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="button15" target-attribute="left"
relation="eq"
source="button14" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="guide10" target-attribute="left"
relation="eq"
source="button15" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="super" target-attribute="right"
relation="eq"
source="guide10" source-attribute="right"
strength="required"/>
<constraint target="guide9" target-attribute="width"
relation="eq"
source="guide10" source-attribute="width"
multiplier="4"
strength="required"/>
<constraint target="button13" target-attribute="width"
relation="eq"
source="button14" source-attribute="width"
strength="required"/>
<constraint target="button14" target-attribute="width"
relation="eq"
source="button15" source-attribute="width"
strength="required"/>
<constraint target="button13" target-attribute="top"
relation="eq"
source="barrier4" source-attribute="bottom"
strength="required"/>
<constraint target="button14" target-attribute="top"
relation="eq"
source="barrier4" source-attribute="bottom"
strength="required"/>
<constraint target="button15" target-attribute="top"
relation="eq"
source="barrier4" source-attribute="bottom"
strength="required"/>
<constraint target="super" target-attribute="bottom"
relation="ge"
source="button13" source-attribute="bottom"
strength="required"/>
<constraint target="super" target-attribute="bottom"
relation="ge"
source="button14" source-attribute="bottom"
strength="required"/>
<constraint target="super" target-attribute="bottom"
relation="ge"
source="button15" source-attribute="bottom"
strength="required"/>
</constraints>
</object>
</property>
<child>
<object class="GtkButton" id="button1">
<property name="label">A</property>
</object>
</child>
<child>
<object class="GtkButton" id="button2">
<property name="label">B</property>
</object>
</child>
<child>
<object class="GtkButton" id="button3">
<property name="label">C</property>
</object>
</child>
<child>
<object class="GtkButton" id="button4">
<property name="label">A</property>
</object>
</child>
<child>
<object class="GtkButton" id="button5">
<property name="label">B</property>
</object>
</child>
<child>
<object class="GtkButton" id="button6">
<property name="label">C</property>
</object>
</child>
<child>
<object class="GtkButton" id="button7">
<property name="label">A</property>
</object>
</child>
<child>
<object class="GtkButton" id="button8">
<property name="label">B</property>
</object>
</child>
<child>
<object class="GtkButton" id="button9">
<property name="label">C</property>
</object>
</child>
<child>
<object class="GtkButton" id="button10">
<property name="label">A</property>
</object>
</child>
<child>
<object class="GtkButton" id="button11">
<property name="label">B</property>
</object>
</child>
<child>
<object class="GtkButton" id="button12">
<property name="label">C</property>
</object>
</child>
<child>
<object class="GtkButton" id="button13">
<property name="label">A</property>
</object>
</child>
<child>
<object class="GtkButton" id="button14">
<property name="label">B</property>
</object>
</child>
<child>
<object class="GtkButton" id="button15">
<property name="label">C</property>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -1,27 +0,0 @@
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

@@ -1,6 +1,7 @@
/* Theming/CSS Accordion
*
* A simple accordion demo written using CSS transitions and multiple backgrounds
*
*/
#include <gtk/gtk.h>

View File

@@ -1,7 +1,8 @@
/* Theming/CSS Basics
*
* GTK themes are written using CSS. Every widget is build of multiple items
* Gtk themes are written using CSS. Every widget is build of multiple items
* that you can style very similarly to a regular website.
*
*/
#include <gtk/gtk.h>

View File

@@ -1,7 +1,8 @@
/* Theming/Multiple Backgrounds
*
* GTK themes are written using CSS. Every widget is build of multiple items
* Gtk themes are written using CSS. Every widget is build of multiple items
* that you can style very similarly to a regular website.
*
*/
#include <gtk/gtk.h>

View File

@@ -1,7 +1,6 @@
/* Theming/Animated Backgrounds
*
* This demo is in honour of a classic Pixbufs demo.
*
* This demo is done in honour of the Pixbufs demo further down.
* It is done exclusively with CSS as the background of the window.
*/

View File

@@ -18,9 +18,6 @@
<file>demoimage.c</file>
<file>demoimage.h</file>
</gresource>
<gresource prefix="/constraints_builder">
<file>constraints_builder.ui</file>
</gresource>
<gresource prefix="/css_accordion">
<file>css_accordion.css</file>
<file>reset.css</file>
@@ -43,11 +40,6 @@
<file>cssview.css</file>
<file>reset.css</file>
</gresource>
<gresource prefix="/dropdown">
<file>suggestionentry.h</file>
<file>suggestionentry.c</file>
<file>suggestionentry.css</file>
</gresource>
<gresource prefix="/theming_style_classes">
<file>theming.ui</file>
</gresource>
@@ -120,45 +112,15 @@
<gresource prefix="/dnd">
<file>dnd.css</file>
</gresource>
<gresource prefix="/errorstates">
<file>errorstates.ui</file>
</gresource>
<gresource prefix="/fishbowl">
<file>fishbowl.ui</file>
<file>gtkfishbowl.c</file>
<file>gtkfishbowl.h</file>
</gresource>
<gresource prefix="/frames">
<file>frames.ui</file>
</gresource>
<gresource prefix="/gears">
<file>gtkgears.c</file>
<file>gtkgears.h</file>
</gresource>
<gresource prefix="/shadertoy">
<file>gtkshadertoy.c</file>
<file>gtkshadertoy.h</file>
<file>alienplanet.glsl</file>
<file>mandelbrot.glsl</file>
<file>neon.glsl</file>
<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>
@@ -195,9 +157,6 @@
<gresource prefix="/listview_settings">
<file>listview_settings.ui</file>
</gresource>
<gresource prefix="/listview_ucd_data/">
<file>ucdnames.data</file>
</gresource>
<gresource prefix="/listview_weather">
<file compressed="true">listview_weather.txt</file>
</gresource>
@@ -205,21 +164,6 @@
<file compressed="true">color.names.txt</file>
<file>listview_colors.css</file>
</gresource>
<gresource prefix="/main">
<file>fontify.c</file>
<file>fontify.h</file>
<file>main.ui</file>
</gresource>
<gresource prefix="/menu">
<file>demo3widget.c</file>
<file>demo3widget.h</file>
<file>demo3widget.ui</file>
</gresource>
<gresource prefix="/paintable_svg">
<file>svgpaintable.h</file>
<file>svgpaintable.c</file>
<file>org.gtk.gtk4.NodeEditor.Devel.svg</file>
</gresource>
<gresource prefix="/shortcuts">
<file>shortcuts.ui</file>
<file>shortcuts-builder.ui</file>
@@ -239,15 +183,9 @@
<file>revealer.ui</file>
</gresource>
<gresource prefix="/images">
<file>pixbufpaintable.h</file>
<file>pixbufpaintable.c</file>
<file>alphatest.png</file>
<file>floppybuddy.gif</file>
<file>gtk-logo.webm</file>
<file alias="org.gtk.Demo4.svg">data/scalable/apps/org.gtk.Demo4.svg</file>
</gresource>
<gresource prefix="/video-player">
<file>bbb.png</file>
</gresource>
<gresource prefix="/sources">
<file>application_demo.c</file>
@@ -256,9 +194,8 @@
<file>clipboard.c</file>
<file>combobox.c</file>
<file>constraints.c</file>
<file>constraints_interactive.c</file>
<file>constraints_vfl.c</file>
<file>constraints_builder.c</file>
<file>constraints2.c</file>
<file>constraints3.c</file>
<file>css_accordion.c</file>
<file>css_basics.c</file>
<file>css_blendmodes.c</file>
@@ -273,20 +210,17 @@
<file>editable_cells.c</file>
<file>entry_completion.c</file>
<file>entry_undo.c</file>
<file>errorstates.c</file>
<file>expander.c</file>
<file>filtermodel.c</file>
<file>fishbowl.c</file>
<file>fixed.c</file>
<file>flowbox.c</file>
<file>frames.c</file>
<file>font_features.c</file>
<file>fontplane.c</file>
<file>fontrendering.c</file>
<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>
@@ -298,30 +232,24 @@
<file>layoutmanager2.c</file>
<file>links.c</file>
<file>listbox.c</file>
<file>listbox_controls.c</file>
<file>listbox2.c</file>
<file>listview_applauncher.c</file>
<file>listview_colors.c</file>
<file>listview_clocks.c</file>
<file>listview_filebrowser.c</file>
<file>listview_minesweeper.c</file>
<file>listview_settings.c</file>
<file>listview_ucd.c</file>
<file>listview_weather.c</file>
<file>listview_words.c</file>
<file>list_store.c</file>
<file>main.c</file>
<file>markup.c</file>
<file>menu.c</file>
<file>overlay.c</file>
<file>overlay_decorative.c</file>
<file>overlay2.c</file>
<file>paint.c</file>
<file>pagesetup.c</file>
<file>paintable.c</file>
<file>paintable_animated.c</file>
<file>paintable_emblem.c</file>
<file>paintable_mediastream.c</file>
<file>paintable_svg.c</file>
<file>paintable_symbolic.c</file>
<file>panes.c</file>
<file>password_entry.c</file>
<file>peg_solitaire.c</file>
@@ -332,7 +260,6 @@
<file>scale.c</file>
<file>search_entry.c</file>
<file>search_entry2.c</file>
<file>shadertoy.c</file>
<file>shortcuts.c</file>
<file>shortcut_triggers.c</file>
<file>sizegroup.c</file>
@@ -364,8 +291,8 @@
<file>messages.txt</file>
<file>apple-red.png</file>
</gresource>
<gresource prefix="/listbox_controls">
<file>listbox_controls.ui</file>
<gresource prefix="/listbox2">
<file>listbox2.ui</file>
</gresource>
<gresource prefix="/glarea">
<file>glarea-gl.fs.glsl</file>

View File

@@ -29,24 +29,29 @@
<item>
<attribute name="label" translatable="yes">_New</attribute>
<attribute name="action">win.new</attribute>
<attribute name="accel">&lt;Control&gt;n</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Open</attribute>
<attribute name="action">win.open</attribute>
<attribute name="accel">&lt;Control&gt;o</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Save</attribute>
<attribute name="action">win.save</attribute>
<attribute name="accel">&lt;Control&gt;s</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Save _As</attribute>
<attribute name="action">win.save-as</attribute>
<attribute name="accel">&lt;Control&gt;q</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">_Quit</attribute>
<attribute name="action">win.quit</attribute>
<attribute name="accel">&lt;Control&gt;&lt;Shift&gt;s</attribute>
</item>
</section>
</submenu>
@@ -56,14 +61,17 @@
<item>
<attribute name="label" translatable="yes">_Copy</attribute>
<attribute name="action">win.copy</attribute>
<attribute name="accel">&lt;Control&gt;c</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Cut</attribute>
<attribute name="action">win.cut</attribute>
<attribute name="accel">&lt;Control&gt;x</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Paste</attribute>
<attribute name="action">win.paste</attribute>
<attribute name="accel">&lt;Control&gt;v</attribute>
</item>
</section>
</submenu>
@@ -73,17 +81,19 @@
<item>
<attribute name="label" translatable="yes">_Help</attribute>
<attribute name="action">win.help</attribute>
<attribute name="accel">F1</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_About</attribute>
<attribute name="action">win.about</attribute>
<attribute name="accel">F7</attribute>
</item>
</section>
</submenu>
</menu>
<object class="GtkAboutDialog" id="aboutdialog1">
<property name="program-name" translatable="yes">Builder demo</property>
<property name="logo-icon-name" translatable="yes">org.gtk.Demo4</property>
<property name="logo-icon-name" translatable="yes">gtk3-demo</property>
<property name="modal">True</property>
</object>
<object class="GtkWindow" id="window1">
@@ -96,24 +106,15 @@
<child>
<object class="GtkPopoverMenuBar" id="menubar1">
<property name="menu-model">menubar</property>
<accessibility>
<property name="label">Main Menu</property>
</accessibility>
</object>
</child>
<child>
<object class="GtkBox" id="toolbar1">
<property name="accessible-role">toolbar</property>
<property name="css-classes">toolbar</property>
<accessibility>
<property name="label">Toolbar</property>
</accessibility>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">New</property>
<property name="tooltip-text" translatable="yes">Create a new file</property>
<property name="icon-name">document-new</property>
<property name="action-name">win.new</property>
</object>
</child>
<child>
@@ -121,7 +122,6 @@
<property name="label" translatable="yes">Open</property>
<property name="tooltip-text" translatable="yes">Open a file</property>
<property name="icon-name">document-open</property>
<property name="action-name">win.open</property>
</object>
</child>
<child>
@@ -129,7 +129,6 @@
<property name="label" translatable="yes">Save</property>
<property name="tooltip-text" translatable="yes">Save a file</property>
<property name="icon-name">document-save</property>
<property name="action-name">win.save</property>
</object>
</child>
<child>
@@ -140,7 +139,6 @@
<property name="label" translatable="yes">Copy</property>
<property name="tooltip-text" translatable="yes">Copy selected object into the clipboard</property>
<property name="icon-name">edit-copy</property>
<property name="action-name">win.copy</property>
</object>
</child>
<child>
@@ -148,7 +146,6 @@
<property name="label" translatable="yes">Cut</property>
<property name="tooltip-text" translatable="yes">Cut selected object into the clipboard</property>
<property name="icon-name">edit-cut</property>
<property name="action-name">win.cut</property>
</object>
</child>
<child>
@@ -156,7 +153,6 @@
<property name="label" translatable="yes">Paste</property>
<property name="tooltip-text" translatable="yes">Paste object from the clipboard</property>
<property name="icon-name">edit-paste</property>
<property name="action-name">win.paste</property>
</object>
</child>
</object>

View File

@@ -1,243 +0,0 @@
#include <math.h>
#include "demo3widget.h"
enum
{
PROP_PAINTABLE = 1,
PROP_SCALE
};
struct _Demo3Widget
{
GtkWidget parent_instance;
GdkPaintable *paintable;
float scale;
GtkWidget *menu;
};
struct _Demo3WidgetClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (Demo3Widget, demo3_widget, GTK_TYPE_WIDGET)
static void
demo3_widget_init (Demo3Widget *self)
{
self->scale = 1.f;
gtk_widget_init_template (GTK_WIDGET (self));
}
static void
demo3_widget_dispose (GObject *object)
{
Demo3Widget *self = DEMO3_WIDGET (object);
g_clear_object (&self->paintable);
g_clear_pointer (&self->menu, gtk_widget_unparent);
G_OBJECT_CLASS (demo3_widget_parent_class)->dispose (object);
}
static void
demo3_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
Demo3Widget *self = DEMO3_WIDGET (widget);
int x, y, width, height;
double w, h;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
w = self->scale * gdk_paintable_get_intrinsic_width (self->paintable);
h = self->scale * gdk_paintable_get_intrinsic_height (self->paintable);
x = MAX (0, (width - ceil (w)) / 2);
y = MAX (0, (height - ceil (h)) / 2);
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_save (snapshot);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
gdk_paintable_snapshot (self->paintable, snapshot, w, h);
gtk_snapshot_restore (snapshot);
gtk_snapshot_pop (snapshot);
}
static void
demo3_widget_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
Demo3Widget *self = DEMO3_WIDGET (widget);
int size;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
size = gdk_paintable_get_intrinsic_width (self->paintable);
else
size = gdk_paintable_get_intrinsic_height (self->paintable);
*minimum = *natural = self->scale * size;
}
static void
demo3_widget_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
Demo3Widget *self = DEMO3_WIDGET (widget);
/* Since we are not using a layout manager (who would do this
* for us), we need to allocate a size for our menu by calling
* gtk_popover_present().
*/
gtk_popover_present (GTK_POPOVER (self->menu));
}
static void
demo3_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
Demo3Widget *self = DEMO3_WIDGET (object);
switch (prop_id)
{
case PROP_PAINTABLE:
g_clear_object (&self->paintable);
self->paintable = g_value_dup_object (value);
gtk_widget_queue_resize (GTK_WIDGET (object));
break;
case PROP_SCALE:
self->scale = g_value_get_float (value);
gtk_widget_queue_resize (GTK_WIDGET (object));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
demo3_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
Demo3Widget *self = DEMO3_WIDGET (object);
switch (prop_id)
{
case PROP_PAINTABLE:
g_value_set_object (value, self->paintable);
break;
case PROP_SCALE:
g_value_set_float (value, self->scale);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
pressed_cb (GtkGestureClick *gesture,
guint n_press,
double x,
double y,
Demo3Widget *self)
{
/* We are placing our menu at the point where
* the click happened, before popping it up.
*/
gtk_popover_set_pointing_to (GTK_POPOVER (self->menu),
&(const GdkRectangle){ x, y, 1, 1 });
gtk_popover_popup (GTK_POPOVER (self->menu));
}
static void
zoom_cb (GtkWidget *widget,
const char *action_name,
GVariant *parameter)
{
Demo3Widget *self = DEMO3_WIDGET (widget);
float scale;
if (g_str_equal (action_name, "zoom.in"))
scale = MIN (10, self->scale * M_SQRT2);
else if (g_str_equal (action_name, "zoom.out"))
scale = MAX (0.01, self->scale / M_SQRT2);
else
scale = 1.0;
gtk_widget_action_set_enabled (widget, "zoom.in", scale < 10);
gtk_widget_action_set_enabled (widget, "zoom.out", scale > 0.01);
gtk_widget_action_set_enabled (widget, "zoom.reset", scale != 1);
g_object_set (widget, "scale", scale, NULL);
}
static void
demo3_widget_class_init (Demo3WidgetClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = demo3_widget_dispose;
object_class->set_property = demo3_widget_set_property;
object_class->get_property = demo3_widget_get_property;
widget_class->snapshot = demo3_widget_snapshot;
widget_class->measure = demo3_widget_measure;
widget_class->size_allocate = demo3_widget_size_allocate;
g_object_class_install_property (object_class, PROP_PAINTABLE,
g_param_spec_object ("paintable", "Paintable", "Paintable",
GDK_TYPE_PAINTABLE,
G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_SCALE,
g_param_spec_float ("scale", "Scale", "Scale",
0.0, 10.0, 1.0,
G_PARAM_READWRITE));
/* These are the actions that we are using in the menu */
gtk_widget_class_install_action (widget_class, "zoom.in", NULL, zoom_cb);
gtk_widget_class_install_action (widget_class, "zoom.out", NULL, zoom_cb);
gtk_widget_class_install_action (widget_class, "zoom.reset", NULL, zoom_cb);
gtk_widget_class_set_template_from_resource (widget_class, "/menu/demo3widget.ui");
gtk_widget_class_bind_template_child (widget_class, Demo3Widget, menu);
gtk_widget_class_bind_template_callback (widget_class, pressed_cb);
}
GtkWidget *
demo3_widget_new (const char *resource)
{
Demo3Widget *self;
GdkPixbuf *pixbuf;
GdkPaintable *paintable;
pixbuf = gdk_pixbuf_new_from_resource (resource, NULL);
paintable = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (pixbuf));
self = g_object_new (DEMO3_TYPE_WIDGET, "paintable", paintable, NULL);
g_object_unref (pixbuf);
g_object_unref (paintable);
return GTK_WIDGET (self);
}

View File

@@ -1,8 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#define DEMO3_TYPE_WIDGET (demo3_widget_get_type ())
G_DECLARE_FINAL_TYPE (Demo3Widget, demo3_widget, DEMO3, WIDGET, GtkWidget)
GtkWidget * demo3_widget_new (const char *resource);

View File

@@ -1,30 +0,0 @@
<interface>
<menu id="model">
<item>
<attribute name="label">Zoom Out</attribute>
<attribute name="action">zoom.out</attribute>
</item>
<item>
<attribute name="label">Zoom In</attribute>
<attribute name="action">zoom.in</attribute>
</item>
<item>
<attribute name="label">11</attribute>
<attribute name="action">zoom.reset</attribute>
</item>
</menu>
<template class="Demo3Widget">
<child>
<object class="GtkPopoverMenu" id="menu">
<property name="has-arrow">0</property>
<property name="menu-model">model</property>
</object>
</child>
<child>
<object class="GtkGestureClick">
<property name="button">3</property>
<signal name="pressed" handler="pressed_cb"/>
</object>
</child>
</template>
</interface>

View File

@@ -47,38 +47,6 @@ get_image_paintable (GtkImage *image)
}
}
static void
update_drag_icon (DemoImage *demo,
GtkDragIcon *icon)
{
const char *icon_name;
GdkPaintable *paintable;
GtkWidget *image;
switch (gtk_image_get_storage_type (GTK_IMAGE (demo->image)))
{
case GTK_IMAGE_PAINTABLE:
paintable = gtk_image_get_paintable (GTK_IMAGE (demo->image));
image = gtk_image_new_from_paintable (paintable);
break;
case GTK_IMAGE_ICON_NAME:
icon_name = gtk_image_get_icon_name (GTK_IMAGE (demo->image));
image = gtk_image_new_from_icon_name (icon_name);
break;
case GTK_IMAGE_EMPTY:
case GTK_IMAGE_GICON:
default:
g_warning ("Image storage type %d not handled",
gtk_image_get_storage_type (GTK_IMAGE (demo->image)));
return;
}
gtk_image_set_pixel_size (GTK_IMAGE (image),
gtk_image_get_pixel_size (GTK_IMAGE (demo->image)));
gtk_drag_icon_set_child (icon, image);
}
static void
drag_begin (GtkDragSource *source,
GdkDrag *drag,
@@ -86,8 +54,14 @@ drag_begin (GtkDragSource *source,
{
GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
DemoImage *demo = DEMO_IMAGE (widget);
GdkPaintable *paintable;
update_drag_icon (demo, GTK_DRAG_ICON (gtk_drag_icon_get_for_drag (drag)));
paintable = get_image_paintable (GTK_IMAGE (demo->image));
if (paintable)
{
gtk_drag_icon_set_from_paintable (drag, paintable, -2, -2);
g_object_unref (paintable);
}
}
static GdkContentProvider *
@@ -100,11 +74,7 @@ prepare_drag (GtkDragSource *source,
DemoImage *demo = DEMO_IMAGE (widget);
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (demo->image));
/* Textures can be serialized, paintables can't, so special case the textures */
if (GDK_IS_TEXTURE (paintable))
return gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, paintable);
else
return gdk_content_provider_new_typed (GDK_TYPE_PAINTABLE, paintable);
return gdk_content_provider_new_typed (GDK_TYPE_PAINTABLE, paintable);
}
static gboolean
@@ -133,11 +103,7 @@ copy_image (GtkWidget *widget,
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (demo->image));
GValue value = G_VALUE_INIT;
/* Textures can be serialized, paintables can't, so special case the textures */
if (GDK_IS_TEXTURE (paintable))
g_value_init (&value, GDK_TYPE_TEXTURE);
else
g_value_init (&value, GDK_TYPE_PAINTABLE);
g_value_init (&value, GDK_TYPE_PAINTABLE);
g_value_set_object (&value, paintable);
gdk_clipboard_set_value (clipboard, &value);
g_value_unset (&value);
@@ -146,46 +112,24 @@ copy_image (GtkWidget *widget,
g_object_unref (paintable);
}
static void
paste_image_cb (GObject *source,
GAsyncResult *result,
gpointer data)
{
GdkClipboard *clipboard = GDK_CLIPBOARD (source);
DemoImage *demo = DEMO_IMAGE (data);
const GValue *value;
value = gdk_clipboard_read_value_finish (clipboard, result, NULL);
if (value == NULL)
{
gtk_widget_error_bell (GTK_WIDGET (demo));
g_object_unref (demo);
return;
}
gtk_image_set_from_paintable (GTK_IMAGE (demo->image), g_value_get_object (value));
g_object_unref (demo);
}
static void
paste_image (GtkWidget *widget,
const char *action_name,
GVariant *parameter)
{
GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
GType type;
DemoImage *demo = DEMO_IMAGE (widget);
GdkContentProvider *content = gdk_clipboard_get_content (clipboard);
GValue value = G_VALUE_INIT;
GdkPaintable *paintable;
if (gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), GDK_TYPE_TEXTURE))
type = GDK_TYPE_TEXTURE;
else
type = GDK_TYPE_PAINTABLE;
g_value_init (&value, GDK_TYPE_PAINTABLE);
if (!gdk_content_provider_get_value (content, &value, NULL))
return;
gdk_clipboard_read_value_async (clipboard,
type,
G_PRIORITY_DEFAULT,
NULL,
paste_image_cb,
g_object_ref (widget));
paintable = GDK_PAINTABLE (g_value_get_object (&value));
gtk_image_set_from_paintable (GTK_IMAGE (demo->image), paintable);
g_value_unset (&value);
}
static void

View File

@@ -44,23 +44,11 @@ G_DEFINE_TYPE_WITH_CODE (DemoTaggedEntry, demo_tagged_entry, GTK_TYPE_WIDGET,
static void
demo_tagged_entry_init (DemoTaggedEntry *entry)
{
GtkCssProvider *provider;
entry->text = gtk_text_new ();
gtk_widget_set_hexpand (entry->text, TRUE);
gtk_widget_set_vexpand (entry->text, TRUE);
gtk_widget_set_parent (entry->text, GTK_WIDGET (entry));
gtk_editable_init_delegate (GTK_EDITABLE (entry));
gtk_editable_set_width_chars (GTK_EDITABLE (entry->text), 6);
gtk_editable_set_max_width_chars (GTK_EDITABLE (entry->text), 6);
gtk_widget_add_css_class (GTK_WIDGET (entry), "tagged");
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/tagged_entry/tagstyle.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
800);
g_object_unref (provider);
}
static void
@@ -128,7 +116,6 @@ demo_tagged_entry_class_init (DemoTaggedEntryClass *klass)
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT);
gtk_widget_class_set_css_name (widget_class, "entry");
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_TEXT_BOX);
}
static GtkEditable *
@@ -224,6 +211,7 @@ static void
demo_tagged_entry_tag_init (DemoTaggedEntryTag *tag)
{
GtkGesture *gesture;
GtkCssProvider *provider;
tag->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_parent (tag->box, GTK_WIDGET (tag));
@@ -233,6 +221,13 @@ demo_tagged_entry_tag_init (DemoTaggedEntryTag *tag)
gesture = gtk_gesture_click_new ();
g_signal_connect (gesture, "released", G_CALLBACK (on_released), tag);
gtk_widget_add_controller (GTK_WIDGET (tag), GTK_EVENT_CONTROLLER (gesture));
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/tagged_entry/tagstyle.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
800);
g_object_unref (provider);
}
static void

View File

@@ -1,5 +1,4 @@
/* Dialogs
* #Keywords: GtkMessageDialog
*
* Dialogs are used to pop up transient windows for information
* and user feedback.

View File

@@ -1,12 +1,8 @@
/* Drag-and-Drop
* #Keywords: dnd, menu, popover, gesture
*
* This demo shows dragging colors and widgets.
* The items in this demo can be moved, recolored
* and rotated.
*
* The demo also has an example for creating a
* menu-like popover without using a menu model.
*/
#include <gtk/gtk.h>
@@ -113,9 +109,12 @@ apply_transform (CanvasItem *item)
y = gtk_widget_get_allocated_height (item->label) / 2.0;
item->r = sqrt (x*x + y*y);
transform = gsk_transform_translate (NULL, &(graphene_point_t) { item->r, item->r });
transform = gsk_transform_rotate (transform, item->angle + item->delta);
transform = gsk_transform_translate (transform, &(graphene_point_t) { -x, -y });
transform = gsk_transform_translate (
gsk_transform_rotate (
gsk_transform_translate (NULL,
&(graphene_point_t) { item->r, item->r }),
item->angle + item->delta),
&(graphene_point_t) { - x, - y });
gtk_fixed_set_child_transform (GTK_FIXED (item->fixed), item->label, transform);
gsk_transform_unref (transform);

View File

@@ -1,5 +1,4 @@
/* Drawing Area
* #Keywords: GtkDrawingArea
*
* GtkDrawingArea is a blank area where you can draw custom displays
* of various kinds.
@@ -311,7 +310,6 @@ do_drawingarea (GtkWidget *do_widget)
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Drawing Area");
gtk_window_set_default_size (GTK_WINDOW (window), 250, -1);
g_signal_connect (window, "destroy",
G_CALLBACK (close_window), NULL);
@@ -326,8 +324,9 @@ do_drawingarea (GtkWidget *do_widget)
/*
* Create the groups area
*/
label = gtk_label_new ("Knockout groups");
gtk_widget_add_css_class (label, "heading");
label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label),
"<u>Knockout groups</u>");
gtk_box_append (GTK_BOX (vbox), label);
frame = gtk_frame_new (NULL);
@@ -344,8 +343,9 @@ do_drawingarea (GtkWidget *do_widget)
* Create the scribble area
*/
label = gtk_label_new ("Scribble area");
gtk_widget_add_css_class (label, "heading");
label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label),
"<u>Scribble area</u>");
gtk_box_append (GTK_BOX (vbox), label);
frame = gtk_frame_new (NULL);

View File

@@ -1,16 +1,17 @@
/* Lists/Selections
/* Drop Downs
*
* The GtkDropDown widget is a modern alternative to GtkComboBox.
* It uses list models instead of tree models, and the content is
* displayed using widgets instead of cell renderers.
*
* This example also shows a custom widget that can replace
* GtkEntryCompletion or GtkComboBoxText. It is not currently
* part of GTK.
* The examples here demonstrate how to use different kinds of
* list models with GtkDropDown, how to use search and how to
* display the selected item differently from the presentation
* in the popup.
*/
#include <gtk/gtk.h>
#include "suggestionentry.h"
#define STRING_TYPE_HOLDER (string_holder_get_type ())
G_DECLARE_FINAL_TYPE (StringHolder, string_holder, STRING, HOLDER, GObject)
@@ -64,22 +65,18 @@ strings_setup_item_single_line (GtkSignalListItemFactory *factory,
GtkListItem *item)
{
GtkWidget *box, *image, *title;
GtkWidget *checkmark;
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
image = gtk_image_new ();
title = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (title), 0.0);
checkmark = gtk_image_new_from_icon_name ("object-select-symbolic");
gtk_box_append (GTK_BOX (box), image);
gtk_box_append (GTK_BOX (box), title);
gtk_box_append (GTK_BOX (box), checkmark);
g_object_set_data (G_OBJECT (item), "title", title);
g_object_set_data (G_OBJECT (item), "image", image);
g_object_set_data (G_OBJECT (item), "checkmark", checkmark);
gtk_list_item_set_child (item, box);
}
@@ -89,7 +86,6 @@ strings_setup_item_full (GtkSignalListItemFactory *factory,
GtkListItem *item)
{
GtkWidget *box, *box2, *image, *title, *description;
GtkWidget *checkmark;
image = gtk_image_new ();
title = gtk_label_new ("");
@@ -97,7 +93,6 @@ strings_setup_item_full (GtkSignalListItemFactory *factory,
description = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (description), 0.0);
gtk_widget_add_css_class (description, "dim-label");
checkmark = gtk_image_new_from_icon_name ("object-select-symbolic");
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
@@ -106,48 +101,26 @@ strings_setup_item_full (GtkSignalListItemFactory *factory,
gtk_box_append (GTK_BOX (box), box2);
gtk_box_append (GTK_BOX (box2), title);
gtk_box_append (GTK_BOX (box2), description);
gtk_box_append (GTK_BOX (box), checkmark);
g_object_set_data (G_OBJECT (item), "title", title);
g_object_set_data (G_OBJECT (item), "image", image);
g_object_set_data (G_OBJECT (item), "description", description);
g_object_set_data (G_OBJECT (item), "checkmark", checkmark);
gtk_list_item_set_child (item, box);
}
static void
selected_item_changed (GtkDropDown *dropdown,
GParamSpec *pspec,
GtkListItem *item)
{
GtkWidget *checkmark;
checkmark = g_object_get_data (G_OBJECT (item), "checkmark");
if (gtk_drop_down_get_selected_item (dropdown) == gtk_list_item_get_item (item))
gtk_widget_set_opacity (checkmark, 1.0);
else
gtk_widget_set_opacity (checkmark, 0.0);
}
static void
strings_bind_item (GtkSignalListItemFactory *factory,
GtkListItem *item,
gpointer data)
GtkListItem *item)
{
GtkDropDown *dropdown = data;
GtkWidget *image, *title, *description;
GtkWidget *checkmark;
StringHolder *holder;
GtkWidget *popup;
holder = gtk_list_item_get_item (item);
title = g_object_get_data (G_OBJECT (item), "title");
image = g_object_get_data (G_OBJECT (item), "image");
description = g_object_get_data (G_OBJECT (item), "description");
checkmark = g_object_get_data (G_OBJECT (item), "checkmark");
gtk_label_set_label (GTK_LABEL (title), holder->title);
if (image)
@@ -160,43 +133,19 @@ strings_bind_item (GtkSignalListItemFactory *factory,
gtk_label_set_label (GTK_LABEL (description), holder->description);
gtk_widget_set_visible (description , holder->description != NULL);
}
popup = gtk_widget_get_ancestor (title, GTK_TYPE_POPOVER);
if (popup && gtk_widget_is_ancestor (popup, GTK_WIDGET (dropdown)))
{
gtk_widget_show (checkmark);
g_signal_connect (dropdown, "notify::selected-item",
G_CALLBACK (selected_item_changed), item);
selected_item_changed (dropdown, NULL, item);
}
else
{
gtk_widget_hide (checkmark);
}
}
static void
strings_unbind_item (GtkSignalListItemFactory *factory,
GtkListItem *list_item,
gpointer data)
{
GtkDropDown *dropdown = data;
g_signal_handlers_disconnect_by_func (dropdown, selected_item_changed, list_item);
}
static GtkListItemFactory *
strings_factory_new (gpointer data, gboolean full)
strings_factory_new (gboolean full)
{
GtkListItemFactory *factory;
factory = gtk_signal_list_item_factory_new ();
if (full)
g_signal_connect (factory, "setup", G_CALLBACK (strings_setup_item_full), data);
g_signal_connect (factory, "setup", G_CALLBACK (strings_setup_item_full), NULL);
else
g_signal_connect (factory, "setup", G_CALLBACK (strings_setup_item_single_line), data);
g_signal_connect (factory, "bind", G_CALLBACK (strings_bind_item), data);
g_signal_connect (factory, "unbind", G_CALLBACK (strings_unbind_item), data);
g_signal_connect (factory, "setup", G_CALLBACK (strings_setup_item_single_line), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (strings_bind_item), NULL);
return factory;
}
@@ -237,22 +186,19 @@ drop_down_new_from_strings (const char *const *titles,
g_return_val_if_fail (descriptions == NULL || g_strv_length ((char **)icons) == g_strv_length ((char **)descriptions), NULL);
model = strings_model_new (titles, icons, descriptions);
widget = g_object_new (GTK_TYPE_DROP_DOWN,
"model", model,
NULL);
g_object_unref (model);
factory = strings_factory_new (widget, FALSE);
factory = strings_factory_new (FALSE);
if (icons != NULL || descriptions != NULL)
list_factory = strings_factory_new (widget, TRUE);
list_factory = strings_factory_new (TRUE);
else
list_factory = NULL;
g_object_set (widget,
"factory", factory,
"list-factory", list_factory,
NULL);
widget = g_object_new (GTK_TYPE_DROP_DOWN,
"model", model,
"factory", factory,
"list-factory", list_factory,
NULL);
g_object_unref (model);
g_object_unref (factory);
if (list_factory)
g_object_unref (list_factory);
@@ -272,110 +218,13 @@ get_title (gpointer item)
return g_strdup (STRING_HOLDER (item)->title);
}
static char *
get_file_name (gpointer item)
{
return g_strdup (g_file_info_get_display_name (G_FILE_INFO (item)));
}
static void
setup_item (GtkSignalListItemFactory *factory,
GtkListItem *item)
{
GtkWidget *box;
GtkWidget *icon;
GtkWidget *label;
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
icon = gtk_image_new ();
label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_box_append (GTK_BOX (box), icon);
gtk_box_append (GTK_BOX (box), label);
gtk_list_item_set_child (item, box);
}
static void
bind_item (GtkSignalListItemFactory *factory,
GtkListItem *item)
{
MatchObject *match = MATCH_OBJECT (gtk_list_item_get_item (item));
GFileInfo *info = G_FILE_INFO (match_object_get_item (match));
GtkWidget *box = gtk_list_item_get_child (item);
GtkWidget *icon = gtk_widget_get_first_child (box);
GtkWidget *label = gtk_widget_get_last_child (box);
gtk_image_set_from_gicon (GTK_IMAGE (icon), g_file_info_get_icon (info));
gtk_label_set_label (GTK_LABEL (label), g_file_info_get_display_name (info));
}
static void
setup_highlight_item (GtkSignalListItemFactory *factory,
GtkListItem *item)
{
GtkWidget *label;
label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_list_item_set_child (item, label);
}
static void
bind_highlight_item (GtkSignalListItemFactory *factory,
GtkListItem *item)
{
MatchObject *obj;
GtkWidget *label;
PangoAttrList *attrs;
PangoAttribute *attr;
const char *str;
obj = MATCH_OBJECT (gtk_list_item_get_item (item));
label = gtk_list_item_get_child (item);
str = match_object_get_string (obj);
gtk_label_set_label (GTK_LABEL (label), str);
attrs = pango_attr_list_new ();
attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
attr->start_index = match_object_get_match_start (obj);
attr->end_index = match_object_get_match_end (obj);
pango_attr_list_insert (attrs, attr);
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs);
}
static void
match_func (MatchObject *obj,
const char *search,
gpointer user_data)
{
char *tmp1, *tmp2;
char *p;
tmp1 = g_utf8_normalize (match_object_get_string (obj), -1, G_NORMALIZE_ALL);
tmp2 = g_utf8_normalize (search, -1, G_NORMALIZE_ALL);
if ((p = strstr (tmp1, tmp2)) != NULL)
match_object_set_match (obj,
p - tmp1,
(p - tmp1) + g_utf8_strlen (search, -1),
1);
else
match_object_set_match (obj, 0, 0, 0);
g_free (tmp1);
g_free (tmp2);
}
GtkWidget *
do_dropdown (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
GtkWidget *button, *box, *spin, *check, *hbox, *label, *entry;
GtkWidget *button, *box, *spin, *check;
GListModel *model;
GtkExpression *expression;
GtkListItemFactory *factory;
const char * const times[] = { "1 minute", "2 minutes", "5 minutes", "20 minutes", NULL };
const char * const many_times[] = {
"1 minute", "2 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes",
@@ -388,49 +237,22 @@ do_dropdown (GtkWidget *do_widget)
const char * const device_descriptions[] = {
"Built-in Audio", "Built-in audio", "Thinkpad Tunderbolt 3 Dock USB Audio", "Thinkpad Tunderbolt 3 Dock USB Audio", NULL
};
char *cwd;
GFile *file;
GListModel *dir;
GtkStringList *strings;
if (!window)
{
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Selections");
gtk_window_set_title (GTK_WINDOW (window), "Drop Downs");
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 20);
gtk_widget_set_margin_start (hbox, 20);
gtk_widget_set_margin_end (hbox, 20);
gtk_widget_set_margin_top (hbox, 20);
gtk_widget_set_margin_bottom (hbox, 20);
gtk_window_set_child (GTK_WINDOW (window), hbox);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
gtk_box_append (GTK_BOX (hbox), box);
label = gtk_label_new ("Dropdowns");
gtk_widget_add_css_class (label, "title-4");
gtk_box_append (GTK_BOX (box), label);
/* A basic dropdown */
button = drop_down_new_from_strings (times, NULL, NULL);
gtk_box_append (GTK_BOX (box), button);
/* A dropdown using an expression to obtain strings */
button = drop_down_new_from_strings (many_times, NULL, NULL);
gtk_drop_down_set_enable_search (GTK_DROP_DOWN (button), TRUE);
expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
0, NULL,
(GCallback)get_title,
NULL, NULL);
gtk_drop_down_set_expression (GTK_DROP_DOWN (button), expression);
gtk_expression_unref (expression);
gtk_box_append (GTK_BOX (box), button);
gtk_widget_set_margin_start (box, 10);
gtk_widget_set_margin_end (box, 10);
gtk_widget_set_margin_top (box, 10);
gtk_widget_set_margin_bottom (box, 10);
gtk_window_set_child (GTK_WINDOW (window), box);
button = gtk_drop_down_new (NULL, NULL);
@@ -448,118 +270,30 @@ do_dropdown (GtkWidget *do_widget)
spin = gtk_spin_button_new_with_range (-1, g_list_model_get_n_items (G_LIST_MODEL (model)), 1);
gtk_widget_set_halign (spin, GTK_ALIGN_START);
gtk_widget_set_margin_start (spin, 20);
g_object_bind_property (button, "selected", spin, "value", G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
gtk_box_append (GTK_BOX (box), spin);
check = gtk_check_button_new_with_label ("Enable search");
gtk_widget_set_margin_start (check, 20);
g_object_bind_property (button, "enable-search", check, "active", G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
gtk_box_append (GTK_BOX (box), check);
g_object_unref (model);
/* A dropdown with a separate list factory */
button = drop_down_new_from_strings (device_titles, device_icons, device_descriptions);
button = drop_down_new_from_strings (times, NULL, NULL);
gtk_box_append (GTK_BOX (box), button);
gtk_box_append (GTK_BOX (hbox), gtk_separator_new (GTK_ORIENTATION_VERTICAL));
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
gtk_box_append (GTK_BOX (hbox), box);
label = gtk_label_new ("Suggestions");
gtk_widget_add_css_class (label, "title-4");
gtk_box_append (GTK_BOX (box), label);
/* A basic suggestion entry */
entry = suggestion_entry_new ();
g_object_set (entry, "placeholder-text", "Words with T or G…", NULL);
strings = gtk_string_list_new ((const char *[]){
"GNOME",
"gnominious",
"Gnomonic projection",
"total",
"totally",
"toto",
"tottery",
"totterer",
"Totten trust",
"totipotent",
"totipotency",
"totemism",
"totem pole",
"Totara",
"totalizer",
"totalizator",
"totalitarianism",
"total parenteral nutrition",
"total hysterectomy",
"total eclipse",
"Totipresence",
"Totipalmi",
"Tomboy",
"zombie",
NULL});
suggestion_entry_set_model (SUGGESTION_ENTRY (entry), G_LIST_MODEL (strings));
g_object_unref (strings);
gtk_box_append (GTK_BOX (box), entry);
/* A suggestion entry using a custom model, and no filtering */
entry = suggestion_entry_new ();
cwd = g_get_current_dir ();
file = g_file_new_for_path (cwd);
dir = G_LIST_MODEL (gtk_directory_list_new ("standard::display-name,standard::content-type,standard::icon,standard::size", file));
suggestion_entry_set_model (SUGGESTION_ENTRY (entry), dir);
g_object_unref (dir);
g_object_unref (file);
g_free (cwd);
button = drop_down_new_from_strings (many_times, NULL, NULL);
gtk_drop_down_set_enable_search (GTK_DROP_DOWN (button), TRUE);
expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
0, NULL,
(GCallback)get_file_name,
(GCallback)get_title,
NULL, NULL);
suggestion_entry_set_expression (SUGGESTION_ENTRY (entry), expression);
gtk_drop_down_set_expression (GTK_DROP_DOWN (button), expression);
gtk_expression_unref (expression);
gtk_box_append (GTK_BOX (box), button);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_item), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_item), NULL);
suggestion_entry_set_factory (SUGGESTION_ENTRY (entry), factory);
g_object_unref (factory);
suggestion_entry_set_use_filter (SUGGESTION_ENTRY (entry), FALSE);
suggestion_entry_set_show_arrow (SUGGESTION_ENTRY (entry), TRUE);
gtk_box_append (GTK_BOX (box), entry);
/* A suggestion entry with match highlighting */
entry = suggestion_entry_new ();
g_object_set (entry, "placeholder-text", "Destination", NULL);
strings = gtk_string_list_new ((const char *[]){
"app-mockups",
"settings-mockups",
"os-mockups",
"software-mockups",
"mocktails",
NULL});
suggestion_entry_set_model (SUGGESTION_ENTRY (entry), G_LIST_MODEL (strings));
g_object_unref (strings);
gtk_box_append (GTK_BOX (box), entry);
suggestion_entry_set_match_func (SUGGESTION_ENTRY (entry), match_func, NULL, NULL);
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_highlight_item), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_highlight_item), NULL);
suggestion_entry_set_factory (SUGGESTION_ENTRY (entry), factory);
g_object_unref (factory);
button = drop_down_new_from_strings (device_titles, device_icons, device_descriptions);
gtk_box_append (GTK_BOX (box), button);
}
if (!gtk_widget_get_visible (window))

View File

@@ -78,11 +78,11 @@ do_entry_completion (GtkWidget *do_widget)
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_widget_set_margin_start (vbox, 18);
gtk_widget_set_margin_end (vbox, 18);
gtk_widget_set_margin_top (vbox, 18);
gtk_widget_set_margin_bottom (vbox, 18);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
gtk_widget_set_margin_start (vbox, 5);
gtk_widget_set_margin_end (vbox, 5);
gtk_widget_set_margin_top (vbox, 5);
gtk_widget_set_margin_bottom (vbox, 5);
gtk_window_set_child (GTK_WINDOW (window), vbox);
label = gtk_label_new (NULL);

View File

@@ -27,16 +27,16 @@ do_entry_undo (GtkWidget *do_widget)
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_widget_set_margin_start (vbox, 18);
gtk_widget_set_margin_end (vbox, 18);
gtk_widget_set_margin_top (vbox, 18);
gtk_widget_set_margin_bottom (vbox, 18);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
gtk_widget_set_margin_start (vbox, 5);
gtk_widget_set_margin_end (vbox, 5);
gtk_widget_set_margin_top (vbox, 5);
gtk_widget_set_margin_bottom (vbox, 5);
gtk_window_set_child (GTK_WINDOW (window), vbox);
label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label),
"Use Control+z or Control+Shift+z to undo or redo changes");
"Use Primary+z or Primary+Shift+z to undo or redo changes");
gtk_box_append (GTK_BOX (vbox), label);
/* Create our entry */

View File

@@ -1,124 +0,0 @@
/* Error States
*
* GtkLabel and GtkEntry can indicate errors if you set the .error
* style class on them.
*
* This examples shows how this can be used in a dialog for input validation.
*
* It also shows how pass callbacks and objects to GtkBuilder with
* GtkBuilderScope and gtk_builder_expose_object().
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
static void
validate_more_details (GtkEntry *entry,
GParamSpec *pspec,
GtkEntry *details)
{
if (strlen (gtk_editable_get_text (GTK_EDITABLE (entry))) > 0 &&
strlen (gtk_editable_get_text (GTK_EDITABLE (details))) == 0)
{
gtk_widget_set_tooltip_text (GTK_WIDGET (entry), "Must have details first");
gtk_widget_add_css_class (GTK_WIDGET (entry), "error");
}
else
{
gtk_widget_set_tooltip_text (GTK_WIDGET (entry), "");
gtk_widget_remove_css_class (GTK_WIDGET (entry), "error");
}
}
static gboolean
mode_switch_state_set (GtkSwitch *sw,
gboolean state,
GtkWidget *scale)
{
GtkWidget *label;
label = GTK_WIDGET (g_object_get_data (G_OBJECT (sw), "error_label"));
if (!state ||
(gtk_range_get_value (GTK_RANGE (scale)) > 50))
{
gtk_widget_hide (label);
gtk_switch_set_state (sw, state);
}
else
{
gtk_widget_show (label);
}
return TRUE;
}
static void
level_scale_value_changed (GtkRange *range,
GtkWidget *sw)
{
GtkWidget *label;
label = GTK_WIDGET (g_object_get_data (G_OBJECT (sw), "error_label"));
if (gtk_switch_get_active (GTK_SWITCH (sw)) &&
!gtk_switch_get_state (GTK_SWITCH (sw)) &&
(gtk_range_get_value (range) > 50))
{
gtk_widget_hide (label);
gtk_switch_set_state (GTK_SWITCH (sw), TRUE);
}
else if (gtk_switch_get_state (GTK_SWITCH (sw)) &&
(gtk_range_get_value (range) <= 50))
{
gtk_switch_set_state (GTK_SWITCH (sw), FALSE);
}
}
GtkWidget *
do_errorstates (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *toplevel;
GtkBuilder *builder;
GtkBuilderScope *scope;
GtkWidget *sw, *label;
toplevel = GTK_WIDGET (gtk_widget_get_root (do_widget));
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
"validate_more_details", G_CALLBACK (validate_more_details),
"mode_switch_state_set", G_CALLBACK (mode_switch_state_set),
"level_scale_value_changed", G_CALLBACK (level_scale_value_changed),
NULL);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
gtk_builder_expose_object (builder, "toplevel", G_OBJECT (toplevel));
gtk_builder_add_from_resource (builder, "/errorstates/errorstates.ui", NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "dialog"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
sw = GTK_WIDGET (gtk_builder_get_object (builder, "mode_switch"));
label = GTK_WIDGET (gtk_builder_get_object (builder, "error_label"));
g_object_set_data (G_OBJECT (sw), "error_label", label);
g_object_unref (builder);
g_object_unref (scope);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,158 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkDialog" id="dialog">
<property name="transient-for">toplevel</property>
<property name="modal">1</property>
<property name="resizable">0</property>
<property name="use-header-bar">1</property>
<property name="title" translatable="yes">Error States</property>
<property name="hide-on-close">1</property>
<child internal-child="content_area">
<object class="GtkBox">
<child>
<object class="GtkGrid">
<property name="row-spacing">10</property>
<property name="column-spacing">10</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
<property name="margin-top">20</property>
<property name="margin-bottom">20</property>
<child>
<object class="GtkLabel">
<property name="halign">end</property>
<property name="valign">baseline</property>
<property name="label">_Details</property>
<property name="use-underline">1</property>
<property name="mnemonic-widget">details_entry</property>
<style>
<class name="dim-label"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="details_entry">
<property name="valign">baseline</property>
<signal name="notify::text" handler="validate_more_details" object="more_details_entry" swapped="yes"/>
<layout>
<property name="column">1</property>
<property name="row">0</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">end</property>
<property name="valign">baseline</property>
<property name="label">More D_etails</property>
<property name="use-underline">1</property>
<property name="mnemonic-widget">more_details_entry</property>
<style>
<class name="dim-label"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="more_details_entry">
<property name="valign">baseline</property>
<signal name="notify::text" handler="validate_more_details" object="details_entry" swapped="no"/>
<layout>
<property name="column">1</property>
<property name="row">1</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">end</property>
<property name="valign">baseline</property>
<property name="label">_Level</property>
<property name="use-underline">1</property>
<property name="mnemonic-widget">level_scale</property>
<style>
<class name="dim-label"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale" id="level_scale">
<property name="valign">baseline</property>
<property name="draw-value">0</property>
<property name="adjustment">
<object class="GtkAdjustment">
<property name="upper">100</property>
<property name="lower">0</property>
<property name="value">50</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
</property>
<signal name="value-changed" handler="level_scale_value_changed" object="mode_switch" swapped="no"/>
<layout>
<property name="column">1</property>
<property name="row">2</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">end</property>
<property name="valign">baseline</property>
<property name="label">_Mode</property>
<property name="use-underline">1</property>
<property name="mnemonic-widget">mode_switch</property>
<style>
<class name="dim-label"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkSwitch" id="mode_switch">
<property name="halign">start</property>
<property name="valign">baseline</property>
<signal name="state-set" handler="mode_switch_state_set" object="level_scale" swapped="no"/>
<layout>
<property name="column">1</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel" id="error_label">
<property name="visible">0</property>
<property name="halign">start</property>
<property name="valign">baseline</property>
<property name="label">Level too low</property>
<style>
<class name="error"/>
</style>
<layout>
<property name="column">2</property>
<property name="row">3</property>
</layout>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -1,5 +1,4 @@
/* Tree View/Filter Model
* #Keywords: GtkTreeView
*
* This example demonstrates how GtkTreeModelFilter can be used not
* just to show a subset of the rows, but also to compute columns

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.16"/>
<object class="GtkListStore" id="liststore1">
<columns>
<column type="gint"/>

View File

@@ -9,7 +9,6 @@
#include "gtkfishbowl.h"
#include "gtkgears.h"
#include "gskshaderpaintable.h"
const char *const css =
".blurred-button {"
@@ -119,12 +118,13 @@ create_label (void)
static GtkWidget *
create_video (void)
{
GtkWidget *w = gtk_video_new ();
GtkMediaStream *stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
GtkWidget *w = gtk_picture_new_for_paintable (GDK_PAINTABLE (stream));
gtk_widget_set_size_request (w, 64, 64);
gtk_video_set_loop (GTK_VIDEO (w), TRUE);
gtk_video_set_autoplay (GTK_VIDEO (w), TRUE);
gtk_video_set_resource (GTK_VIDEO (w), "/images/gtk-logo.webm");
gtk_media_stream_set_loop (stream, TRUE);
gtk_media_stream_play (stream);
g_object_unref (stream);
return w;
}
@@ -149,38 +149,6 @@ 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)
{
@@ -217,7 +185,6 @@ static const struct {
{ "Gears", create_gears },
{ "Switch", create_switch },
{ "Menubutton", create_menu_button },
{ "Shader", create_cogs },
};
static int selected_widget_type = -1;

View File

@@ -13,13 +13,13 @@
</style>
<child>
<object class="GtkButton">
<property name="icon-name">go-previous-symbolic</property>
<property name="icon-name">pan-start-symbolic</property>
<signal name="clicked" handler="fishbowl_prev_button_clicked_cb" object="bowl" swapped="no"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">go-next-symbolic</property>
<property name="icon-name">pan-end-symbolic</property>
<signal name="clicked" handler="fishbowl_next_button_clicked_cb" object="bowl" swapped="no"/>
</object>
</child>
@@ -33,9 +33,6 @@
<lookup name="framerate">bowl</lookup>
</closure>
</binding>
<attributes>
<attribute name="font-features" value="tnum=1"/>
</attributes>
</object>
</child>
<child type="end">

View File

@@ -1,5 +1,4 @@
/* Fixed Layout
* #Keywords: GtkLayoutManager
*
* GtkFixed is a container that allows placing and transforming
* widgets manually.

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkWindow" id="window">
<property name="default-width">600</property>
<property name="default-height">500</property>
@@ -10,8 +11,12 @@
<object class="GtkButton" id="reset">
<property name="receives-default">1</property>
<property name="tooltip-text">Reset</property>
<property name="icon-name">view-refresh-symbolic</property>
<signal name="clicked" handler="font_features_reset_features" swapped="no"/>
<child>
<object class="GtkImage">
<property name="icon-name">view-refresh-symbolic</property>
</object>
</child>
</object>
</child>
</object>

View File

@@ -1068,6 +1068,7 @@ update_font_variations (void)
unsigned int length;
int i;
child = gtk_widget_get_first_child (variations_grid);
while ((child = gtk_widget_get_first_child (variations_grid)))
gtk_grid_remove (GTK_GRID (variations_grid), child);
@@ -1136,7 +1137,7 @@ done:
g_free (design_coords);
}
G_MODULE_EXPORT void
void
font_features_font_changed (void)
{
update_script_combo ();
@@ -1144,14 +1145,14 @@ font_features_font_changed (void)
update_font_variations ();
}
G_MODULE_EXPORT void
void
font_features_script_changed (void)
{
update_features ();
update_display ();
}
G_MODULE_EXPORT void
void
font_features_reset_features (void)
{
GList *l;
@@ -1197,7 +1198,7 @@ switch_to_label (void)
update_display ();
}
G_MODULE_EXPORT void
void
font_features_toggle_edit (void)
{
if (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (stack)), "label") == 0)
@@ -1206,7 +1207,7 @@ font_features_toggle_edit (void)
switch_to_label ();
}
G_MODULE_EXPORT void
void
font_features_stop_edit (void)
{
g_signal_emit_by_name (edit_toggle, "clicked");

View File

@@ -24,29 +24,15 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
GtkTextIter *end)
{
GtkTextTagTable *table;
GSList *attrs, *l;
PangoAttribute *attr;
GtkTextTag *tag;
char name[256];
float fg_alpha, bg_alpha;
table = gtk_text_buffer_get_tag_table (buffer);
#define LANGUAGE_ATTR(attr_name) \
{ \
const char *language = pango_language_to_string (((PangoAttrLanguage*)attr)->value); \
g_snprintf (name, 256, "language=%s", language); \
tag = gtk_text_tag_table_lookup (table, name); \
if (!tag) \
{ \
tag = gtk_text_tag_new (name); \
g_object_set (tag, #attr_name, language, NULL); \
gtk_text_tag_table_add (table, tag); \
g_object_unref (tag); \
} \
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
#define STRING_ATTR(attr_name) \
#define STRING_ATTR(pango_attr_name, attr_name) \
attr = pango_attr_iterator_get (iter, pango_attr_name); \
if (attr) \
{ \
const char *string = ((PangoAttrString*)attr)->value; \
g_snprintf (name, 256, #attr_name "=%s", string); \
@@ -61,7 +47,9 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
#define INT_ATTR(attr_name) \
#define INT_ATTR(pango_attr_name, attr_name) \
attr = pango_attr_iterator_get (iter, pango_attr_name); \
if (attr) \
{ \
int value = ((PangoAttrInt*)attr)->value; \
g_snprintf (name, 256, #attr_name "=%d", value); \
@@ -76,24 +64,9 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
#define FONT_ATTR(attr_name) \
{ \
PangoFontDescription *desc = ((PangoAttrFontDesc*)attr)->desc; \
char *str = pango_font_description_to_string (desc); \
g_snprintf (name, 256, "font-desc=%s", str); \
g_free (str); \
tag = gtk_text_tag_table_lookup (table, name); \
if (!tag) \
{ \
tag = gtk_text_tag_new (name); \
g_object_set (tag, #attr_name, desc, NULL); \
gtk_text_tag_table_add (table, tag); \
g_object_unref (tag); \
} \
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
#define FLOAT_ATTR(attr_name) \
#define FLOAT_ATTR(pango_attr_name, attr_name) \
attr = pango_attr_iterator_get (iter, pango_attr_name); \
if (attr) \
{ \
float value = ((PangoAttrFloat*)attr)->value; \
g_snprintf (name, 256, #attr_name "=%g", value); \
@@ -108,7 +81,9 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
#define RGBA_ATTR(attr_name, alpha_value) \
#define RGBA_ATTR(pango_attr_name, attr_name) \
attr = pango_attr_iterator_get (iter, pango_attr_name); \
if (attr) \
{ \
PangoColor *color; \
GdkRGBA rgba; \
@@ -116,7 +91,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
rgba.red = color->red / 65535.; \
rgba.green = color->green / 65535.; \
rgba.blue = color->blue / 65535.; \
rgba.alpha = alpha_value; \
rgba.alpha = 1.; \
char *str = gdk_rgba_to_string (&rgba); \
g_snprintf (name, 256, #attr_name "=%s", str); \
g_free (str); \
@@ -131,193 +106,63 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
#define VOID_ATTR(attr_name) \
{ \
tag = gtk_text_tag_table_lookup (table, #attr_name); \
if (!tag) \
{ \
tag = gtk_text_tag_new (#attr_name); \
g_object_set (tag, #attr_name, TRUE, NULL); \
gtk_text_tag_table_add (table, tag); \
g_object_unref (tag); \
} \
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
fg_alpha = bg_alpha = 1.;
attrs = pango_attr_iterator_get_attrs (iter);
for (l = attrs; l; l = l->next)
attr = pango_attr_iterator_get (iter, PANGO_ATTR_LANGUAGE);
if (attr)
{
PangoAttribute *attr = l->data;
switch ((int)attr->klass->type)
const char *language = pango_language_to_string (((PangoAttrLanguage*)attr)->value);
g_snprintf (name, 256, "language=%s", language);
tag = gtk_text_tag_table_lookup (table, name);
if (!tag)
{
case PANGO_ATTR_FOREGROUND_ALPHA:
fg_alpha = ((PangoAttrInt*)attr)->value / 65535.;
break;
case PANGO_ATTR_BACKGROUND_ALPHA:
bg_alpha = ((PangoAttrInt*)attr)->value / 65535.;
break;
default:
break;
tag = gtk_text_tag_new (name);
g_object_set (tag, "language", language, NULL);
gtk_text_tag_table_add (table, tag);
g_object_unref (tag);
}
gtk_text_buffer_apply_tag (buffer, tag, start, end);
}
for (l = attrs; l; l = l->next)
STRING_ATTR (PANGO_ATTR_FAMILY, family)
INT_ATTR (PANGO_ATTR_STYLE, style)
INT_ATTR (PANGO_ATTR_WEIGHT, weight)
INT_ATTR (PANGO_ATTR_VARIANT, variant)
INT_ATTR (PANGO_ATTR_STRETCH, stretch)
INT_ATTR (PANGO_ATTR_SIZE, size)
attr = pango_attr_iterator_get (iter, PANGO_ATTR_FONT_DESC);
if (attr)
{
PangoAttribute *attr = l->data;
switch (attr->klass->type)
PangoFontDescription *desc = ((PangoAttrFontDesc*)attr)->desc;
char *str = pango_font_description_to_string (desc);
g_snprintf (name, 256, "font-desc=%s", str);
g_free (str);
tag = gtk_text_tag_table_lookup (table, name);
if (!tag)
{
case PANGO_ATTR_LANGUAGE:
LANGUAGE_ATTR (language);
break;
case PANGO_ATTR_FAMILY:
STRING_ATTR (family);
break;
case PANGO_ATTR_STYLE:
INT_ATTR (style);
break;
case PANGO_ATTR_WEIGHT:
INT_ATTR (weight);
break;
case PANGO_ATTR_VARIANT:
INT_ATTR (variant);
break;
case PANGO_ATTR_STRETCH:
INT_ATTR (stretch);
break;
case PANGO_ATTR_SIZE:
INT_ATTR (size);
break;
case PANGO_ATTR_FONT_DESC:
FONT_ATTR (font-desc);
break;
case PANGO_ATTR_FOREGROUND:
RGBA_ATTR (foreground_rgba, fg_alpha);
break;
case PANGO_ATTR_BACKGROUND:
RGBA_ATTR (background_rgba, bg_alpha);
break;
case PANGO_ATTR_UNDERLINE:
INT_ATTR (underline);
break;
case PANGO_ATTR_UNDERLINE_COLOR:
RGBA_ATTR (underline_rgba, fg_alpha);
break;
case PANGO_ATTR_OVERLINE:
INT_ATTR (overline);
break;
case PANGO_ATTR_OVERLINE_COLOR:
RGBA_ATTR (overline_rgba, fg_alpha);
break;
case PANGO_ATTR_STRIKETHROUGH:
INT_ATTR (strikethrough);
break;
case PANGO_ATTR_STRIKETHROUGH_COLOR:
RGBA_ATTR (strikethrough_rgba, fg_alpha);
break;
case PANGO_ATTR_RISE:
INT_ATTR (rise);
break;
case PANGO_ATTR_SCALE:
FLOAT_ATTR (scale);
break;
case PANGO_ATTR_FALLBACK:
INT_ATTR (fallback);
break;
case PANGO_ATTR_LETTER_SPACING:
INT_ATTR (letter_spacing);
break;
case PANGO_ATTR_FONT_FEATURES:
STRING_ATTR (font_features);
break;
case PANGO_ATTR_ALLOW_BREAKS:
INT_ATTR (allow_breaks);
break;
case PANGO_ATTR_SHOW:
INT_ATTR (show_spaces);
break;
case PANGO_ATTR_INSERT_HYPHENS:
INT_ATTR (insert_hyphens);
break;
case PANGO_ATTR_LINE_HEIGHT:
FLOAT_ATTR (line_height);
break;
case PANGO_ATTR_ABSOLUTE_LINE_HEIGHT:
break;
case PANGO_ATTR_WORD:
VOID_ATTR (word);
break;
case PANGO_ATTR_SENTENCE:
VOID_ATTR (sentence);
break;
case PANGO_ATTR_BASELINE_SHIFT:
INT_ATTR (baseline_shift);
break;
case PANGO_ATTR_FONT_SCALE:
INT_ATTR (font_scale);
break;
case PANGO_ATTR_SHAPE:
case PANGO_ATTR_ABSOLUTE_SIZE:
case PANGO_ATTR_GRAVITY:
case PANGO_ATTR_GRAVITY_HINT:
case PANGO_ATTR_FOREGROUND_ALPHA:
case PANGO_ATTR_BACKGROUND_ALPHA:
break;
case PANGO_ATTR_TEXT_TRANSFORM:
INT_ATTR (text_transform);
break;
case PANGO_ATTR_INVALID:
default:
g_assert_not_reached ();
break;
tag = gtk_text_tag_new (name);
g_object_set (tag, "font-desc", desc, NULL);
gtk_text_tag_table_add (table, tag);
g_object_unref (tag);
}
gtk_text_buffer_apply_tag (buffer, tag, start, end);
}
g_slist_free_full (attrs, (GDestroyNotify)pango_attribute_destroy);
#undef LANGUAGE_ATTR
#undef STRING_ATTR
#undef INT_ATTR
#undef FONT_ATTR
#undef FLOAT_ATTR
#undef RGBA_ATTR
RGBA_ATTR (PANGO_ATTR_FOREGROUND, foreground_rgba)
RGBA_ATTR (PANGO_ATTR_BACKGROUND, background_rgba)
INT_ATTR (PANGO_ATTR_UNDERLINE, underline)
RGBA_ATTR (PANGO_ATTR_UNDERLINE_COLOR, underline_rgba)
INT_ATTR (PANGO_ATTR_OVERLINE, overline)
RGBA_ATTR (PANGO_ATTR_OVERLINE_COLOR, overline_rgba)
INT_ATTR (PANGO_ATTR_STRIKETHROUGH, strikethrough)
RGBA_ATTR (PANGO_ATTR_STRIKETHROUGH_COLOR, strikethrough_rgba)
INT_ATTR (PANGO_ATTR_RISE, rise)
FLOAT_ATTR (PANGO_ATTR_SCALE, scale)
INT_ATTR (PANGO_ATTR_FALLBACK, fallback)
INT_ATTR (PANGO_ATTR_LETTER_SPACING, letter_spacing)
STRING_ATTR (PANGO_ATTR_FONT_FEATURES, font_features)
INT_ATTR (PANGO_ATTR_ALLOW_BREAKS, allow_breaks)
INT_ATTR (PANGO_ATTR_SHOW, show_spaces)
INT_ATTR (PANGO_ATTR_INSERT_HYPHENS, insert_hyphens)
}
typedef struct
@@ -541,7 +386,7 @@ fontify (const char *format,
char *theme;
gboolean prefer_dark;
const char *style_arg;
char *text;
const char *text;
GtkTextIter start, end;
GBytes *bytes;
GError *error = NULL;
@@ -593,7 +438,7 @@ fontify (const char *format,
gtk_text_buffer_get_bounds (source_buffer, &start, &end);
text = gtk_text_buffer_get_text (source_buffer, &start, &end, TRUE);
bytes = g_bytes_new_take (text, strlen (text));
bytes = g_bytes_new_static (text, strlen (text));
#ifdef HAVE_GIO_UNIX
/* Work around https://gitlab.gnome.org/GNOME/glib/-/issues/2182 */
@@ -610,5 +455,4 @@ fontify (const char *format,
NULL,
fontify_finish,
g_object_ref (source_buffer));
g_bytes_unref (bytes);
}

View File

@@ -1,11 +1,6 @@
/* Pango/Font Rendering
/* Pango/Font rendering
*
* Demonstrates various aspects of font rendering,
* such as hinting, antialiasing and grid alignment.
*
* The demo lets you explore font rendering options
* interactively to get a feeling for they affect the
* shape and positioning of the glyphs.
* Demonstrates various aspects of font rendering.
*/
#include <gtk/gtk.h>
@@ -15,21 +10,16 @@ static GtkWidget *font_button = NULL;
static GtkWidget *entry = NULL;
static GtkWidget *image = NULL;
static GtkWidget *hinting = NULL;
static GtkWidget *anti_alias = NULL;
static GtkWidget *hint_metrics = NULL;
static GtkWidget *up_button = NULL;
static GtkWidget *down_button = NULL;
static GtkWidget *text_radio = NULL;
static GtkWidget *show_grid = NULL;
static GtkWidget *show_extents = NULL;
static GtkWidget *show_pixels = NULL;
static GtkWidget *show_outlines = NULL;
static PangoContext *context;
static int scale = 7;
static double pixel_alpha = 1.0;
static double outline_alpha = 0.0;
static int scale = 9;
static void
update_image (void)
@@ -37,7 +27,7 @@ update_image (void)
const char *text;
PangoFontDescription *desc;
PangoLayout *layout;
PangoRectangle ink, logical;
PangoRectangle ink, pink, logical;
int baseline;
cairo_surface_t *surface;
cairo_t *cr;
@@ -47,8 +37,6 @@ update_image (void)
cairo_font_options_t *fopt;
cairo_hint_style_t hintstyle;
cairo_hint_metrics_t hintmetrics;
cairo_antialias_t antialias;
cairo_path_t *path;
if (!context)
context = gtk_widget_create_pango_context (image);
@@ -77,13 +65,6 @@ update_image (void)
hintmetrics = CAIRO_HINT_METRICS_OFF;
cairo_font_options_set_hint_metrics (fopt, hintmetrics);
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (anti_alias)))
antialias = CAIRO_ANTIALIAS_GRAY;
else
antialias = CAIRO_ANTIALIAS_NONE;
cairo_font_options_set_antialias (fopt, antialias);
pango_context_set_round_glyph_positions (context, hintmetrics == CAIRO_HINT_METRICS_ON);
pango_cairo_context_set_font_options (context, fopt);
cairo_font_options_destroy (fopt);
pango_context_changed (context);
@@ -94,6 +75,7 @@ update_image (void)
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, text, -1);
pango_layout_get_extents (layout, &ink, &logical);
pink = ink;
baseline = pango_layout_get_baseline (layout);
pango_extents_to_pixels (&ink, NULL);
@@ -103,14 +85,10 @@ update_image (void)
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
cairo_set_source_rgba (cr, 0, 0, 0, pixel_alpha);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_move_to (cr, 10, 10);
pango_cairo_show_layout (cr, layout);
pango_cairo_layout_path (cr, layout);
path = cairo_copy_path (cr);
cairo_destroy (cr);
g_object_unref (layout);
@@ -149,7 +127,7 @@ update_image (void)
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (show_extents)))
{
cairo_set_source_rgb (cr, 0, 0, 1);
cairo_set_source_rgba (cr, 0, 0, 1, 1);
cairo_rectangle (cr,
scale * (10 + pango_units_to_double (logical.x)) - 0.5,
@@ -162,45 +140,17 @@ update_image (void)
cairo_line_to (cr, scale * (10 + pango_units_to_double (logical.x + logical.width)) + 1,
scale * (10 + pango_units_to_double (baseline)) - 0.5);
cairo_stroke (cr);
cairo_set_source_rgb (cr, 1, 0, 0);
cairo_set_source_rgba (cr, 1, 0, 0, 1);
cairo_rectangle (cr,
scale * (10 + ink.x) - 0.5,
scale * (10 + ink.y) - 0.5,
scale * ink.width + 1,
scale * ink.height + 1);
scale * (10 + pango_units_to_double (pink.x)) + 0.5,
scale * (10 + pango_units_to_double (pink.y)) + 0.5,
scale * pango_units_to_double (pink.width) - 1,
scale * pango_units_to_double (pink.height) - 1);
cairo_stroke (cr);
}
for (int i = 0; i < path->num_data; i += path->data[i].header.length)
{
cairo_path_data_t *data = &path->data[i];
switch (data->header.type)
{
case CAIRO_PATH_CURVE_TO:
data[3].point.x *= scale; data[3].point.y *= scale;
data[2].point.x *= scale; data[2].point.y *= scale;
data[1].point.x *= scale; data[1].point.y *= scale;
break;
case CAIRO_PATH_LINE_TO:
case CAIRO_PATH_MOVE_TO:
data[1].point.x *= scale; data[1].point.y *= scale;
break;
case CAIRO_PATH_CLOSE_PATH:
break;
default:
g_assert_not_reached ();
}
}
cairo_set_source_rgba (cr, 0, 0, 0, outline_alpha);
cairo_move_to (cr, scale * 20 - 0.5, scale * 20 - 0.5);
cairo_append_path (cr, path);
cairo_stroke (cr);
cairo_surface_destroy (surface);
cairo_destroy (cr);
cairo_path_destroy (path);
}
else
{
@@ -208,26 +158,10 @@ update_image (void)
PangoLayoutRun *run;
PangoGlyphInfo *g;
int i, j;
GString *str;
gunichar ch;
if (*text == '\0')
text = " ";
ch = g_utf8_get_char (text);
str = g_string_new ("");
for (i = 0; i < 4; i++)
{
g_string_append_unichar (str, ch);
g_string_append_unichar (str, 0x200c);
}
layout = pango_layout_new (context);
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, str->str, -1);
g_string_free (str, TRUE);
pango_layout_set_text (layout, "aaaa", -1);
pango_layout_get_extents (layout, &ink, &logical);
pango_extents_to_pixels (&logical, NULL);
@@ -242,7 +176,7 @@ update_image (void)
cairo_set_source_rgb (cr, 0, 0, 0);
for (i = 0; i < 4; i++)
{
g = &(run->glyphs->glyphs[2*i]);
g = &(run->glyphs->glyphs[i]);
g->geometry.width = PANGO_UNITS_ROUND (g->geometry.width * 3 / 2);
}
@@ -250,7 +184,7 @@ update_image (void)
{
for (i = 0; i < 4; i++)
{
g = &(run->glyphs->glyphs[2*i]);
g = &(run->glyphs->glyphs[i]);
g->geometry.x_offset = i * (PANGO_SCALE / 4);
g->geometry.y_offset = j * (PANGO_SCALE / 4);
}
@@ -269,6 +203,7 @@ update_image (void)
cairo_surface_destroy (surface);
}
gtk_picture_set_pixbuf (GTK_PICTURE (image), pixbuf2);
g_object_unref (pixbuf2);
@@ -276,78 +211,6 @@ update_image (void)
pango_font_description_free (desc);
}
static gboolean fading = FALSE;
static double start_pixel_alpha;
static double end_pixel_alpha;
static double start_outline_alpha;
static double end_outline_alpha;
static gint64 start_time;
static gint64 end_time;
static double
ease_out_cubic (double t)
{
double p = t - 1;
return p * p * p + 1;
}
static gboolean
change_alpha (GtkWidget *widget,
GdkFrameClock *clock,
gpointer user_data)
{
gint64 now = g_get_monotonic_time ();
double t;
t = ease_out_cubic ((now - start_time) / (double) (end_time - start_time));
pixel_alpha = start_pixel_alpha + (end_pixel_alpha - start_pixel_alpha) * t;
outline_alpha = start_outline_alpha + (end_outline_alpha - start_outline_alpha) * t;
update_image ();
if (now >= end_time)
{
fading = FALSE;
return G_SOURCE_REMOVE;
}
return G_SOURCE_CONTINUE;
}
static void
start_alpha_fade (void)
{
gboolean pixels;
gboolean outlines;
if (fading)
return;
pixels = gtk_check_button_get_active (GTK_CHECK_BUTTON (show_pixels));
outlines = gtk_check_button_get_active (GTK_CHECK_BUTTON (show_outlines));
start_pixel_alpha = pixel_alpha;
if (pixels && outlines)
end_pixel_alpha = 0.5;
else if (pixels)
end_pixel_alpha = 1;
else
end_pixel_alpha = 0;
start_outline_alpha = outline_alpha;
if (outlines)
end_outline_alpha = 1.0;
else
end_outline_alpha = 0.0;
start_time = g_get_monotonic_time ();
end_time = start_time + G_TIME_SPAN_SECOND / 2;
fading = TRUE;
gtk_widget_add_tick_callback (window, change_alpha, NULL, NULL);
}
static void
update_buttons (void)
{
@@ -355,26 +218,20 @@ update_buttons (void)
gtk_widget_set_sensitive (down_button, scale > 1);
}
static gboolean
scale_up (GtkWidget *widget,
GVariant *args,
gpointer user_data)
static void
scale_up (void)
{
scale += 1;
update_buttons ();
update_image ();
return TRUE;
}
static gboolean
scale_down (GtkWidget *widget,
GVariant *args,
gpointer user_data)
static void
scale_down (void)
{
scale -= 1;
update_buttons ();
update_image ();
return TRUE;
}
GtkWidget *
@@ -395,26 +252,20 @@ do_fontrendering (GtkWidget *do_widget)
entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
image = GTK_WIDGET (gtk_builder_get_object (builder, "image"));
hinting = GTK_WIDGET (gtk_builder_get_object (builder, "hinting"));
anti_alias = GTK_WIDGET (gtk_builder_get_object (builder, "antialias"));
hint_metrics = GTK_WIDGET (gtk_builder_get_object (builder, "hint_metrics"));
text_radio = GTK_WIDGET (gtk_builder_get_object (builder, "text_radio"));
show_grid = GTK_WIDGET (gtk_builder_get_object (builder, "show_grid"));
show_extents = GTK_WIDGET (gtk_builder_get_object (builder, "show_extents"));
show_pixels = GTK_WIDGET (gtk_builder_get_object (builder, "show_pixels"));
show_outlines = GTK_WIDGET (gtk_builder_get_object (builder, "show_outlines"));
g_signal_connect (up_button, "clicked", G_CALLBACK (scale_up), NULL);
g_signal_connect (down_button, "clicked", G_CALLBACK (scale_down), NULL);
g_signal_connect (entry, "notify::text", G_CALLBACK (update_image), NULL);
g_signal_connect (font_button, "notify::font-desc", G_CALLBACK (update_image), NULL);
g_signal_connect (hinting, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (anti_alias, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (hint_metrics, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (text_radio, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (show_grid, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (show_extents, "notify::active", G_CALLBACK (update_image), NULL);
g_signal_connect (show_pixels, "notify::active", G_CALLBACK (start_alpha_fade), NULL);
g_signal_connect (show_outlines, "notify::active", G_CALLBACK (start_alpha_fade), NULL);
update_image ();

View File

@@ -1,8 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkAdjustment" id="scale_adj">
<property name="upper">24</property>
<property name="step-increment">1</property>
<property name="page-increment">4</property>
</object>
<object class="GtkWindow" id="window">
<property name="default-width">1024</property>
<property name="default-height">768</property>
<property name="default-width">1080</property>
<property name="default-height">430</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child type="title">
@@ -82,119 +87,69 @@
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_pixels">
<property name="label">Show _Pixels</property>
<property name="use-underline">1</property>
<property name="active">1</property>
<object class="GtkLabel">
<property name="label">Hinting</property>
<property name="xalign">1</property>
<style>
<class name="dim-label"/>
</style>
<layout>
<property name="column">3</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_outlines">
<property name="label">Show _Outline</property>
<property name="use-underline">1</property>
<layout>
<property name="column">3</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="label">_Hinting</property>
<property name="use-underline">1</property>
<property name="mnemonic-widget">hinting</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="hinting">
<property name="active">0</property>
<property name="valign">center</property>
<items>
<item translatable="yes" id="none">None</item>
<item translatable="yes" id="slight">Slight</item>
<item translatable="yes" id="medium">Medium</item>
<item translatable="yes" id="full">Full</item>
</items>
</object>
</child>
<object class="GtkComboBoxText" id="hinting">
<property name="active">0</property>
<property name="valign">center</property>
<items>
<item translatable="yes" id="none">None</item>
<item translatable="yes" id="slight">Slight</item>
<item translatable="yes" id="medium">Medium</item>
<item translatable="yes" id="full">Full</item>
</items>
<layout>
<property name="column">4</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="antialias">
<property name="label">_Antialias</property>
<property name="use-underline">1</property>
<property name="active">1</property>
<layout>
<property name="column">4</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="hint_metrics">
<property name="label">Hint _Metrics</property>
<property name="use-underline">1</property>
<property name="label">Hint Metrics</property>
<layout>
<property name="column">4</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_extents">
<property name="label">Show Extents</property>
<property name="active">1</property>
<layout>
<property name="column">5</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_grid">
<property name="active">1</property>
<property name="label">Show Grid</property>
<layout>
<property name="column">5</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_extents">
<property name="label">Show _Extents</property>
<property name="use-underline">1</property>
<layout>
<property name="column">6</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkCheckButton" id="show_grid">
<property name="label">Show _Grid</property>
<property name="use-underline">1</property>
<layout>
<property name="column">6</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton" id="up_button">
<property name="icon-name">list-add-symbolic</property>
<property name="halign">center</property>
<property name="valign">center</property>
<style>
<class name="circular"/>
</style>
<child>
<object class="GtkShortcutController">
<property name="scope">managed</property>
<child>
<object class="GtkShortcut">
<property name="trigger">&lt;Control&gt;plus</property>
<property name="action">activate</property>
</object>
</child>
</object>
</child>
<layout>
<property name="column">7</property>
<property name="column">6</property>
<property name="row">0</property>
</layout>
</object>
@@ -202,24 +157,11 @@
<child>
<object class="GtkButton" id="down_button">
<property name="icon-name">list-remove-symbolic</property>
<property name="halign">center</property>
<property name="valign">center</property>
<style>
<class name="circular"/>
</style>
<child>
<object class="GtkShortcutController">
<property name="scope">managed</property>
<child>
<object class="GtkShortcut">
<property name="trigger">&lt;Control&gt;minus</property>
<property name="action">activate</property>
</object>
</child>
</object>
</child>
<layout>
<property name="column">7</property>
<property name="column">6</property>
<property name="row">1</property>
</layout>
</object>
@@ -228,7 +170,7 @@
<object class="GtkLabel">
<property name="hexpand">1</property>
<layout>
<property name="column">8</property>
<property name="column">7</property>
</layout>
</object>
</child>

View File

@@ -1,165 +0,0 @@
/* Benchmark/Frames
*
* This demo is intentionally as simple as possible, to see what
* framerate the windowing system can deliver on its own.
*
* It does nothing but change the drawn color, for every frame.
*/
#include <gtk/gtk.h>
typedef struct
{
GtkWidget parent_instance;
GdkRGBA color1;
GdkRGBA color2;
guint64 time2;
float t;
guint tick_cb;
} ColorWidget;
typedef struct
{
GtkWidgetClass parent_class;
} ColorWidgetClass;
G_DEFINE_TYPE (ColorWidget, color_widget, GTK_TYPE_WIDGET)
#define TIME_SPAN (3.0 * G_TIME_SPAN_SECOND)
static gboolean
change_color (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer data)
{
ColorWidget *color = (ColorWidget *)widget;
gint64 time;
time = gdk_frame_clock_get_frame_time (frame_clock);
if (time >= color->time2)
{
color->time2 = time + TIME_SPAN;
color->color1 = color->color2;
color->color2.red = g_random_double_range (0, 1);
color->color2.green = g_random_double_range (0, 1);
color->color2.blue = g_random_double_range (0, 1);
color->color2.alpha = 1;
}
color->t = 1 - (color->time2 - time) / TIME_SPAN;
gtk_widget_queue_draw (widget);
return G_SOURCE_CONTINUE;
}
static void
color_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
ColorWidget *color = (ColorWidget *)widget;
float w, h;
GdkRGBA c;
w = gtk_widget_get_width (widget);
h = gtk_widget_get_height (widget);
c.red = (1 - color->t) * color->color1.red + color->t * color->color2.red;
c.green = (1 - color->t) * color->color1.green + color->t * color->color2.green;
c.blue = (1 - color->t) * color->color1.blue + color->t * color->color2.blue;
c.alpha = 1;
gtk_snapshot_append_color (snapshot, &c, &GRAPHENE_RECT_INIT (0, 0, w, h));
}
static void
color_widget_init (ColorWidget *color)
{
gtk_widget_add_tick_callback (GTK_WIDGET (color), change_color, NULL, NULL);
gtk_widget_set_hexpand (GTK_WIDGET (color), TRUE);
gtk_widget_set_vexpand (GTK_WIDGET (color), TRUE);
}
static void
color_widget_class_init (ColorWidgetClass *class)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
widget_class->snapshot = color_widget_snapshot;
}
GtkWidget *
color_widget_new (void)
{
return g_object_new (color_widget_get_type (), NULL);
}
static gboolean
update_fps_label (gpointer data)
{
GtkWidget *label = GTK_WIDGET (data);
GdkFrameClock *frame_clock;
frame_clock = gtk_widget_get_frame_clock (label);
if (frame_clock)
{
char *fps;
fps = g_strdup_printf ("%.2f fps", gdk_frame_clock_get_fps (frame_clock));
gtk_label_set_label (GTK_LABEL (label), fps);
g_free (fps);
}
else
gtk_label_set_label (GTK_LABEL (label), "");
return G_SOURCE_CONTINUE;
}
static void
remove_id (gpointer data)
{
guint id = GPOINTER_TO_UINT (data);
g_source_remove (id);
}
GtkWidget *
do_frames (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkBuilder *builder;
GtkWidget *box;
GtkWidget *label;
guint id;
builder = gtk_builder_new_from_resource ("/frames/frames.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
label = GTK_WIDGET (gtk_builder_get_object (builder, "fps"));
box = GTK_WIDGET (gtk_builder_get_object (builder, "box"));
gtk_box_append (GTK_BOX (box), color_widget_new ());
id = g_timeout_add (500, update_fps_label, label);
g_object_set_data_full (G_OBJECT (label), "tick_cb",
GUINT_TO_POINTER (id), remove_id);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="resizable">1</property>
<property name="default-width">600</property>
<property name="default-height">400</property>
<property name="title">Frames</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<child type="end">
<object class="GtkLabel" id="fps">
<attributes>
<attribute name="font-features" value="tnum=1"/>
</attributes>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="box">
</object>
</child>
</object>
</interface>

View File

@@ -6,22 +6,6 @@ import re
import os
from collections import *
def add_quotes(s):
return "\"" + s.lower() + "\""
def wordify(s):
return s.strip().rstrip(".,;:")
def is_keyword(s):
if s == "GTK":
return False
elif s.startswith(("Gtk", "Gdk", "Pango")):
return True
elif s.startswith("G") and s[1].isupper():
return True
else:
return False
out_file = sys.argv[1]
in_files = sys.argv[2:]
@@ -35,14 +19,13 @@ struct _DemoData
{
const char *name;
const char *title;
const char **keywords;
const char *filename;
GDoDemoFunc func;
DemoData *children;
};
"""
# Demo = namedtuple('Demo', ['name', 'title', 'keywords', 'file', 'func'])
# Demo = namedtuple('Demo', ['name', 'title', 'file', 'func'])
demos = []
@@ -51,17 +34,14 @@ for demo_file in in_files:
demo_name = filename.replace(".c", "")
with open(demo_file, 'r', encoding='utf-8') as f:
title = f.readline().replace("/*", "").strip()
keywords = set()
line = f.readline().strip();
while not line.endswith('*/'):
if line.startswith("* #Keywords:"):
keywords = keywords.union(set(map(wordify, line.replace ("* #Keywords:", "").strip().split(","))))
else:
keywords = keywords.union(set(filter(is_keyword, map(wordify, line.replace ("* ", "").split()))))
line = f.readline().strip()
file_output += "GtkWidget *do_" + demo_name + " (GtkWidget *do_widget);\n"
demos.append((demo_name, title, keywords, filename, "do_" + demo_name, -1))
# demos += Demo(name = demo_name,
# title = title,
# file = demo_file,
# func = "do_" + title)
demos.append((demo_name, title, filename, "do_" + demo_name, -1))
# Generate a List of "Parent names"
parents = []
@@ -77,7 +57,7 @@ for demo in demos:
if not parent_name in parents:
parents.append(parent_name)
parent_ids.append(parent_index)
demos.append(("NULL", parent_name, set(), "NULL", "NULL", parent_index))
demos.append(("NULL", parent_name, "NULL", "NULL", parent_index))
parent_index = parent_index + 1
@@ -91,7 +71,8 @@ for parent in parents:
for child in demos:
if child[1].startswith(parent + "/"):
title = child[1][child[1].rfind('/') + 1:]
file_output += " { \"" + child[0] + "\", \"" + title + "\", " + "(const char*[]) {" + ", ".join(list(map(add_quotes, child[2])) + ["NULL"]) + " }, \"" + child[3] + "\", " + child[4] + ", NULL },\n"
file_output += " { \"" + child[0] + "\", \"" + title + "\", \"" + child[2] + "\", " + child[3] + ", NULL },\n"
file_output += " { NULL }\n};\n"
i = i + 1
@@ -105,10 +86,9 @@ for demo in demos:
# Do not generate one of these for demos with a parent demo
if "/" not in demo[1]:
child_array = "NULL"
name = demo[0]
title = demo[1]
keywords = demo[2]
file = demo[3]
name = demo[0];
title = demo[1];
file = demo[2]
if name != "NULL":
name = "\"" + name + "\""
if title != "NULL":
@@ -116,9 +96,9 @@ for demo in demos:
if file != "NULL":
file = "\"" + file + "\""
if demo[5] != -1:
child_array = "child" + str(demo[5])
file_output += " { " + name + ", " + title + ", " + "(const char*[]) {" + ", ".join(list(map(add_quotes, keywords)) + ["NULL"]) + " }, " + file + ", " + demo[4] + ", " + child_array + " },\n"
if demo[4] != -1:
child_array = "child" + str(demo[4])
file_output += " { " + name + ", " + title + ", " + file + ", " + demo[3] + ", " + child_array + " },\n"
file_output += " { NULL }\n};\n"

View File

@@ -1,5 +1,4 @@
/* Gestures
* #Keywords: GtkGesture
*
* Perform gestures on touchscreens and other input devices. This
* demo reacts to long presses and swipes from all devices, plus

View File

@@ -406,7 +406,6 @@ create_glarea_window (GtkWidget *do_widget)
gl_area = gtk_gl_area_new ();
gtk_widget_set_hexpand (gl_area, TRUE);
gtk_widget_set_vexpand (gl_area, TRUE);
gtk_widget_set_size_request (gl_area, 100, 200);
gtk_box_append (GTK_BOX (box), gl_area);
/* We need to initialize and free GL resources, so we use

View File

@@ -1,174 +0,0 @@
// Originally from: https://www.shadertoy.com/view/ttBcRV
// License CC0: Flying through glowing stars
// The result of playing around trying to improve an old shader
#define PI 3.141592654
#define TAU (2.0*PI)
#define TIME iTime
#define RESOLUTION iResolution
#define LESS(a,b,c) mix(a,b,step(0.,c))
#define SABS(x,k) LESS((.5/(k))*(x)*(x)+(k)*.5,abs(x),abs(x)-(k))
#define MROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
vec3 hsv2rgb(vec3 c) {
const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
float hash(in vec3 co) {
return fract(sin(dot(co, vec3(12.9898,58.233, 12.9898+58.233))) * 13758.5453);
}
float starn(vec2 p, float r, int n, float m) {
// From IQ: https://www.shadertoy.com/view/3tSGDy
// https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm
// Minor tweak to use SABS over abs to smooth inner corners
// SABS: https://www.shadertoy.com/view/Ws2SDK
// next 4 lines can be precomputed for a given shape
float an = 3.141593/float(n);
float en = 3.141593/m; // m is between 2 and n
vec2 acs = vec2(cos(an),sin(an));
vec2 ecs = vec2(cos(en),sin(en)); // ecs=vec2(0,1) for regular polygon,
float bn = mod(atan(p.x,p.y),2.0*an) - an;
p = length(p)*vec2(cos(bn),SABS(sin(bn), 0.15));
p -= r*acs;
p += ecs*clamp( -dot(p,ecs), 0.0, r*acs.y/ecs.y);
return length(p)*sign(p.x);
}
vec4 alphaBlend(vec4 back, vec4 front) {
vec3 xyz = mix(back.xyz*back.w, front.xyz, front.w);
float w = mix(back.w, 1.0, front.w);
return vec4(xyz, w);
}
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);
}
vec3 offset(float z) {
float a = z;
vec2 p = -0.075*(vec2(cos(a), sin(a*sqrt(2.0))) + vec2(cos(a*sqrt(0.75)), sin(a*sqrt(0.5))));
return vec3(p, z);
}
vec3 doffset(float z) {
float eps = 0.05;
return 0.5*(offset(z + eps) - offset(z - eps))/eps;
}
vec3 ddoffset(float z) {
float eps = 0.05;
return 0.5*(doffset(z + eps) - doffset(z - eps))/eps;
}
vec4 planeCol(vec3 ro, vec3 rd, float n, vec3 pp) {
const float s = 0.5;
vec2 p = pp.xy;
float z = pp.z;
vec2 dpy = dFdy(p);
float aa = length(dpy);
p -= (1.0+5.0*(pp.z - ro.z))*offset(z).xy;
p *= s;
float r = hash(vec3(floor(p+0.5), n));
p = fract(p+0.5)-0.5;
rot(p, ((TAU*r+n)*0.25));
float d = starn(p, 0.20, 3 + 2*int(3.0*r), 3.0);
d -= 0.06;
d/=s;
float ds = -d+0.03;
vec3 cols = hsv2rgb(vec3(337.0/360.0+0.1*sin(n*0.3), 0.8, 0.54+0.2*sin(n*0.3)));
float ts = 1.0 - smoothstep(-aa, 0.0, ds);
vec4 cs = vec4(cols, ts*0.93);
float db = abs(d) - (0.06);
db = abs(db) - 0.03;
db = abs(db) - 0.00;
db = max(db, -d+0.03);
vec3 colb = vec3(1.0, 0.7, 0.5);
float tb = exp(-(db)*30.0*(1.0 - 10.0*aa));
vec4 cb = vec4(1.5*colb, tb);
vec4 ct = alphaBlend(cs, cb);
return ct;
}
vec3 color(vec3 ww, vec3 uu, vec3 vv, vec3 ro, vec2 p) {
vec3 rd = normalize(p.x*uu + p.y*vv + (2.0-tanh(length(p)))*ww);
vec4 col = vec4(vec3(0.0), 1.0);
const float planeDist = 1.0;
const int furthest = 6;
const int fadeFrom = furthest-3;
float nz = floor(ro.z / planeDist);
for (int i = furthest; i >= 1; --i) {
float pz = planeDist*nz + planeDist*float(i);
float pd = (pz - ro.z)/rd.z;
if (pd > 0.0) {
vec3 pp = ro + rd*pd;
vec4 pcol = planeCol(ro, rd, nz+float(i), pp);
float fadeIn = 1.0-smoothstep(planeDist*float(fadeFrom), planeDist*float(furthest), pp.z-ro.z);
pcol.xyz *= sqrt(fadeIn);
col = alphaBlend(col, pcol);
}
}
return col.xyz*col.w;
}
vec3 postProcess(vec3 col, vec2 q) {
col=pow(clamp(col,0.0,1.0),vec3(0.75));
col=col*0.6+0.4*col*col*(3.0-2.0*col);
col=mix(col, vec3(dot(col, vec3(0.33))), -0.4);
col*=0.5+0.5*pow(19.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7);
return col;
}
vec3 effect(vec2 p, vec2 q) {
float tm = TIME*0.65;
vec3 ro = offset(tm);
vec3 dro = doffset(tm);
vec3 ddro = ddoffset(tm);
vec3 ww = normalize(dro);
vec3 uu = normalize(cross(vec3(0.0,1.0,0.0)+1.5*ddro, ww));
vec3 vv = normalize(cross(ww, uu));
vec3 col = color(ww, uu, vv, ro, p);
col = postProcess(col, q);
const float fadeIn = 2.0;
return col*smoothstep(0.0, fadeIn, TIME);
}
void mainImage(out vec4 fragColor, vec2 fragCoord) {
vec2 q = fragCoord/RESOLUTION.xy;
vec2 p = -1. + 2. * q;
p.x *= RESOLUTION.x/RESOLUTION.y;
vec3 col = effect(p, q);
fragColor = vec4(col, 1.0);
}

View File

@@ -1,351 +0,0 @@
/* 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_show (button);
}
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_hide (button);
}
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;
GtkCssProvider *provider;
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);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (provider, "button.small { padding: 0; }", -1);
gtk_style_context_add_provider (gtk_widget_get_style_context (button),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_object_unref (provider);
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_hide (button);
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 GtkWidget *
create_gltransition_window (GtkWidget *do_widget)
{
GtkWidget *window, *headerbar, *scale, *outer_grid, *grid, *background;
GdkPaintable *paintable;
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);
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_show (demo_window);
else
gtk_window_destroy (GTK_WINDOW (demo_window));
return demo_window;
}

View File

@@ -1,334 +0,0 @@
/*
* 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

@@ -1,53 +0,0 @@
/*
* 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 ())
GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GskShaderPaintable, gsk_shader_paintable, GSK, SHADER_PAINTABLE, GObject)
GDK_AVAILABLE_IN_ALL
GdkPaintable * gsk_shader_paintable_new (GskGLShader *shader,
GBytes *data);
GDK_AVAILABLE_IN_ALL
GskGLShader * gsk_shader_paintable_get_shader (GskShaderPaintable *self);
GDK_AVAILABLE_IN_ALL
void gsk_shader_paintable_set_shader (GskShaderPaintable *self,
GskGLShader *shader);
GDK_AVAILABLE_IN_ALL
GBytes * gsk_shader_paintable_get_args (GskShaderPaintable *self);
GDK_AVAILABLE_IN_ALL
void gsk_shader_paintable_set_args (GskShaderPaintable *self,
GBytes *data);
GDK_AVAILABLE_IN_ALL
void gsk_shader_paintable_update_time (GskShaderPaintable *self,
int time_idx,
gint64 frame_time);
G_END_DECLS
#endif /* __GSK_SHADER_PAINTABLE_H__ */

View File

@@ -74,9 +74,9 @@ gtk_fishbowl_init (GtkFishbowl *fishbowl)
/**
* gtk_fishbowl_new:
*
* Creates a new `GtkFishbowl`.
* Creates a new #GtkFishbowl.
*
* Returns: a new `GtkFishbowl`.
* Returns: a new #GtkFishbowl.
*/
GtkWidget*
gtk_fishbowl_new (void)
@@ -179,9 +179,6 @@ gtk_fishbowl_add (GtkFishbowl *fishbowl,
child_info->dy = new_speed ();
gtk_widget_set_parent (widget, GTK_WIDGET (fishbowl));
gtk_accessible_update_state (GTK_ACCESSIBLE (widget),
GTK_ACCESSIBLE_STATE_HIDDEN, TRUE,
-1);
g_hash_table_insert (priv->children, widget, child_info);
priv->count++;
@@ -345,8 +342,6 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
G_PARAM_READWRITE);
g_object_class_install_properties (object_class, NUM_PROPERTIES, props);
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_PRESENTATION);
}
guint

View File

@@ -764,7 +764,7 @@ gtk_gears_realize (GtkWidget *widget)
glShaderSource(v, 1, &p, NULL);
glCompileShader(v);
glGetShaderInfoLog(v, sizeof msg, NULL, msg);
g_debug ("vertex shader info: %s\n", msg);
g_print ("vertex shader info: %s\n", msg);
/* Compile the fragment shader */
if (gdk_gl_context_get_use_es (context))
@@ -775,7 +775,7 @@ gtk_gears_realize (GtkWidget *widget)
glShaderSource(f, 1, &p, NULL);
glCompileShader(f);
glGetShaderInfoLog(f, sizeof msg, NULL, msg);
g_debug ("fragment shader info: %s\n", msg);
g_print ("fragment shader info: %s\n", msg);
/* Create and link the shader program */
program = glCreateProgram();
@@ -786,9 +786,7 @@ gtk_gears_realize (GtkWidget *widget)
glLinkProgram(program);
glGetProgramInfoLog(program, sizeof msg, NULL, msg);
g_debug ("program info: %s\n", msg);
glDetachShader (program, v);
glDetachShader (program, f);
g_print ("program info: %s\n", msg);
glDeleteShader (v);
glDeleteShader (f);

View File

@@ -1,264 +0,0 @@
#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

@@ -1,23 +0,0 @@
#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

@@ -1,361 +0,0 @@
#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

@@ -1,23 +0,0 @@
#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

@@ -1,526 +0,0 @@
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <epoxy/gl.h>
#include "gtkshadertoy.h"
const char *default_image_shader =
"void mainImage(out vec4 fragColor, in vec2 fragCoord) {\n"
" // Normalized pixel coordinates (from 0 to 1)\n"
" vec2 uv = fragCoord/iResolution.xy;\n"
"\n"
" // Time varying pixel color\n"
" vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));\n"
"\n"
" if (distance(iMouse.xy, fragCoord.xy) <= 10.0) {\n"
" col = vec3(0.0);\n"
" }\n"
"\n"
" // Output to screen\n"
" fragColor = vec4(col,1.0);\n"
"}\n";
const char *shadertoy_vertex_shader =
"#version 150 core\n"
"\n"
"uniform vec3 iResolution;\n"
"\n"
"in vec2 position;\n"
"out vec2 fragCoord;\n"
"\n"
"void main() {\n"
" gl_Position = vec4(position, 0.0, 1.0);\n"
"\n"
" // Convert from OpenGL coordinate system (with origin in center\n"
" // of screen) to Shadertoy/texture coordinate system (with origin\n"
" // in lower left corner)\n"
" fragCoord = (gl_Position.xy + vec2(1.0)) / vec2(2.0) * iResolution.xy;\n"
"}\n";
const char *fragment_prefix =
"#version 150 core\n"
"\n"
"uniform vec3 iResolution; // viewport resolution (in pixels)\n"
"uniform float iTime; // shader playback time (in seconds)\n"
"uniform float iTimeDelta; // render time (in seconds)\n"
"uniform int iFrame; // shader playback frame\n"
"uniform float iChannelTime[4]; // channel playback time (in seconds)\n"
"uniform vec3 iChannelResolution[4]; // channel resolution (in pixels)\n"
"uniform vec4 iMouse; // mouse pixel coords. xy: current (if MLB down), zw: click\n"
"uniform sampler2D iChannel0;\n"
"uniform sampler2D iChannel1;\n"
"uniform sampler2D iChannel2;\n"
"uniform sampler2D iChannel3;\n"
"uniform vec4 iDate; // (year, month, day, time in seconds)\n"
"uniform float iSampleRate; // sound sample rate (i.e., 44100)\n"
"\n"
"in vec2 fragCoord;\n"
"out vec4 vFragColor;\n";
// Fragment shader suffix
const char *fragment_suffix =
" void main() {\n"
" vec4 c;\n"
" mainImage(c, fragCoord);\n"
" vFragColor = c;\n"
" }\n";
typedef struct {
char *image_shader;
gboolean image_shader_dirty;
gboolean error_set;
/* Vertex buffers */
GLuint vao;
GLuint buffer;
/* Active program */
GLuint program;
/* Location of uniforms for program */
GLuint resolution_location;
GLuint time_location;
GLuint timedelta_location;
GLuint frame_location;
GLuint mouse_location;
/* Current uniform values */
float resolution[3];
float time;
float timedelta;
float mouse[4];
int frame;
/* Animation data */
gint64 first_frame_time;
gint64 first_frame;
guint tick;
} GtkShadertoyPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GtkShadertoy, gtk_shadertoy, GTK_TYPE_GL_AREA)
static gboolean gtk_shadertoy_render (GtkGLArea *area,
GdkGLContext *context);
static void gtk_shadertoy_reshape (GtkGLArea *area,
int width,
int height);
static void gtk_shadertoy_realize (GtkWidget *widget);
static void gtk_shadertoy_unrealize (GtkWidget *widget);
static gboolean gtk_shadertoy_tick (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data);
GtkWidget *
gtk_shadertoy_new (void)
{
return g_object_new (gtk_shadertoy_get_type (), NULL);
}
static void
drag_begin_cb (GtkGestureDrag *drag,
double x,
double y,
gpointer user_data)
{
GtkShadertoy *shadertoy = GTK_SHADERTOY (user_data);
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
int height = gtk_widget_get_height (GTK_WIDGET (shadertoy));
int scale = gtk_widget_get_scale_factor (GTK_WIDGET (shadertoy));
priv->mouse[0] = x * scale;
priv->mouse[1] = (height - y) * scale;
priv->mouse[2] = priv->mouse[0];
priv->mouse[3] = priv->mouse[1];
}
static void
drag_update_cb (GtkGestureDrag *drag,
double dx,
double dy,
gpointer user_data)
{
GtkShadertoy *shadertoy = GTK_SHADERTOY (user_data);
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
int width = gtk_widget_get_width (GTK_WIDGET (shadertoy));
int height = gtk_widget_get_height (GTK_WIDGET (shadertoy));
int scale = gtk_widget_get_scale_factor (GTK_WIDGET (shadertoy));
double x, y;
gtk_gesture_drag_get_start_point (drag, &x, &y);
x += dx;
y += dy;
if (x >= 0 && x < width &&
y >= 0 && y < height)
{
priv->mouse[0] = x * scale;
priv->mouse[1] = (height - y) * scale;
}
}
static void
drag_end_cb (GtkGestureDrag *drag,
double dx,
double dy,
gpointer user_data)
{
GtkShadertoy *shadertoy = GTK_SHADERTOY (user_data);
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
priv->mouse[2] = -priv->mouse[2];
priv->mouse[3] = -priv->mouse[3];
}
static void
gtk_shadertoy_init (GtkShadertoy *shadertoy)
{
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
GtkGesture *drag;
priv->image_shader = g_strdup (default_image_shader);
priv->tick = gtk_widget_add_tick_callback (GTK_WIDGET (shadertoy), gtk_shadertoy_tick, shadertoy, NULL);
drag = gtk_gesture_drag_new ();
gtk_widget_add_controller (GTK_WIDGET (shadertoy), GTK_EVENT_CONTROLLER (drag));
g_signal_connect (drag, "drag-begin", (GCallback)drag_begin_cb, shadertoy);
g_signal_connect (drag, "drag-update", (GCallback)drag_update_cb, shadertoy);
g_signal_connect (drag, "drag-end", (GCallback)drag_end_cb, shadertoy);
}
static void
gtk_shadertoy_finalize (GObject *obj)
{
GtkShadertoy *shadertoy = GTK_SHADERTOY (obj);
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
gtk_widget_remove_tick_callback (GTK_WIDGET (shadertoy), priv->tick);
g_free (priv->image_shader);
G_OBJECT_CLASS (gtk_shadertoy_parent_class)->finalize (obj);
}
static void
gtk_shadertoy_class_init (GtkShadertoyClass *klass)
{
GTK_GL_AREA_CLASS (klass)->render = gtk_shadertoy_render;
GTK_GL_AREA_CLASS (klass)->resize = gtk_shadertoy_reshape;
GTK_WIDGET_CLASS (klass)->realize = gtk_shadertoy_realize;
GTK_WIDGET_CLASS (klass)->unrealize = gtk_shadertoy_unrealize;
G_OBJECT_CLASS (klass)->finalize = gtk_shadertoy_finalize;
}
/* new window size or exposure */
static void
gtk_shadertoy_reshape (GtkGLArea *area, int width, int height)
{
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private ((GtkShadertoy *) area);
priv->resolution[0] = width;
priv->resolution[1] = height;
priv->resolution[2] = 1.0; /* screen aspect ratio */
/* Set the viewport */
glViewport (0, 0, (GLint) width, (GLint) height);
}
static GLuint
create_shader (int type,
const char *src,
GError **error)
{
GLuint shader;
int status;
shader = glCreateShader (type);
glShaderSource (shader, 1, &src, NULL);
glCompileShader (shader);
glGetShaderiv (shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
int log_len;
char *buffer;
glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &log_len);
buffer = g_malloc (log_len + 1);
glGetShaderInfoLog (shader, log_len, NULL, buffer);
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_COMPILATION_FAILED,
"Compile failure in %s shader:\n%s",
type == GL_VERTEX_SHADER ? "vertex" : "fragment",
buffer);
g_free (buffer);
glDeleteShader (shader);
return 0;
}
return shader;
}
static gboolean
init_shaders (GtkShadertoy *shadertoy,
const char *vertex_source,
const char *fragment_source,
GError **error)
{
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
GLuint vertex, fragment;
GLuint program = 0;
int status;
gboolean res = TRUE;
vertex = create_shader (GL_VERTEX_SHADER, vertex_source, error);
if (vertex == 0)
return FALSE;
fragment = create_shader (GL_FRAGMENT_SHADER, fragment_source, error);
if (fragment == 0)
{
glDeleteShader (vertex);
return FALSE;
}
program = glCreateProgram ();
glAttachShader (program, vertex);
glAttachShader (program, fragment);
glLinkProgram (program);
glGetProgramiv (program, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
int log_len;
char *buffer;
glGetProgramiv (program, GL_INFO_LOG_LENGTH, &log_len);
buffer = g_malloc (log_len + 1);
glGetProgramInfoLog (program, log_len, NULL, buffer);
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_LINK_FAILED,
"Linking failure:\n%s", buffer);
res = FALSE;
g_free (buffer);
glDeleteProgram (program);
goto out;
}
if (priv->program != 0)
glDeleteProgram (priv->program);
priv->program = program;
priv->resolution_location = glGetUniformLocation (program, "iResolution");
priv->time_location = glGetUniformLocation (program, "iTime");
priv->timedelta_location = glGetUniformLocation (program, "iTimeDelta");
priv->frame_location = glGetUniformLocation (program, "iFrame");
priv->mouse_location = glGetUniformLocation (program, "iMouse");
glDetachShader (program, vertex);
glDetachShader (program, fragment);
out:
/* These are now owned by the program and can be deleted */
glDeleteShader (vertex);
glDeleteShader (fragment);
return res;
}
static void
gtk_shadertoy_realize_shader (GtkShadertoy *shadertoy)
{
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
char *fragment_shader;
GError *error = NULL;
fragment_shader = g_strconcat (fragment_prefix, priv->image_shader, fragment_suffix, NULL);
if (!init_shaders (shadertoy, shadertoy_vertex_shader, fragment_shader, &error))
{
priv->error_set = TRUE;
gtk_gl_area_set_error (GTK_GL_AREA (shadertoy), error);
g_error_free (error);
}
g_free (fragment_shader);
/* Start new shader at time zero */
priv->first_frame_time = 0;
priv->first_frame = 0;
priv->image_shader_dirty = FALSE;
}
static gboolean
gtk_shadertoy_render (GtkGLArea *area,
GdkGLContext *context)
{
GtkShadertoy *shadertoy = GTK_SHADERTOY (area);
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
if (gtk_gl_area_get_error (area) != NULL)
return FALSE;
if (priv->image_shader_dirty)
gtk_shadertoy_realize_shader (shadertoy);
/* Clear the viewport */
glClearColor (0.0, 0.0, 0.0, 1.0);
glClear (GL_COLOR_BUFFER_BIT);
glUseProgram (priv->program);
/* Update uniforms */
if (priv->resolution_location != -1)
glUniform3fv (priv->resolution_location, 1, priv->resolution);
if (priv->time_location != -1)
glUniform1f (priv->time_location, priv->time);
if (priv->timedelta_location != -1)
glUniform1f (priv->timedelta_location, priv->timedelta);
if (priv->frame_location != -1)
glUniform1i (priv->frame_location, priv->frame);
if (priv->mouse_location != -1)
glUniform4fv (priv->mouse_location, 1, priv->mouse);
/* Use the vertices in our buffer */
glBindBuffer (GL_ARRAY_BUFFER, priv->buffer);
glEnableVertexAttribArray (0);
glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays (GL_TRIANGLES, 0, 6);
/* We finished using the buffers and program */
glDisableVertexAttribArray (0);
glBindBuffer (GL_ARRAY_BUFFER, 0);
glUseProgram (0);
/* Flush the contents of the pipeline */
glFlush ();
return TRUE;
}
const char *
gtk_shadertoy_get_image_shader (GtkShadertoy *shadertoy)
{
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
return priv->image_shader;
}
void
gtk_shadertoy_set_image_shader (GtkShadertoy *shadertoy,
const char *shader)
{
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
g_free (priv->image_shader);
priv->image_shader = g_strdup (shader);
/* Don't override error we didn't set it ourselves */
if (priv->error_set)
{
gtk_gl_area_set_error (GTK_GL_AREA (shadertoy), NULL);
priv->error_set = FALSE;
}
priv->image_shader_dirty = TRUE;
}
static void
gtk_shadertoy_realize (GtkWidget *widget)
{
GtkGLArea *glarea = GTK_GL_AREA (widget);
GtkShadertoy *shadertoy = GTK_SHADERTOY (widget);
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
/* Draw two triangles across whole screen */
const GLfloat vertex_data[] = {
-1.0f, -1.0f, 0.f, 1.f,
-1.0f, 1.0f, 0.f, 1.f,
1.0f, 1.0f, 0.f, 1.f,
-1.0f, -1.0f, 0.f, 1.f,
1.0f, 1.0f, 0.f, 1.f,
1.0f, -1.0f, 0.f, 1.f,
};
GTK_WIDGET_CLASS (gtk_shadertoy_parent_class)->realize (widget);
gtk_gl_area_make_current (glarea);
if (gtk_gl_area_get_error (glarea) != NULL)
return;
glGenVertexArrays (1, &priv->vao);
glBindVertexArray (priv->vao);
glGenBuffers (1, &priv->buffer);
glBindBuffer (GL_ARRAY_BUFFER, priv->buffer);
glBufferData (GL_ARRAY_BUFFER, sizeof (vertex_data), vertex_data, GL_STATIC_DRAW);
glBindBuffer (GL_ARRAY_BUFFER, 0);
gtk_shadertoy_realize_shader (shadertoy);
}
static void
gtk_shadertoy_unrealize (GtkWidget *widget)
{
GtkGLArea *glarea = GTK_GL_AREA (widget);
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private ((GtkShadertoy *) widget);
gtk_gl_area_make_current (glarea);
if (gtk_gl_area_get_error (glarea) == NULL)
{
if (priv->buffer != 0)
glDeleteBuffers (1, &priv->buffer);
if (priv->vao != 0)
glDeleteVertexArrays (1, &priv->vao);
if (priv->program != 0)
glDeleteProgram (priv->program);
}
GTK_WIDGET_CLASS (gtk_shadertoy_parent_class)->unrealize (widget);
}
static gboolean
gtk_shadertoy_tick (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GtkShadertoy *shadertoy = GTK_SHADERTOY (widget);
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
gint64 frame_time;
gint64 frame;
float previous_time;
frame = gdk_frame_clock_get_frame_counter (frame_clock);
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
if (priv->first_frame_time == 0)
{
priv->first_frame_time = frame_time;
priv->first_frame = frame;
previous_time = 0;
}
else
previous_time = priv->time;
priv->time = (frame_time - priv->first_frame_time) / 1000000.0f;
priv->frame = frame - priv->first_frame;
priv->timedelta = priv->time - previous_time;
gtk_widget_queue_draw (widget);
return G_SOURCE_CONTINUE;
}

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