Compare commits
1 Commits
gdk-win32-
...
wip/css-va
Author | SHA1 | Date | |
---|---|---|---|
|
5bbe811090 |
@@ -1,4 +1,4 @@
|
|||||||
# See https://www.apertis.org/policies/coding_conventions/#code-formatting
|
# See https://wiki.apertis.org/Guidelines/Coding_conventions#Code_formatting
|
||||||
BasedOnStyle: GNU
|
BasedOnStyle: GNU
|
||||||
AlwaysBreakAfterDefinitionReturnType: All
|
AlwaysBreakAfterDefinitionReturnType: All
|
||||||
BreakBeforeBinaryOperators: None
|
BreakBeforeBinaryOperators: None
|
||||||
|
1
.gitignore
vendored
@@ -1,2 +1 @@
|
|||||||
/subprojects/*/
|
/subprojects/*/
|
||||||
.flatpak-builder/
|
|
||||||
|
359
.gitlab-ci.yml
@@ -22,44 +22,29 @@ stages:
|
|||||||
|
|
||||||
# Common variables
|
# Common variables
|
||||||
variables:
|
variables:
|
||||||
COMMON_MESON_FLAGS: "-Dwerror=true -Dcairo:werror=false -Dgi-docgen:werror=false -Dgraphene:werror=false -Dlibepoxy:werror=false -Dlibsass:werror=false -Dpango:werror=false -Dsassc:werror=false -Dgdk-pixbuf:werror=false -Dglib:werror=false -Dlibcloudproviders:werror=false -Dlibpng:werror=false -Dlibtiff:werror=false -Dsysprof:werror=false -Dwayland-protocols:werror=false -Dharfbuzz:werror=false -Dfreetype2:werror=false -Dfontconfig:werror=false -Dfribidi:werror=false -Dlibffi:werror=false -Dlibjpeg-turbo:werror=false -Dmutest:werror=false -Dpixman:werror=false -Dproxy-libintl:werror=false"
|
COMMON_MESON_FLAGS: "-Dwerror=true -Dglib:werror=false -Dpango:werror=false -Dgtk-doc:werror=false -Dwayland-protocols:werror=false -Dsysprof:werror=false -Dwayland:werror=false"
|
||||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Dbuild-testsuite=true -Dintrospection=enabled"
|
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
||||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||||
MESON_TEST_MAX_PROCESSES: 8
|
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v38"
|
||||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v52"
|
FLATPAK_IMAGE: "quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master"
|
||||||
|
|
||||||
workflow:
|
.only-default:
|
||||||
rules:
|
only:
|
||||||
# run merge request pipelines
|
- branches
|
||||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
except:
|
||||||
# do not run branch pipelines if corresponding merge requests exist...
|
- tags
|
||||||
# (this avoids duplicate pipelines)
|
|
||||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
|
|
||||||
when: never
|
|
||||||
# ...but otherwise run branch pipelines
|
|
||||||
- if: $CI_COMMIT_BRANCH
|
|
||||||
# run tag pipelines
|
|
||||||
- if: $CI_COMMIT_TAG
|
|
||||||
|
|
||||||
default:
|
|
||||||
retry:
|
|
||||||
max: 2
|
|
||||||
when:
|
|
||||||
- 'runner_system_failure'
|
|
||||||
- 'stuck_or_timeout_failure'
|
|
||||||
- 'scheduler_failure'
|
|
||||||
- 'api_failure'
|
|
||||||
interruptible: true
|
|
||||||
|
|
||||||
style-check-diff:
|
style-check-diff:
|
||||||
|
extends: .only-default
|
||||||
image: $FEDORA_IMAGE
|
image: $FEDORA_IMAGE
|
||||||
stage: check
|
stage: check
|
||||||
when: manual
|
allow_failure: true
|
||||||
script:
|
script:
|
||||||
- .gitlab-ci/run-style-check-diff.sh
|
- .gitlab-ci/run-style-check-diff.sh
|
||||||
|
|
||||||
.build-fedora-default:
|
.build-fedora-default:
|
||||||
|
extends: .only-default
|
||||||
image: $FEDORA_IMAGE
|
image: $FEDORA_IMAGE
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
when: always
|
||||||
@@ -67,7 +52,6 @@ style-check-diff:
|
|||||||
junit:
|
junit:
|
||||||
- "${CI_PROJECT_DIR}/_build/report-x11.xml"
|
- "${CI_PROJECT_DIR}/_build/report-x11.xml"
|
||||||
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
|
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
|
||||||
- "${CI_PROJECT_DIR}/_build/report-wayland_gl.xml"
|
|
||||||
- "${CI_PROJECT_DIR}/_build/report-broadway.xml"
|
- "${CI_PROJECT_DIR}/_build/report-broadway.xml"
|
||||||
name: "gtk-${CI_COMMIT_REF_NAME}"
|
name: "gtk-${CI_COMMIT_REF_NAME}"
|
||||||
paths:
|
paths:
|
||||||
@@ -78,14 +62,17 @@ style-check-diff:
|
|||||||
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.node"
|
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.node"
|
||||||
- "${CI_PROJECT_DIR}/_build/testsuite/tools/output/*/*"
|
- "${CI_PROJECT_DIR}/_build/testsuite/tools/output/*/*"
|
||||||
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
|
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
|
||||||
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.node"
|
|
||||||
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
|
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
|
||||||
- "${CI_PROJECT_DIR}/_build/testsuite/headless/*/*.log"
|
|
||||||
- "${CI_PROJECT_DIR}/_build_hello/meson-logs"
|
- "${CI_PROJECT_DIR}/_build_hello/meson-logs"
|
||||||
cache:
|
cache:
|
||||||
key: "$CI_JOB_NAME"
|
key: "$CI_JOB_NAME"
|
||||||
paths:
|
paths:
|
||||||
- _ccache/
|
- _ccache/
|
||||||
|
- subprojects/gdk-pixbuf/
|
||||||
|
- subprojects/glib/
|
||||||
|
- subprojects/graphene/
|
||||||
|
- subprojects/libepoxy/
|
||||||
|
- subprojects/pango/
|
||||||
|
|
||||||
fedora-x86_64:
|
fedora-x86_64:
|
||||||
extends: .build-fedora-default
|
extends: .build-fedora-default
|
||||||
@@ -95,19 +82,19 @@ fedora-x86_64:
|
|||||||
EXTRA_MESON_FLAGS: "--buildtype=debug --default-library=both"
|
EXTRA_MESON_FLAGS: "--buildtype=debug --default-library=both"
|
||||||
script:
|
script:
|
||||||
- .gitlab-ci/show-info-linux.sh
|
- .gitlab-ci/show-info-linux.sh
|
||||||
- export PATH="$HOME/.local/bin:$PATH"
|
- meson subprojects update
|
||||||
- meson subprojects download
|
- mkdir _install
|
||||||
- meson subprojects update --reset
|
- meson --prefix=${CI_PROJECT_DIR}/_install
|
||||||
- meson setup
|
${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
||||||
${COMMON_MESON_FLAGS}
|
|
||||||
${EXTRA_MESON_FLAGS}
|
|
||||||
${BACKEND_FLAGS}
|
|
||||||
${FEATURE_FLAGS}
|
|
||||||
_build
|
_build
|
||||||
- meson compile -C _build
|
- meson compile -C _build
|
||||||
- .gitlab-ci/run-tests.sh _build x11 gtk
|
- meson install -C _build
|
||||||
# only repeat test runs that are likely affected by test setups
|
- PKG_CONFIG_PATH=${CI_PROJECT_DIR}/_install/lib64/pkgconfig:${CI_PROJECT_DIR}/_install/share/pkgconfig meson setup _build_hello examples/hello
|
||||||
- .gitlab-ci/run-tests.sh _build wayland_gl gtk:gdk,gtk:gsk-gl
|
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
|
||||||
|
- .gitlab-ci/run-tests.sh _build x11
|
||||||
|
- .gitlab-ci/run-tests.sh _build wayland
|
||||||
|
- .gitlab-ci/run-tests.sh _build waylandgles
|
||||||
|
- .gitlab-ci/run-tests.sh _build broadway
|
||||||
|
|
||||||
release-build:
|
release-build:
|
||||||
extends: .build-fedora-default
|
extends: .build-fedora-default
|
||||||
@@ -117,44 +104,11 @@ release-build:
|
|||||||
EXTRA_MESON_FLAGS: "--buildtype=release"
|
EXTRA_MESON_FLAGS: "--buildtype=release"
|
||||||
script:
|
script:
|
||||||
- .gitlab-ci/show-info-linux.sh
|
- .gitlab-ci/show-info-linux.sh
|
||||||
- mkdir _install
|
- meson subprojects update
|
||||||
# don't use catch by default, since it causes sporadic test failures
|
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
||||||
# - export PATH="$HOME/.local/bin:${CI_PROJECT_DIR}/_install/bin:$PATH"
|
|
||||||
# - .gitlab-ci/install-meson-project.sh --prefix ${CI_PROJECT_DIR}/_install https://gitlab.gnome.org/jadahl/catch.git main
|
|
||||||
- meson subprojects download
|
|
||||||
- meson subprojects update --reset
|
|
||||||
- meson setup
|
|
||||||
--prefix=${CI_PROJECT_DIR}/_install
|
|
||||||
${COMMON_MESON_FLAGS}
|
|
||||||
${EXTRA_MESON_FLAGS}
|
|
||||||
${BACKEND_FLAGS}
|
|
||||||
${FEATURE_FLAGS}
|
|
||||||
_build
|
_build
|
||||||
- meson compile -C _build
|
- ninja -C _build
|
||||||
- meson install -C _build
|
- .gitlab-ci/run-tests.sh _build x11
|
||||||
- PKG_CONFIG_PATH=${CI_PROJECT_DIR}/_install/lib64/pkgconfig:${CI_PROJECT_DIR}/_install/share/pkgconfig meson setup _build_hello examples/hello
|
|
||||||
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
|
|
||||||
- .gitlab-ci/run-tests.sh _build wayland gtk
|
|
||||||
|
|
||||||
fedora-clang:
|
|
||||||
extends: .build-fedora-default
|
|
||||||
stage: build
|
|
||||||
needs: []
|
|
||||||
variables:
|
|
||||||
EXTRA_MESON_FLAGS: "--buildtype=release"
|
|
||||||
script:
|
|
||||||
- .gitlab-ci/show-info-linux.sh
|
|
||||||
- export PATH="$HOME/.local/bin:$PATH"
|
|
||||||
- export CC=clang
|
|
||||||
- meson subprojects download
|
|
||||||
- meson subprojects update --reset
|
|
||||||
- meson setup
|
|
||||||
${COMMON_MESON_FLAGS}
|
|
||||||
${EXTRA_MESON_FLAGS}
|
|
||||||
${BACKEND_FLAGS}
|
|
||||||
${FEATURE_FLAGS}
|
|
||||||
_build
|
|
||||||
- meson compile -C _build
|
|
||||||
|
|
||||||
fedora-mingw64:
|
fedora-mingw64:
|
||||||
extends: .build-fedora-default
|
extends: .build-fedora-default
|
||||||
@@ -174,14 +128,37 @@ fedora-mingw64:
|
|||||||
# mingw64-graphene (rawhide)
|
# mingw64-graphene (rawhide)
|
||||||
script:
|
script:
|
||||||
- .gitlab-ci/show-info-linux.sh
|
- .gitlab-ci/show-info-linux.sh
|
||||||
- export PATH="$HOME/.local/bin:$PATH"
|
- meson subprojects update
|
||||||
- pip3 install --user meson~=1.0
|
- mkdir _build && cd _build
|
||||||
- meson subprojects download
|
- mingw64-meson -Dintrospection=disabled -Dgraphene:introspection=disabled
|
||||||
- meson subprojects update --reset
|
- ninja
|
||||||
- meson -Dintrospection=disabled -Dgraphene:introspection=disabled _build
|
|
||||||
- meson compile -C _build
|
installed-tests:
|
||||||
|
extends: .build-fedora-default
|
||||||
|
stage: build
|
||||||
|
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
|
||||||
|
- ninja -C _build
|
||||||
|
- sudo ninja -C _build install
|
||||||
|
- dbus-run-session xvfb-run -a -s "-screen 0 1024x768x24"
|
||||||
|
gnome-desktop-testing-runner
|
||||||
|
--report-directory=_build/installed-tests-report/failed/
|
||||||
|
--parallel=0
|
||||||
|
gtk-4.0
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- "_build/installed-tests-report/"
|
||||||
|
|
||||||
|
|
||||||
.mingw-defaults:
|
.mingw-defaults:
|
||||||
|
extends: .only-default
|
||||||
stage: build
|
stage: build
|
||||||
tags:
|
tags:
|
||||||
- win32-ps
|
- win32-ps
|
||||||
@@ -198,11 +175,11 @@ fedora-mingw64:
|
|||||||
- subprojects/libepoxy/
|
- subprojects/libepoxy/
|
||||||
- subprojects/pango/
|
- subprojects/pango/
|
||||||
|
|
||||||
msys2-ucrt64:
|
msys2-mingw64:
|
||||||
extends: .mingw-defaults
|
extends: .mingw-defaults
|
||||||
needs: []
|
needs: []
|
||||||
variables:
|
variables:
|
||||||
MSYSTEM: "UCRT64"
|
MSYSTEM: "MINGW64"
|
||||||
CHERE_INVOKING: "yes"
|
CHERE_INVOKING: "yes"
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
when: always
|
||||||
@@ -211,64 +188,39 @@ msys2-ucrt64:
|
|||||||
- "${CI_PROJECT_DIR}/_build/gtkdll.tar.gz"
|
- "${CI_PROJECT_DIR}/_build/gtkdll.tar.gz"
|
||||||
|
|
||||||
macos:
|
macos:
|
||||||
rules:
|
extends: .only-default
|
||||||
# Do not run in forks as the runner is not available there.
|
only:
|
||||||
# (except for dehesselle who maintains the runner)
|
- branches@GNOME/gtk
|
||||||
- if: $CI_PROJECT_NAMESPACE != "GNOME" && $CI_PROJECT_NAMESPACE != "dehesselle"
|
|
||||||
when: never
|
|
||||||
- if: $RUNNER == "macosintel"
|
|
||||||
variables:
|
|
||||||
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
|
|
||||||
NINJA_PKG: $CI_API_V4_URL/projects/30745/packages/generic/ninja_macos/v1.11.1.1+9/ninja-1.11.1.1-cp38-cp38-macosx_11_0_x86_64.whl
|
|
||||||
when: manual
|
|
||||||
allow_failure: true
|
|
||||||
- if: $RUNNER == "macosarm"
|
|
||||||
variables:
|
|
||||||
SDKROOT: /opt/sdks/MacOSX11.3.sdk
|
|
||||||
NINJA_PKG: ninja==1.11.1.1
|
|
||||||
stage: build
|
stage: build
|
||||||
parallel:
|
|
||||||
matrix:
|
|
||||||
- RUNNER: [ "macosintel", "macosarm" ]
|
|
||||||
tags:
|
tags:
|
||||||
- ${RUNNER}
|
- macos
|
||||||
needs: []
|
needs: []
|
||||||
variables:
|
|
||||||
EXTRA_MESON_FLAGS: ""
|
|
||||||
BACKEND_FLAGS: "-Dx11-backend=false -Dbroadway-backend=true"
|
|
||||||
FEATURE_FLAGS: "-Dmedia-gstreamer=disabled -Dintrospection=enabled -Dgobject-introspection:werror=false"
|
|
||||||
TMPDIR: /Users/Shared/work/tmp
|
|
||||||
PIP_CACHE_DIR: /Users/Shared/build/cache
|
|
||||||
PIPENV_CACHE_DIR: $PIP_CACHE_DIR
|
|
||||||
PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR
|
|
||||||
before_script:
|
before_script:
|
||||||
- .gitlab-ci/show-info-macos.sh
|
- bash .gitlab-ci/show-info-osx.sh
|
||||||
- python3 -m venv .venv
|
- pip3 install --user meson==0.60.3
|
||||||
# Building the introspection feature requires pkg-config and bison.
|
- pip3 install --user ninja
|
||||||
- curl -L $CI_API_V4_URL/projects/30437/packages/generic/pkgconfig/v0.29.2+10/pkg-config-0.29.2+10_$(uname -m).tar.xz | tar -C .venv -xJ
|
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
|
||||||
- curl -L $CI_API_V4_URL/projects/30438/packages/generic/bison/v3.8.2+3/bison-3.8.2+3_$(uname -m).tar.xz | tar -C .venv -xJ
|
- export MESON_FORCE_BACKTRACE=1
|
||||||
- source .venv/bin/activate
|
|
||||||
- pip3 install meson==1.3.2 $NINJA_PKG
|
|
||||||
# We're not setting up ccache here on purpose as it accelerates the build
|
|
||||||
# so much that it triggers race conditions in the gobject-introspection
|
|
||||||
# subproject.
|
|
||||||
script:
|
script:
|
||||||
- meson setup
|
- meson -Dx11-backend=false
|
||||||
${COMMON_MESON_FLAGS}
|
-Dbroadway-backend=true
|
||||||
${EXTRA_MESON_FLAGS}
|
-Dmacos-backend=true
|
||||||
${BACKEND_FLAGS}
|
-Dmedia-gstreamer=disabled
|
||||||
${FEATURE_FLAGS}
|
-Dintrospection=disabled
|
||||||
|
-Dcpp_std=c++11
|
||||||
|
-Dpixman:tests=disabled
|
||||||
_build
|
_build
|
||||||
- meson compile -C _build
|
- ninja -C _build
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
when: always
|
||||||
paths:
|
paths:
|
||||||
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
||||||
|
|
||||||
vs2017-x64:
|
vs2017-x64:
|
||||||
|
extends: .only-default
|
||||||
# TODO: Uncomment this when ready to merge.
|
# TODO: Uncomment this when ready to merge.
|
||||||
# rules:
|
#only:
|
||||||
# - if: $CI_PROJECT_NAMESPACE == "GNOME"
|
# - branches@GNOME/gtk
|
||||||
stage: build
|
stage: build
|
||||||
tags:
|
tags:
|
||||||
- win32-ps
|
- win32-ps
|
||||||
@@ -281,7 +233,7 @@ vs2017-x64:
|
|||||||
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
||||||
|
|
||||||
.flatpak-defaults:
|
.flatpak-defaults:
|
||||||
image: "quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master"
|
image: $FLATPAK_IMAGE
|
||||||
stage: flatpak
|
stage: flatpak
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
tags:
|
tags:
|
||||||
@@ -291,67 +243,65 @@ vs2017-x64:
|
|||||||
- "${APPID}-dev.flatpak"
|
- "${APPID}-dev.flatpak"
|
||||||
- 'repo.tar'
|
- 'repo.tar'
|
||||||
expire_in: 1 day
|
expire_in: 1 day
|
||||||
rules:
|
|
||||||
# Only build Flatpak bundles automatically on main
|
|
||||||
- if: $CI_COMMIT_BRANCH == "main"
|
|
||||||
- if: $CI_COMMIT_BRANCH != "main"
|
|
||||||
when: "manual"
|
|
||||||
script:
|
script:
|
||||||
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
|
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
|
||||||
|
|
||||||
flatpak:demo:
|
# Manual jobs, for branches and MRs
|
||||||
extends: '.flatpak-defaults'
|
.flatpak-manual:
|
||||||
|
extends: .flatpak-defaults
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
# Only build Flatpak bundles automatically on main
|
||||||
|
.flatpak-main:
|
||||||
|
extends: .flatpak-defaults
|
||||||
|
only:
|
||||||
|
- main
|
||||||
|
|
||||||
|
flatpak-manual:demo:
|
||||||
|
extends: .flatpak-manual
|
||||||
needs: []
|
needs: []
|
||||||
variables:
|
variables:
|
||||||
APPID: org.gtk.Demo4
|
APPID: org.gtk.Demo4
|
||||||
|
|
||||||
flatpak:demo:aarch64:
|
flatpak-main:demo:
|
||||||
extends: '.flatpak-defaults'
|
extends: .flatpak-main
|
||||||
needs: []
|
needs: []
|
||||||
tags:
|
|
||||||
- flatpak-aarch64
|
|
||||||
variables:
|
variables:
|
||||||
APPID: org.gtk.Demo4
|
APPID: org.gtk.Demo4
|
||||||
|
|
||||||
flatpak:widget-factory:
|
flatpak-manual:widget-factory:
|
||||||
extends: '.flatpak-defaults'
|
extends: .flatpak-manual
|
||||||
needs: []
|
needs: []
|
||||||
variables:
|
variables:
|
||||||
APPID: org.gtk.WidgetFactory4
|
APPID: org.gtk.WidgetFactory4
|
||||||
|
|
||||||
flatpak:widget-factory:aarch64:
|
flatpak-main:widget-factory:
|
||||||
extends: '.flatpak-defaults'
|
extends: .flatpak-main
|
||||||
needs: []
|
needs: []
|
||||||
tags:
|
|
||||||
- flatpak-aarch64
|
|
||||||
variables:
|
variables:
|
||||||
APPID: org.gtk.WidgetFactory4
|
APPID: org.gtk.WidgetFactory4
|
||||||
|
|
||||||
flatpak:icon-browser:
|
flatpak-manual:icon-browser:
|
||||||
extends: '.flatpak-defaults'
|
extends: .flatpak-manual
|
||||||
needs: []
|
needs: []
|
||||||
variables:
|
variables:
|
||||||
APPID: org.gtk.IconBrowser4
|
APPID: org.gtk.IconBrowser4
|
||||||
|
|
||||||
flatpak:icon-browser:aarch64:
|
flatpak-main:icon-browser:
|
||||||
extends: '.flatpak-defaults'
|
extends: .flatpak-main
|
||||||
needs: []
|
needs: []
|
||||||
tags:
|
|
||||||
- flatpak-aarch64
|
|
||||||
variables:
|
variables:
|
||||||
APPID: org.gtk.IconBrowser4
|
APPID: org.gtk.IconBrowser4
|
||||||
|
|
||||||
flatpak:node-editor:
|
flatpak-manual:node-editor:
|
||||||
extends: '.flatpak-defaults'
|
extends: .flatpak-manual
|
||||||
needs: []
|
needs: []
|
||||||
variables:
|
variables:
|
||||||
APPID: org.gtk.gtk4.NodeEditor
|
APPID: org.gtk.gtk4.NodeEditor
|
||||||
|
|
||||||
flatpak:node-editor:aarch64:
|
flatpak-main:node-editor:
|
||||||
extends: '.flatpak-defaults'
|
extends: .flatpak-main
|
||||||
needs: []
|
needs: []
|
||||||
tags:
|
|
||||||
- flatpak-aarch64
|
|
||||||
variables:
|
variables:
|
||||||
APPID: org.gtk.gtk4.NodeEditor
|
APPID: org.gtk.gtk4.NodeEditor
|
||||||
|
|
||||||
@@ -360,35 +310,23 @@ flatpak:node-editor:aarch64:
|
|||||||
# https://gitlab.gnome.org/GNOME/Initiatives/-/wikis/DevOps-with-Flatpak
|
# https://gitlab.gnome.org/GNOME/Initiatives/-/wikis/DevOps-with-Flatpak
|
||||||
nightly demo:
|
nightly demo:
|
||||||
extends: '.publish_nightly'
|
extends: '.publish_nightly'
|
||||||
needs: ['flatpak:demo']
|
dependencies: ['flatpak-main:demo']
|
||||||
|
needs: ['flatpak-main:demo']
|
||||||
nightly demo aarch64:
|
|
||||||
extends: '.publish_nightly'
|
|
||||||
needs: ['flatpak:demo:aarch64']
|
|
||||||
|
|
||||||
nightly factory:
|
nightly factory:
|
||||||
extends: '.publish_nightly'
|
extends: '.publish_nightly'
|
||||||
needs: ['flatpak:widget-factory']
|
dependencies: ['flatpak-main:widget-factory']
|
||||||
|
needs: ['flatpak-main:widget-factory']
|
||||||
nightly factory aarch64:
|
|
||||||
extends: '.publish_nightly'
|
|
||||||
needs: ['flatpak:widget-factory:aarch64']
|
|
||||||
|
|
||||||
nightly icon-browser:
|
nightly icon-browser:
|
||||||
extends: '.publish_nightly'
|
extends: '.publish_nightly'
|
||||||
needs: ['flatpak:icon-browser']
|
dependencies: ['flatpak-main:icon-browser']
|
||||||
|
needs: ['flatpak-main:icon-browser']
|
||||||
nightly icon-browser aarch64:
|
|
||||||
extends: '.publish_nightly'
|
|
||||||
needs: ['flatpak:icon-browser:aarch64']
|
|
||||||
|
|
||||||
nightly node-editor:
|
nightly node-editor:
|
||||||
extends: '.publish_nightly'
|
extends: '.publish_nightly'
|
||||||
needs: ['flatpak:node-editor']
|
dependencies: ['flatpak-main:node-editor']
|
||||||
|
needs: ['flatpak-main:node-editor']
|
||||||
nightly node-editor aarch64:
|
|
||||||
extends: '.publish_nightly'
|
|
||||||
needs: ['flatpak:node-editor:aarch64']
|
|
||||||
|
|
||||||
static-scan:
|
static-scan:
|
||||||
image: $FEDORA_IMAGE
|
image: $FEDORA_IMAGE
|
||||||
@@ -397,63 +335,38 @@ static-scan:
|
|||||||
variables:
|
variables:
|
||||||
EXTRA_MESON_FLAGS: "--buildtype=debug"
|
EXTRA_MESON_FLAGS: "--buildtype=debug"
|
||||||
script:
|
script:
|
||||||
- export PATH="$HOME/.local/bin:$PATH"
|
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} _scan_build
|
||||||
- meson setup
|
|
||||||
${COMMON_MESON_FLAGS}
|
|
||||||
${EXTRA_MESON_FLAGS}
|
|
||||||
${BACKEND_FLAGS}
|
|
||||||
${FEATURE_FLAGS}
|
|
||||||
_scan_build
|
|
||||||
- ninja -C _scan_build scan-build
|
- ninja -C _scan_build scan-build
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- _scan_build/meson-logs
|
- _scan_build/meson-logs
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
|
||||||
# Run tests with the address sanitizer. We need to turn off introspection
|
# Run tests with the address sanitizer. We need to turn off introspection,
|
||||||
# and f16c, since they are incompatible with asan
|
# since it is incompatible with asan
|
||||||
asan-build:
|
asan-build:
|
||||||
extends: .build-fedora-default
|
image: $FEDORA_IMAGE
|
||||||
tags: [ asan ]
|
tags: [ asan ]
|
||||||
stage: analysis
|
stage: analysis
|
||||||
needs: []
|
needs: []
|
||||||
variables:
|
variables:
|
||||||
MESON_TEST_MAX_PROCESSES: 4
|
|
||||||
script:
|
script:
|
||||||
- export PATH="$HOME/.local/bin:$PATH"
|
- CC=clang meson --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=disabled _build
|
||||||
- CC=clang meson setup
|
|
||||||
--buildtype=debugoptimized
|
|
||||||
-Db_sanitize=address
|
|
||||||
-Db_lundef=false
|
|
||||||
-Dbuild-demos=false
|
|
||||||
-Dbuild-tests=false
|
|
||||||
-Dbuild-examples=false
|
|
||||||
-Dintrospection=disabled
|
|
||||||
-Df16c=disabled
|
|
||||||
_build
|
|
||||||
- ninja -C _build
|
- ninja -C _build
|
||||||
- .gitlab-ci/run-tests.sh _build wayland gtk
|
- .gitlab-ci/run-tests.sh _build wayland
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- _build/meson-logs
|
||||||
|
allow_failure: true
|
||||||
|
|
||||||
reference:
|
reference:
|
||||||
image: $FEDORA_IMAGE
|
image: $FEDORA_IMAGE
|
||||||
stage: docs
|
stage: docs
|
||||||
needs: []
|
needs: []
|
||||||
|
variables:
|
||||||
|
EXTRA_MESON_FLAGS: "--buildtype=release --force-fallback-for=gdk-pixbuf,pango"
|
||||||
script:
|
script:
|
||||||
- export PATH="$HOME/.local/bin:$PATH"
|
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} -Dgtk_doc=true -Dgdk-pixbuf:gtk_doc=true -Dpango:gtk_doc=true _build
|
||||||
- meson setup
|
|
||||||
${COMMON_MESON_FLAGS}
|
|
||||||
--buildtype=release
|
|
||||||
--force-fallback-for=gdk-pixbuf,pango
|
|
||||||
-Dintrospection=enabled
|
|
||||||
-Ddocumentation=true
|
|
||||||
-Dman-pages=true
|
|
||||||
-Dgdk-pixbuf:gtk_doc=true
|
|
||||||
-Dpango:documentation=true
|
|
||||||
-Dbuild-demos=true
|
|
||||||
-Dbuild-examples=false
|
|
||||||
-Dbuild-tests=false
|
|
||||||
-Dbuild-testsuite=false
|
|
||||||
_build
|
|
||||||
- meson compile -C _build
|
- meson compile -C _build
|
||||||
- mkdir -p _reference/
|
- mkdir -p _reference/
|
||||||
- mv _build/docs/reference/gdk/gdk4/ _reference/gdk4/
|
- mv _build/docs/reference/gdk/gdk4/ _reference/gdk4/
|
||||||
@@ -461,7 +374,6 @@ reference:
|
|||||||
- mv _build/docs/reference/gdk/gdk4-wayland/ _reference/gdk4-wayland/
|
- mv _build/docs/reference/gdk/gdk4-wayland/ _reference/gdk4-wayland/
|
||||||
- mv _build/docs/reference/gsk/gsk4/ _reference/gsk4/
|
- mv _build/docs/reference/gsk/gsk4/ _reference/gsk4/
|
||||||
- mv _build/docs/reference/gtk/gtk4/ _reference/gtk4/
|
- mv _build/docs/reference/gtk/gtk4/ _reference/gtk4/
|
||||||
- mv _build/docs/reference/gtk/*.html _reference/gtk4/
|
|
||||||
- mv _build/subprojects/pango/docs/Pango/ _reference/Pango/
|
- mv _build/subprojects/pango/docs/Pango/ _reference/Pango/
|
||||||
- mv _build/subprojects/pango/docs/PangoCairo/ _reference/PangoCairo/
|
- mv _build/subprojects/pango/docs/PangoCairo/ _reference/PangoCairo/
|
||||||
- mv _build/subprojects/pango/docs/PangoFc/ _reference/PangoFc/
|
- mv _build/subprojects/pango/docs/PangoFc/ _reference/PangoFc/
|
||||||
@@ -477,10 +389,9 @@ reference:
|
|||||||
publish-docs:
|
publish-docs:
|
||||||
image: fedora:latest
|
image: fedora:latest
|
||||||
stage: publish
|
stage: publish
|
||||||
interruptible: false
|
|
||||||
needs: ['reference']
|
needs: ['reference']
|
||||||
script:
|
script:
|
||||||
- "curl -X POST -F token=${PAGES_TRIGGER_TOKEN} -F ref=docs-gtk-org https://gitlab.gnome.org/api/v4/projects/665/trigger/pipeline"
|
- "curl -X POST -F token=${PAGES_TRIGGER_TOKEN} -F ref=docs-gtk-org https://gitlab.gnome.org/api/v4/projects/665/trigger/pipeline"
|
||||||
rules:
|
only:
|
||||||
- if: $CI_COMMIT_REF_NAME == "main"
|
refs:
|
||||||
|
- main
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
FROM fedora:40
|
FROM fedora:36
|
||||||
|
|
||||||
RUN dnf -y install \
|
RUN dnf -y install \
|
||||||
adwaita-icon-theme \
|
adwaita-icon-theme \
|
||||||
|
atk-devel \
|
||||||
|
at-spi2-atk-devel \
|
||||||
avahi-gobject-devel \
|
avahi-gobject-devel \
|
||||||
cairo-devel \
|
cairo-devel \
|
||||||
cairo-gobject-devel \
|
cairo-gobject-devel \
|
||||||
@@ -17,7 +19,6 @@ RUN dnf -y install \
|
|||||||
desktop-file-utils \
|
desktop-file-utils \
|
||||||
diffutils \
|
diffutils \
|
||||||
elfutils-libelf-devel \
|
elfutils-libelf-devel \
|
||||||
expat-devel \
|
|
||||||
fribidi-devel \
|
fribidi-devel \
|
||||||
gcc \
|
gcc \
|
||||||
gcc-c++ \
|
gcc-c++ \
|
||||||
@@ -29,8 +30,7 @@ RUN dnf -y install \
|
|||||||
glib2-static \
|
glib2-static \
|
||||||
glibc-devel \
|
glibc-devel \
|
||||||
glibc-headers \
|
glibc-headers \
|
||||||
glslc \
|
gnome-desktop-testing \
|
||||||
gnupg2 \
|
|
||||||
gobject-introspection-devel \
|
gobject-introspection-devel \
|
||||||
graphene-devel \
|
graphene-devel \
|
||||||
graphviz \
|
graphviz \
|
||||||
@@ -71,22 +71,18 @@ RUN dnf -y install \
|
|||||||
mesa-libEGL-devel \
|
mesa-libEGL-devel \
|
||||||
mesa-libGLES-devel \
|
mesa-libGLES-devel \
|
||||||
meson \
|
meson \
|
||||||
mutter \
|
|
||||||
ninja-build \
|
ninja-build \
|
||||||
pango-devel \
|
pango-devel \
|
||||||
pcre-devel \
|
pcre-devel \
|
||||||
pcre-static \
|
pcre-static \
|
||||||
pipewire \
|
|
||||||
pipewire-gstreamer \
|
|
||||||
python3 \
|
python3 \
|
||||||
python3-docutils \
|
python3-docutils \
|
||||||
python3-gobject \
|
python3-gobject \
|
||||||
python3-jinja2 \
|
python3-jinja2 \
|
||||||
python3-markdown \
|
python3-markdown \
|
||||||
python3-packaging \
|
|
||||||
python3-pip \
|
python3-pip \
|
||||||
python3-pydbus \
|
|
||||||
python3-pygments \
|
python3-pygments \
|
||||||
|
python3-toml \
|
||||||
python3-typogrify \
|
python3-typogrify \
|
||||||
python3-wheel \
|
python3-wheel \
|
||||||
redhat-rpm-config \
|
redhat-rpm-config \
|
||||||
@@ -97,13 +93,11 @@ RUN dnf -y install \
|
|||||||
weston \
|
weston \
|
||||||
weston-libs \
|
weston-libs \
|
||||||
which \
|
which \
|
||||||
wireplumber \
|
|
||||||
xorg-x11-server-Xvfb \
|
xorg-x11-server-Xvfb \
|
||||||
&& dnf -y update \
|
&& dnf install -y 'dnf-command(builddep)' \
|
||||||
|
&& dnf builddep -y wayland \
|
||||||
&& dnf clean all
|
&& dnf clean all
|
||||||
|
|
||||||
RUN rm /usr/share/vulkan/icd.d/powervr_mesa_icd.x86_64.json
|
|
||||||
|
|
||||||
# Enable sudo for wheel users
|
# Enable sudo for wheel users
|
||||||
RUN sed -i -e 's/# %wheel/%wheel/' -e '0,/%wheel/{s/%wheel/# %wheel/}' /etc/sudoers
|
RUN sed -i -e 's/# %wheel/%wheel/' -e '0,/%wheel/{s/%wheel/# %wheel/}' /etc/sudoers
|
||||||
|
|
||||||
|
@@ -20,14 +20,13 @@ flatpak build ${builddir} meson \
|
|||||||
-Dx11-backend=true \
|
-Dx11-backend=true \
|
||||||
-Dwayland-backend=true \
|
-Dwayland-backend=true \
|
||||||
-Dbuild-tests=false \
|
-Dbuild-tests=false \
|
||||||
-Dbuild-testsuite=false \
|
|
||||||
-Dbuild-examples=false \
|
-Dbuild-examples=false \
|
||||||
-Dintrospection=disabled \
|
-Dintrospection=disabled \
|
||||||
-Dbuild-demos=true \
|
-Ddemos=true \
|
||||||
-Dprofile=devel \
|
-Dprofile=devel \
|
||||||
_flatpak_build
|
_flatpak_build
|
||||||
|
|
||||||
flatpak build --env=CI_COMMIT_SHORT_SHA=$CI_COMMIT_SHORT_SHA ${builddir} ninja -C _flatpak_build install
|
flatpak build ${builddir} ninja -C _flatpak_build install
|
||||||
|
|
||||||
flatpak-builder \
|
flatpak-builder \
|
||||||
--user --disable-rofiles-fuse \
|
--user --disable-rofiles-fuse \
|
||||||
|
@@ -1,91 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat <<-EOF
|
|
||||||
Usage: $(basename $0) [OPTION…] REPO_URL COMMIT
|
|
||||||
|
|
||||||
Check out and install a meson project
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-Dkey=val Option to pass on to meson
|
|
||||||
--prefix Prefix to install to
|
|
||||||
--subdir Build subdirectory instead of whole project
|
|
||||||
--prepare Script to run before build
|
|
||||||
|
|
||||||
-h, --help Display this help
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
TEMP=$(getopt \
|
|
||||||
--name=$(basename $0) \
|
|
||||||
--options='D:h' \
|
|
||||||
--longoptions='prefix:' \
|
|
||||||
--longoptions='subdir:' \
|
|
||||||
--longoptions='prepare:' \
|
|
||||||
--longoptions='help' \
|
|
||||||
-- "$@")
|
|
||||||
|
|
||||||
eval set -- "$TEMP"
|
|
||||||
unset TEMP
|
|
||||||
|
|
||||||
MESON_OPTIONS=()
|
|
||||||
PREFIX=/usr
|
|
||||||
SUBDIR=.
|
|
||||||
PREPARE=:
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
case "$1" in
|
|
||||||
-D)
|
|
||||||
MESON_OPTIONS+=( -D$2 )
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
|
|
||||||
--prefix)
|
|
||||||
PREFIX=$2
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
|
|
||||||
--subdir)
|
|
||||||
SUBDIR=$2
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
|
|
||||||
--prepare)
|
|
||||||
PREPARE=$2
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
|
|
||||||
-h|--help)
|
|
||||||
usage
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
|
|
||||||
--)
|
|
||||||
shift
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ $# -lt 2 ]]; then
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
REPO_URL="$1"
|
|
||||||
COMMIT="$2"
|
|
||||||
|
|
||||||
CHECKOUT_DIR=$(mktemp --directory)
|
|
||||||
trap "rm -rf $CHECKOUT_DIR" EXIT
|
|
||||||
|
|
||||||
git clone --depth 1 "$REPO_URL" -b "$COMMIT" "$CHECKOUT_DIR"
|
|
||||||
|
|
||||||
pushd "$CHECKOUT_DIR/$SUBDIR"
|
|
||||||
sh -c "$PREPARE"
|
|
||||||
meson setup --prefix "$PREFIX" _build "${MESON_OPTIONS[@]}"
|
|
||||||
meson compile -C _build
|
|
||||||
meson install -C _build
|
|
||||||
popd
|
|
@@ -324,7 +324,7 @@ for line in args.infile:
|
|||||||
units.append(unit)
|
units.append(unit)
|
||||||
|
|
||||||
report = {}
|
report = {}
|
||||||
report['date'] = datetime.datetime.now(datetime.UTC)
|
report['date'] = datetime.datetime.utcnow()
|
||||||
report['locale_date'] = report['date'].strftime("%c")
|
report['locale_date'] = report['date'].strftime("%c")
|
||||||
report['project_name'] = args.project_name
|
report['project_name'] = args.project_name
|
||||||
report['backend'] = args.backend
|
report['backend'] = args.backend
|
||||||
|
@@ -44,7 +44,7 @@ outfile = args.output
|
|||||||
testsuites = ET.Element('testsuites')
|
testsuites = ET.Element('testsuites')
|
||||||
testsuites.set('id', '{}/{}'.format(args.job_id, args.branch))
|
testsuites.set('id', '{}/{}'.format(args.job_id, args.branch))
|
||||||
testsuites.set('package', args.project_name)
|
testsuites.set('package', args.project_name)
|
||||||
testsuites.set('timestamp', datetime.datetime.now(datetime.UTC).isoformat(timespec='minutes'))
|
testsuites.set('timestamp', datetime.datetime.utcnow().isoformat(timespec='minutes'))
|
||||||
|
|
||||||
suites = {}
|
suites = {}
|
||||||
for line in args.infile:
|
for line in args.infile:
|
||||||
|
@@ -23,7 +23,6 @@ push=0
|
|||||||
list=0
|
list=0
|
||||||
print_help=0
|
print_help=0
|
||||||
no_login=0
|
no_login=0
|
||||||
no_cache=0
|
|
||||||
|
|
||||||
while (($# > 0)); do
|
while (($# > 0)); do
|
||||||
case "${1%%=*}" in
|
case "${1%%=*}" in
|
||||||
@@ -35,7 +34,6 @@ while (($# > 0)); do
|
|||||||
--base|-b) read_arg base "$@" || shift;;
|
--base|-b) read_arg base "$@" || shift;;
|
||||||
--version|-v) read_arg base_version "$@" || shift;;
|
--version|-v) read_arg base_version "$@" || shift;;
|
||||||
--no-login) no_login=1;;
|
--no-login) no_login=1;;
|
||||||
--no-cache) no_cache=1;;
|
|
||||||
*) echo -e "\e[1;31mERROR\e[0m: Unknown option '$1'"; exit 1;;
|
*) echo -e "\e[1;31mERROR\e[0m: Unknown option '$1'"; exit 1;;
|
||||||
esac
|
esac
|
||||||
shift
|
shift
|
||||||
@@ -105,21 +103,11 @@ TAG="${REGISTRY}/gnome/gtk/${base}:${base_version}"
|
|||||||
|
|
||||||
if [ $build == 1 ]; then
|
if [ $build == 1 ]; then
|
||||||
echo -e "\e[1;32mBUILDING\e[0m: ${base} as ${TAG}"
|
echo -e "\e[1;32mBUILDING\e[0m: ${base} as ${TAG}"
|
||||||
if [ $no_cache == 0 ]; then
|
${CMD} build \
|
||||||
${CMD} build \
|
${format} \
|
||||||
${format} \
|
--build-arg HOST_USER_ID="$UID" \
|
||||||
--build-arg HOST_USER_ID="$UID" \
|
--tag "${TAG}" \
|
||||||
--tag "${TAG}" \
|
--file "${base}.Dockerfile" .
|
||||||
--file "${base}.Dockerfile" .
|
|
||||||
else
|
|
||||||
${CMD} build \
|
|
||||||
${format} \
|
|
||||||
--no-cache \
|
|
||||||
--build-arg HOST_USER_ID="$UID" \
|
|
||||||
--tag "${TAG}" \
|
|
||||||
--file "${base}.Dockerfile" .
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -138,8 +126,7 @@ if [ $run == 1 ]; then
|
|||||||
echo -e "\e[1;32mRUNNING\e[0m: ${base} as ${TAG}"
|
echo -e "\e[1;32mRUNNING\e[0m: ${base} as ${TAG}"
|
||||||
${CMD} run \
|
${CMD} run \
|
||||||
--rm \
|
--rm \
|
||||||
--userns=keep-id \
|
--volume "$(pwd)/..:/home/user/app" \
|
||||||
--volume "$(pwd)/..:/home/user/app:rw,z" \
|
|
||||||
--workdir "/home/user/app" \
|
--workdir "/home/user/app" \
|
||||||
--tty \
|
--tty \
|
||||||
--interactive "${TAG}" \
|
--interactive "${TAG}" \
|
||||||
|
@@ -1,32 +0,0 @@
|
|||||||
#!/usr/bin/sh
|
|
||||||
#
|
|
||||||
builddir=$1
|
|
||||||
suite=$2
|
|
||||||
unit=$3
|
|
||||||
|
|
||||||
echo "** builddir: ${builddir}"
|
|
||||||
echo "** suite: ${suite}"
|
|
||||||
echo "** unit: ${unit}"
|
|
||||||
|
|
||||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
|
||||||
|
|
||||||
weston --backend=headless-backend.so --socket=wayland-5 --idle-time=0 &
|
|
||||||
compositor=$!
|
|
||||||
|
|
||||||
export WAYLAND_DISPLAY=wayland-5
|
|
||||||
|
|
||||||
meson test -C ${builddir} \
|
|
||||||
--print-errorlogs \
|
|
||||||
--setup=wayland \
|
|
||||||
--suite=${suite} \
|
|
||||||
--no-suite=failing \
|
|
||||||
--no-suite=flaky \
|
|
||||||
--no-suite=wayland_failing \
|
|
||||||
--no-suite=gsk-compare-broadway \
|
|
||||||
--verbose \
|
|
||||||
"${unit}"
|
|
||||||
|
|
||||||
exit_code=$?
|
|
||||||
kill ${compositor}
|
|
||||||
|
|
||||||
exit ${exit_code}
|
|
@@ -1,33 +1,24 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -x
|
set +x
|
||||||
set +e
|
set +e
|
||||||
|
|
||||||
srcdir=$( pwd )
|
srcdir=$( pwd )
|
||||||
builddir=$1
|
builddir=$1
|
||||||
setup=$2
|
backend=$2
|
||||||
suite=$3
|
|
||||||
multiplier=${MESON_TEST_TIMEOUT_MULTIPLIER:-1}
|
|
||||||
n_processes=${MESON_TEST_MAX_PROCESSES:-1}
|
|
||||||
|
|
||||||
# Ignore memory leaks lower in dependencies
|
# Ignore memory leaks lower in dependencies
|
||||||
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:detect_leaks=0:allocator_may_return_null=1
|
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0
|
||||||
|
export G_SLICE=always-malloc
|
||||||
|
|
||||||
case "${setup}" in
|
case "${backend}" in
|
||||||
x11*)
|
x11)
|
||||||
dbus-run-session -- \
|
xvfb-run -a -s "-screen 0 1024x768x24 -noreset" \
|
||||||
xvfb-run -a -s "-screen 0 1024x768x24 -noreset" \
|
|
||||||
meson test -C ${builddir} \
|
meson test -C ${builddir} \
|
||||||
--quiet \
|
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||||
--timeout-multiplier "${multiplier}" \
|
|
||||||
--num-processes "${n_processes}" \
|
|
||||||
--print-errorlogs \
|
--print-errorlogs \
|
||||||
--setup=${setup} \
|
--setup=${backend} \
|
||||||
--suite=${suite//,/ --suite=} \
|
--suite=gtk \
|
||||||
--no-suite=failing \
|
|
||||||
--no-suite=${setup}_failing \
|
|
||||||
--no-suite=flaky \
|
|
||||||
--no-suite=headless \
|
|
||||||
--no-suite=gsk-compare-broadway
|
--no-suite=gsk-compare-broadway
|
||||||
|
|
||||||
# Store the exit code for the CI run, but always
|
# Store the exit code for the CI run, but always
|
||||||
@@ -35,57 +26,63 @@ case "${setup}" in
|
|||||||
exit_code=$?
|
exit_code=$?
|
||||||
;;
|
;;
|
||||||
|
|
||||||
wayland*)
|
wayland)
|
||||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||||
|
|
||||||
weston --backend=headless-backend.so --socket=wayland-5 --idle-time=0 &
|
weston --backend=headless-backend.so --socket=wayland-5 --idle-time=0 &
|
||||||
compositor=$!
|
compositor=$!
|
||||||
export WAYLAND_DISPLAY=wayland-5
|
export WAYLAND_DISPLAY=wayland-5
|
||||||
|
|
||||||
dbus-run-session -- \
|
meson test -C ${builddir} \
|
||||||
meson test -C ${builddir} \
|
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||||
--quiet \
|
|
||||||
--timeout-multiplier "${multiplier}" \
|
|
||||||
--num-processes "${n_processes}" \
|
|
||||||
--print-errorlogs \
|
--print-errorlogs \
|
||||||
--setup=${setup} \
|
--setup=${backend} \
|
||||||
--suite=${suite//,/ --suite=} \
|
--suite=gtk \
|
||||||
--no-suite=failing \
|
|
||||||
--no-suite=${setup}_failing \
|
|
||||||
--no-suite=flaky \
|
|
||||||
--no-suite=headless \
|
|
||||||
--no-suite=gsk-compare-broadway
|
--no-suite=gsk-compare-broadway
|
||||||
exit_code=$?
|
|
||||||
|
|
||||||
|
exit_code=$?
|
||||||
kill ${compositor}
|
kill ${compositor}
|
||||||
;;
|
;;
|
||||||
|
|
||||||
broadway*)
|
waylandgles)
|
||||||
|
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||||
|
|
||||||
|
weston --backend=headless-backend.so --socket=wayland-6 --idle-time=0 &
|
||||||
|
compositor=$!
|
||||||
|
export WAYLAND_DISPLAY=wayland-6
|
||||||
|
|
||||||
|
meson test -C ${builddir} \
|
||||||
|
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||||
|
--print-errorlogs \
|
||||||
|
--setup=${backend} \
|
||||||
|
--suite=gtk \
|
||||||
|
--no-suite=gsk-compare-broadway
|
||||||
|
|
||||||
|
exit_code=$?
|
||||||
|
kill ${compositor}
|
||||||
|
;;
|
||||||
|
|
||||||
|
broadway)
|
||||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||||
|
|
||||||
${builddir}/gdk/broadway/gtk4-broadwayd :5 &
|
${builddir}/gdk/broadway/gtk4-broadwayd :5 &
|
||||||
server=$!
|
server=$!
|
||||||
export BROADWAY_DISPLAY=:5
|
export BROADWAY_DISPLAY=:5
|
||||||
|
|
||||||
dbus-run-session -- \
|
meson test -C ${builddir} \
|
||||||
meson test -C ${builddir} \
|
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||||
--quiet \
|
|
||||||
--timeout-multiplier "${multiplier}" \
|
|
||||||
--num-processes "${n_processes}" \
|
|
||||||
--print-errorlogs \
|
--print-errorlogs \
|
||||||
--setup=${setup} \
|
--setup=${backend} \
|
||||||
--suite=${suite//,/ --suite=} \
|
--suite=gtk \
|
||||||
--no-suite=failing \
|
|
||||||
--no-suite=${setup}_failing \
|
|
||||||
--no-suite=flaky \
|
|
||||||
--no-suite=headless \
|
|
||||||
--no-suite=gsk-compare-opengl
|
--no-suite=gsk-compare-opengl
|
||||||
|
|
||||||
|
# don't let Broadway failures fail the run, for now
|
||||||
|
exit_code=0
|
||||||
kill ${server}
|
kill ${server}
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo "Failed to add ${setup} to .gitlab-ci/run-tests.sh"
|
echo "Failed to add ${backend} to .gitlab-ci/run-tests.sh"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
@@ -94,18 +91,17 @@ esac
|
|||||||
cd ${builddir}
|
cd ${builddir}
|
||||||
|
|
||||||
$srcdir/.gitlab-ci/meson-junit-report.py \
|
$srcdir/.gitlab-ci/meson-junit-report.py \
|
||||||
--project-name=gtk \
|
--project-name=gtk \
|
||||||
--backend="${setup}" \
|
--backend=${backend} \
|
||||||
--job-id="${CI_JOB_NAME}" \
|
--job-id="${CI_JOB_NAME}" \
|
||||||
--output="report-${setup}.xml" \
|
--output=report-${backend}.xml \
|
||||||
"meson-logs/testlog-${setup}.json"
|
meson-logs/testlog-${backend}.json
|
||||||
|
|
||||||
$srcdir/.gitlab-ci/meson-html-report.py \
|
$srcdir/.gitlab-ci/meson-html-report.py \
|
||||||
--project-name=gtk \
|
--project-name=gtk \
|
||||||
--backend="${setup}" \
|
--backend=${backend} \
|
||||||
--job-id="${CI_JOB_NAME}" \
|
--job-id="${CI_JOB_NAME}" \
|
||||||
--reftest-output-dir="testsuite/reftests/output/${setup}" \
|
--reftest-output-dir="testsuite/reftests/output/${backend}" \
|
||||||
--output="report-${setup}.html" \
|
--output=report-${backend}.html \
|
||||||
"meson-logs/testlog-${setup}.json"
|
meson-logs/testlog-${backend}.json
|
||||||
|
|
||||||
exit $exit_code
|
exit $exit_code
|
||||||
|
@@ -3,11 +3,6 @@
|
|||||||
set -eux -o pipefail
|
set -eux -o pipefail
|
||||||
|
|
||||||
xcodebuild -version || :
|
xcodebuild -version || :
|
||||||
|
xcodebuild -showsdks || :
|
||||||
if [ -z "$SDKROOT" ]; then
|
|
||||||
xcodebuild -showsdks || :
|
|
||||||
else
|
|
||||||
echo "SDKROOT = $SDKROOT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
system_profiler SPSoftwareDataType || :
|
system_profiler SPSoftwareDataType || :
|
@@ -5,8 +5,8 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
|
|||||||
@echo on
|
@echo on
|
||||||
|
|
||||||
:: FIXME: make warnings fatal
|
:: FIXME: make warnings fatal
|
||||||
pip3 install --upgrade --user meson~=0.64 || goto :error
|
pip3 install --upgrade --user meson==0.60.3 || goto :error
|
||||||
meson setup -Dbackend_max_links=1 -Ddebug=false -Dmedia-gstreamer=disabled -Dvulkan=disabled _build || goto :error
|
meson -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error
|
||||||
ninja -C _build || goto :error
|
ninja -C _build || goto :error
|
||||||
|
|
||||||
goto :EOF
|
goto :EOF
|
||||||
|
@@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
if [[ "$MSYSTEM" == "MINGW32" ]]; then
|
||||||
|
export MSYS2_ARCH="i686"
|
||||||
|
else
|
||||||
|
export MSYS2_ARCH="x86_64"
|
||||||
|
fi
|
||||||
|
|
||||||
# Update everything
|
# Update everything
|
||||||
pacman --noconfirm -Suy
|
pacman --noconfirm -Suy
|
||||||
|
|
||||||
@@ -9,27 +15,24 @@ pacman --noconfirm -Suy
|
|||||||
pacman --noconfirm -S --needed \
|
pacman --noconfirm -S --needed \
|
||||||
base-devel \
|
base-devel \
|
||||||
git \
|
git \
|
||||||
${MINGW_PACKAGE_PREFIX}-cc \
|
mingw-w64-$MSYS2_ARCH-cc \
|
||||||
${MINGW_PACKAGE_PREFIX}-ccache \
|
mingw-w64-$MSYS2_ARCH-ccache \
|
||||||
${MINGW_PACKAGE_PREFIX}-pkgconf \
|
mingw-w64-$MSYS2_ARCH-pkgconf \
|
||||||
${MINGW_PACKAGE_PREFIX}-gobject-introspection \
|
mingw-w64-$MSYS2_ARCH-gobject-introspection \
|
||||||
${MINGW_PACKAGE_PREFIX}-meson \
|
mingw-w64-$MSYS2_ARCH-meson \
|
||||||
${MINGW_PACKAGE_PREFIX}-adwaita-icon-theme \
|
mingw-w64-$MSYS2_ARCH-adwaita-icon-theme \
|
||||||
${MINGW_PACKAGE_PREFIX}-atk \
|
mingw-w64-$MSYS2_ARCH-atk \
|
||||||
${MINGW_PACKAGE_PREFIX}-cairo \
|
mingw-w64-$MSYS2_ARCH-cairo \
|
||||||
${MINGW_PACKAGE_PREFIX}-gdk-pixbuf2 \
|
mingw-w64-$MSYS2_ARCH-gdk-pixbuf2 \
|
||||||
${MINGW_PACKAGE_PREFIX}-glib2 \
|
mingw-w64-$MSYS2_ARCH-glib2 \
|
||||||
${MINGW_PACKAGE_PREFIX}-graphene \
|
mingw-w64-$MSYS2_ARCH-graphene \
|
||||||
${MINGW_PACKAGE_PREFIX}-json-glib \
|
mingw-w64-$MSYS2_ARCH-json-glib \
|
||||||
${MINGW_PACKAGE_PREFIX}-libepoxy \
|
mingw-w64-$MSYS2_ARCH-libepoxy \
|
||||||
${MINGW_PACKAGE_PREFIX}-pango \
|
mingw-w64-$MSYS2_ARCH-pango \
|
||||||
${MINGW_PACKAGE_PREFIX}-fribidi \
|
mingw-w64-$MSYS2_ARCH-fribidi \
|
||||||
${MINGW_PACKAGE_PREFIX}-gst-plugins-bad-libs \
|
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
|
||||||
${MINGW_PACKAGE_PREFIX}-shared-mime-info \
|
mingw-w64-$MSYS2_ARCH-shared-mime-info \
|
||||||
${MINGW_PACKAGE_PREFIX}-python-gobject \
|
mingw-w64-$MSYS2_ARCH-python-gobject
|
||||||
${MINGW_PACKAGE_PREFIX}-shaderc \
|
|
||||||
${MINGW_PACKAGE_PREFIX}-vulkan \
|
|
||||||
${MINGW_PACKAGE_PREFIX}-vulkan-headers
|
|
||||||
|
|
||||||
mkdir -p _ccache
|
mkdir -p _ccache
|
||||||
export CCACHE_BASEDIR="$(pwd)"
|
export CCACHE_BASEDIR="$(pwd)"
|
||||||
@@ -39,10 +42,11 @@ export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
|
|||||||
ccache --zero-stats
|
ccache --zero-stats
|
||||||
ccache --show-stats
|
ccache --show-stats
|
||||||
export CCACHE_DISABLE=true
|
export CCACHE_DISABLE=true
|
||||||
meson setup \
|
meson \
|
||||||
-Dx11-backend=false \
|
-Dx11-backend=false \
|
||||||
-Dwayland-backend=false \
|
-Dwayland-backend=false \
|
||||||
-Dwin32-backend=true \
|
-Dwin32-backend=true \
|
||||||
|
-Dvulkan=disabled \
|
||||||
-Dintrospection=enabled \
|
-Dintrospection=enabled \
|
||||||
-Dgtk:werror=true \
|
-Dgtk:werror=true \
|
||||||
_build
|
_build
|
||||||
|
@@ -34,9 +34,7 @@
|
|||||||
<!--
|
<!--
|
||||||
- Which version of GTK you are using
|
- Which version of GTK you are using
|
||||||
- What operating system and version
|
- What operating system and version
|
||||||
- What windowing system (X11 or Wayland)
|
- For Linux, which distribution
|
||||||
- What graphics driver / mesa version
|
|
||||||
- For Linux, which distribution
|
|
||||||
- If you built GTK yourself, the list of options used to configure the build
|
- If you built GTK yourself, the list of options used to configure the build
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
45
AUTHORS
@@ -7,7 +7,7 @@ Peter Mattis <petm@xcf.berkeley.edu>
|
|||||||
Spencer Kimball <spencer@xcf.berkeley.edu>
|
Spencer Kimball <spencer@xcf.berkeley.edu>
|
||||||
Josh MacDonald <jmacd@xcf.berkeley.edu>
|
Josh MacDonald <jmacd@xcf.berkeley.edu>
|
||||||
|
|
||||||
The team that build GTK 2 (in alphabetical order)
|
The Team that build GTK 2 (in alphabetical order)
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
Shawn T. Amundson <amundson@gtk.org>
|
Shawn T. Amundson <amundson@gtk.org>
|
||||||
Jerome Bolliet <bolliet@gtk.org>
|
Jerome Bolliet <bolliet@gtk.org>
|
||||||
@@ -28,8 +28,9 @@ Jay Painter <jpaint@gtk.org>
|
|||||||
Manish Singh <manish@gtk.org>
|
Manish Singh <manish@gtk.org>
|
||||||
Owen Taylor <otaylor@gtk.org>
|
Owen Taylor <otaylor@gtk.org>
|
||||||
|
|
||||||
The team that built GTK 3
|
The current team (GTK 3 and 4)
|
||||||
-------------------------
|
------------------------------
|
||||||
|
|
||||||
Jonas Ådahl <jadahl@gmail.com>
|
Jonas Ådahl <jadahl@gmail.com>
|
||||||
Tim Bäder <mail@baedert.org>
|
Tim Bäder <mail@baedert.org>
|
||||||
Emmanuele Bassi <ebassi@gnome.org>
|
Emmanuele Bassi <ebassi@gnome.org>
|
||||||
@@ -39,16 +40,6 @@ Carlos Garnacho <mrgarnacho@gmail.com>
|
|||||||
Alexander Larsson <alexl@redhat.com>
|
Alexander Larsson <alexl@redhat.com>
|
||||||
Benjamin Otte <otte@gnome.org>
|
Benjamin Otte <otte@gnome.org>
|
||||||
|
|
||||||
The current team (GTK 4)
|
|
||||||
------------------------
|
|
||||||
Jonas Ådahl <jadahl@gmail.com>
|
|
||||||
Emmanuele Bassi <ebassi@gnome.org>
|
|
||||||
Christian Hergert <chergert@gnome.org>
|
|
||||||
Chun-wei Fan <fanchunwei@src.gnome.org>
|
|
||||||
Matthias Clasen <mclasen@redhat.com>
|
|
||||||
Carlos Garnacho <mrgarnacho@gmail.com>
|
|
||||||
Benjamin Otte <otte@gnome.org>
|
|
||||||
|
|
||||||
|
|
||||||
There are many others who have contributed patches; we thank them,
|
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.
|
||||||
@@ -58,15 +49,35 @@ Over time, GTK has incorporated some pieces of software which
|
|||||||
started as independent projects. We list the original authors here:
|
started as independent projects. We list the original authors here:
|
||||||
|
|
||||||
|
|
||||||
|
MS-Windows theme engine
|
||||||
|
-----------------------
|
||||||
|
Raymond Penners
|
||||||
|
Dom Lachowicz
|
||||||
|
|
||||||
|
|
||||||
|
Pixbuf theme engine
|
||||||
|
-------------------
|
||||||
|
Owen Taylor
|
||||||
|
|
||||||
|
|
||||||
IME input method
|
IME input method
|
||||||
----------------
|
----------------
|
||||||
Takuro Ashie
|
Takuro Ashie
|
||||||
Kazuki IWAMOTO
|
Kazuki IWAMOTO
|
||||||
|
|
||||||
MacOS backend
|
|
||||||
-------------
|
Mac OS X backend
|
||||||
|
----------------
|
||||||
Anders Carlsson
|
Anders Carlsson
|
||||||
|
|
||||||
GtkInspector (originally gtkparasite)
|
|
||||||
-------------------------------------
|
DirectFB backend
|
||||||
|
----------------
|
||||||
|
Denis Oliver Kropp
|
||||||
|
Sven Neumann
|
||||||
|
Mike Emmel
|
||||||
|
|
||||||
|
|
||||||
|
gtkparasite
|
||||||
|
-----------
|
||||||
Christian Hammond
|
Christian Hammond
|
||||||
|
@@ -21,7 +21,7 @@ many things that we value:
|
|||||||
Please, do not use the issue tracker for support questions. If you have
|
Please, do not use the issue tracker for support questions. If you have
|
||||||
questions on how to use GTK effectively, you can use:
|
questions on how to use GTK effectively, you can use:
|
||||||
|
|
||||||
- the `gtk` [room on matrix](https://matrix.to/#/#gtk:gnome.org)
|
- the `#gtk` IRC channel on irc.gnome.org
|
||||||
- the [gtk tag on the GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
|
- the [gtk tag on the GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
|
||||||
|
|
||||||
You can also look at the GTK tag on [Stack
|
You can also look at the GTK tag on [Stack
|
||||||
@@ -35,7 +35,8 @@ The issue tracker is meant to be used for actionable issues only.
|
|||||||
|
|
||||||
You should not open a new issue for security related questions.
|
You should not open a new issue for security related questions.
|
||||||
|
|
||||||
When in doubt, follow the process for [GNOME security issues](https://security.gnome.org/).
|
When in doubt, send an email to the [security](mailto:security@gnome.org)
|
||||||
|
mailing list.
|
||||||
|
|
||||||
### Bug reports
|
### Bug reports
|
||||||
|
|
||||||
@@ -43,7 +44,6 @@ If you're reporting a bug make sure to list:
|
|||||||
|
|
||||||
0. which version of GTK are you using?
|
0. which version of GTK are you using?
|
||||||
0. which operating system are you using?
|
0. which operating system are you using?
|
||||||
0. what display and graphics driver are you using?
|
|
||||||
0. the necessary steps to reproduce the issue
|
0. the necessary steps to reproduce the issue
|
||||||
0. the expected outcome
|
0. the expected outcome
|
||||||
0. a description of the behavior; screenshots are also welcome
|
0. a description of the behavior; screenshots are also welcome
|
||||||
@@ -100,16 +100,14 @@ development tools appropriate for your operating system, including:
|
|||||||
- Meson
|
- Meson
|
||||||
- Ninja
|
- Ninja
|
||||||
- Gettext (19.7 or newer)
|
- Gettext (19.7 or newer)
|
||||||
- a [C99 compatible compiler][glib-toolchain-reqs]
|
- a [C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
|
||||||
|
|
||||||
Up-to-date instructions about developing GNOME applications and libraries
|
Up-to-date instructions about developing GNOME applications and libraries
|
||||||
can be found on [the GNOME Developer Center](https://developer.gnome.org).
|
can be found on [the GNOME Developer Center](https://developer.gnome.org).
|
||||||
|
|
||||||
The GTK project uses GitLab for code hosting and for tracking issues. More
|
The GTK project uses GitLab for code hosting and for tracking issues. More
|
||||||
information about using GitLab can be found on [the GNOME handbook][handbook].
|
information about using GitLab can be found [on the GNOME
|
||||||
|
wiki](https://wiki.gnome.org/GitLab).
|
||||||
[glib-toolchain-reqs]: https://gitlab.gnome.org/GNOME/glib/-/blob/main/docs/toolchain-requirements.md
|
|
||||||
[handbook]: https://handbook.gnome.org/infrastructure/gitlab.html
|
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
@@ -133,7 +131,7 @@ GTK will attempt to download and build some of these dependencies if it
|
|||||||
cannot find them on your system.
|
cannot find them on your system.
|
||||||
|
|
||||||
Additionally, you may want to look at projects that create a development
|
Additionally, you may want to look at projects that create a development
|
||||||
environment for you, like [jhbuild](https://gitlab.gnome.org/GNOME/jhbuild)
|
environment for you, like [jhbuild](https://wiki.gnome.org/HowDoI/Jhbuild)
|
||||||
and [gvsbuild](https://github.com/wingtk/gvsbuild).
|
and [gvsbuild](https://github.com/wingtk/gvsbuild).
|
||||||
|
|
||||||
### Getting started
|
### Getting started
|
||||||
@@ -146,28 +144,33 @@ $ git clone https://gitlab.gnome.org/yourusername/gtk.git
|
|||||||
$ cd gtk
|
$ cd gtk
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Note**: if you plan to push changes to back to the main repository and
|
||||||
|
have a GNOME account, you can skip the fork, and use the following instead:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ git clone git@gitlab.gnome.org:GNOME/gtk.git
|
||||||
|
$ cd gtk
|
||||||
|
```
|
||||||
|
|
||||||
To compile the Git version of GTK on your system, you will need to
|
To compile the Git version of GTK on your system, you will need to
|
||||||
configure your build using Meson:
|
configure your build using Meson:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ meson setup _builddir .
|
$ meson _builddir .
|
||||||
$ meson compile -C _builddir
|
$ cd _builddir
|
||||||
|
$ ninja
|
||||||
```
|
```
|
||||||
|
|
||||||
Typically, you should work on your own branch:
|
Typically, you should work on your own branch:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ git switch -C your-branch
|
$ git checkout -b your-branch
|
||||||
```
|
```
|
||||||
|
|
||||||
Once you've finished working on the bug fix or feature, push the branch
|
Once you've finished working on the bug fix or feature, push the branch
|
||||||
to the Git repository and open a new merge request, to let the GTK
|
to the Git repository and open a new merge request, to let the GTK
|
||||||
maintainers review your contribution.
|
maintainers review your contribution.
|
||||||
|
|
||||||
**Important**: Do **not** attach a diff or a patch file to a GitLab issue.
|
|
||||||
Patches cannot be reviewed, and do not not go through the CI pipeline. If
|
|
||||||
you wish to submit your changes to GTK, always use a merge request.
|
|
||||||
|
|
||||||
### Code reviews
|
### Code reviews
|
||||||
|
|
||||||
Each contribution is reviewed by the core developers of the GTK project.
|
Each contribution is reviewed by the core developers of the GTK project.
|
||||||
@@ -210,7 +213,7 @@ Closes #1234
|
|||||||
`git commit -a --author "Joe Coder <joe@coder.org>"` and `--signoff`.
|
`git commit -a --author "Joe Coder <joe@coder.org>"` and `--signoff`.
|
||||||
|
|
||||||
- If your commit is addressing an issue, use the
|
- If your commit is addressing an issue, use the
|
||||||
[GitLab syntax](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
|
[GitLab syntax](https://docs.gitlab.com/ce/user/project/issues/automatic_issue_closing.html)
|
||||||
to automatically close the issue when merging the commit with the upstream
|
to automatically close the issue when merging the commit with the upstream
|
||||||
repository:
|
repository:
|
||||||
|
|
||||||
@@ -240,11 +243,13 @@ people committing to GTK to follow a few rules:
|
|||||||
code, you should always ask. If your change is minor and you've been
|
code, you should always ask. If your change is minor and you've been
|
||||||
working on GTK for a while it probably isn't necessary to ask. But when
|
working on GTK for a while it probably isn't necessary to ask. But when
|
||||||
in doubt, ask. Even if your change is correct, somebody may know a
|
in doubt, ask. Even if your change is correct, somebody may know a
|
||||||
better way to do things.
|
better way to do things. If you are making changes to GTK, you should
|
||||||
The `gtk` [room on matrix](https://matrix.to/#/#gtk:gnome.org) is also a
|
be subscribed to the [gtk-devel](https://mail.gnome.org/mailman/listinfo/gtk-devel-list)
|
||||||
good place to find GTK developers to discuss changes, but if you live
|
mailing list; this is a good place to ask about intended changes.
|
||||||
outside of the EU/US time zones, the [gtk tag on the GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
|
The `#gtk` IRC channel on irc.gnome.org is also a good place to find GTK
|
||||||
is the most certain and preferred method.
|
developers to discuss changes, but if you live outside of the EU/US time
|
||||||
|
zones, an email to the gtk-devel mailing list is the most certain and
|
||||||
|
preferred method.
|
||||||
|
|
||||||
0. Ask _first_.
|
0. Ask _first_.
|
||||||
|
|
||||||
@@ -259,4 +264,4 @@ people committing to GTK to follow a few rules:
|
|||||||
|
|
||||||
If you have been contributing to GTK for a while and you don't have commit
|
If you have been contributing to GTK for a while and you don't have commit
|
||||||
access to the repository, you may ask to obtain it following the [GNOME account
|
access to the repository, you may ask to obtain it following the [GNOME account
|
||||||
process](https://handbook.gnome.org/infrastructure/developer-access.html).
|
process](https://wiki.gnome.org/AccountsTeam/NewAccounts).
|
||||||
|
61
README.md
@@ -39,21 +39,18 @@ Nightly documentation can be found at
|
|||||||
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk4/
|
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk4/
|
||||||
|
|
||||||
Nightly flatpaks of our demos can be installed from the
|
Nightly flatpaks of our demos can be installed from the
|
||||||
[GNOME Nightly](https://nightly.gnome.org/) repository:
|
[GNOME Nightly](https://wiki.gnome.org/Apps/Nightly) repository:
|
||||||
|
- `flatpak remote-add --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo`
|
||||||
```sh
|
- `flatpak install gnome-nightly org.gtk.Demo4`
|
||||||
flatpak remote-add --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo
|
- `flatpak install gnome-nightly org.gtk.WidgetFactory4`
|
||||||
flatpak install gnome-nightly org.gtk.Demo4
|
- `flatpak install gnome-nightly org.gtk.IconBrowser4`
|
||||||
flatpak install gnome-nightly org.gtk.WidgetFactory4
|
|
||||||
flatpak install gnome-nightly org.gtk.IconBrowser4
|
|
||||||
```
|
|
||||||
|
|
||||||
Building and installing
|
Building and installing
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
In order to build GTK you will need:
|
In order to build GTK you will need:
|
||||||
|
|
||||||
- [a C11 compatible compiler](https://gitlab.gnome.org/GNOME/glib/-/blob/main/docs/toolchain-requirements.md)
|
- [a C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
|
||||||
- [Python 3](https://www.python.org/)
|
- [Python 3](https://www.python.org/)
|
||||||
- [Meson](http://mesonbuild.com)
|
- [Meson](http://mesonbuild.com)
|
||||||
- [Ninja](https://ninja-build.org)
|
- [Ninja](https://ninja-build.org)
|
||||||
@@ -70,13 +67,6 @@ building for:
|
|||||||
- [Graphene](https://github.com/ebassi/graphene)
|
- [Graphene](https://github.com/ebassi/graphene)
|
||||||
- [Xkb-common](https://github.com/xkbcommon/libxkbcommon)
|
- [Xkb-common](https://github.com/xkbcommon/libxkbcommon)
|
||||||
|
|
||||||
If you are building the Wayland backend, you will also need:
|
|
||||||
|
|
||||||
- Wayland-client
|
|
||||||
- Wayland-protocols
|
|
||||||
- Wayland-cursor
|
|
||||||
- Wayland-EGL
|
|
||||||
|
|
||||||
If you are building the X11 backend, you will also need:
|
If you are building the X11 backend, you will also need:
|
||||||
|
|
||||||
- Xlib, and the following X extensions:
|
- Xlib, and the following X extensions:
|
||||||
@@ -89,24 +79,32 @@ If you are building the X11 backend, you will also need:
|
|||||||
- xdamage
|
- xdamage
|
||||||
- xcomposite
|
- xcomposite
|
||||||
|
|
||||||
|
If you are building the Wayland backend, you will also need:
|
||||||
|
|
||||||
|
- Wayland-client
|
||||||
|
- Wayland-protocols
|
||||||
|
- Wayland-cursor
|
||||||
|
- Wayland-EGL
|
||||||
|
|
||||||
Once you have all the necessary dependencies, you can build GTK by using
|
Once you have all the necessary dependencies, you can build GTK by using
|
||||||
Meson:
|
Meson:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ meson setup _build
|
$ meson _build .
|
||||||
$ meson compile -C_build
|
$ cd _build
|
||||||
|
$ ninja
|
||||||
```
|
```
|
||||||
|
|
||||||
You can run the test suite using:
|
You can run the test suite using:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ meson test -C_build
|
$ meson test
|
||||||
```
|
```
|
||||||
|
|
||||||
And, finally, you can install GTK using:
|
And, finally, you can install GTK using:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ sudo meson install -C_build
|
$ sudo ninja install
|
||||||
```
|
```
|
||||||
|
|
||||||
Complete information about installing GTK and related libraries
|
Complete information about installing GTK and related libraries
|
||||||
@@ -118,17 +116,24 @@ docs/reference/gtk/html/gtk-building.html
|
|||||||
|
|
||||||
Or [online](https://docs.gtk.org/gtk4/building.html)
|
Or [online](https://docs.gtk.org/gtk4/building.html)
|
||||||
|
|
||||||
Building from git
|
Default branch renamed to `main`
|
||||||
-----------------
|
--------------------------------
|
||||||
|
|
||||||
The GTK sources are hosted on [gitlab.gnome.org](http://gitlab.gnome.org). The main
|
The default development branch of GTK has been renamed to `main`.
|
||||||
development branch is called `main`, and stable branches are named after their minor
|
To update your local checkout, use:
|
||||||
version, for example `gtk-4-10`.
|
```sh
|
||||||
|
git checkout master
|
||||||
|
git branch -m master main
|
||||||
|
git fetch
|
||||||
|
git branch --unset-upstream
|
||||||
|
git branch -u origin/main
|
||||||
|
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
|
||||||
|
```
|
||||||
|
|
||||||
How to report bugs
|
How to report bugs
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
Bugs should be reported on the [issues page](https://gitlab.gnome.org/GNOME/gtk/issues/).
|
Bugs should be reported on the [issues page](https://gitlab.gnome.org/GNOME/gtk/issues/new).
|
||||||
|
|
||||||
In the bug report please include:
|
In the bug report please include:
|
||||||
|
|
||||||
@@ -136,13 +141,9 @@ In the bug report please include:
|
|||||||
|
|
||||||
- which version of GTK you are using
|
- which version of GTK you are using
|
||||||
- what operating system and version
|
- what operating system and version
|
||||||
- what windowing system (X11 or Wayland)
|
|
||||||
- what graphics driver / mesa version
|
|
||||||
- for Linux, which distribution
|
- for Linux, which distribution
|
||||||
- if you built GTK, the list of options used to configure the build
|
- if you built GTK, the list of options used to configure the build
|
||||||
|
|
||||||
Most of this information can be found in the GTK inspector.
|
|
||||||
|
|
||||||
And anything else you think is relevant.
|
And anything else you think is relevant.
|
||||||
|
|
||||||
* How to reproduce the bug.
|
* How to reproduce the bug.
|
||||||
|
@@ -185,6 +185,7 @@
|
|||||||
"builddir" : true,
|
"builddir" : true,
|
||||||
"config-opts" : [
|
"config-opts" : [
|
||||||
"--libdir=/app/lib",
|
"--libdir=/app/lib",
|
||||||
|
"-Dvulkan=disabled",
|
||||||
"-Dbuildtype=debugoptimized",
|
"-Dbuildtype=debugoptimized",
|
||||||
"-Dprofile=devel"
|
"-Dprofile=devel"
|
||||||
],
|
],
|
||||||
|
@@ -114,6 +114,7 @@
|
|||||||
"builddir" : true,
|
"builddir" : true,
|
||||||
"config-opts" : [
|
"config-opts" : [
|
||||||
"--libdir=/app/lib",
|
"--libdir=/app/lib",
|
||||||
|
"-Dvulkan=disabled",
|
||||||
"-Dbuildtype=debugoptimized",
|
"-Dbuildtype=debugoptimized",
|
||||||
"-Dprofile=devel"
|
"-Dprofile=devel"
|
||||||
],
|
],
|
||||||
|
@@ -114,6 +114,7 @@
|
|||||||
"builddir" : true,
|
"builddir" : true,
|
||||||
"config-opts" : [
|
"config-opts" : [
|
||||||
"--libdir=/app/lib",
|
"--libdir=/app/lib",
|
||||||
|
"-Dvulkan=disabled",
|
||||||
"-Dbuildtype=debugoptimized",
|
"-Dbuildtype=debugoptimized",
|
||||||
"-Dprofile=devel"
|
"-Dprofile=devel"
|
||||||
],
|
],
|
||||||
@@ -130,6 +131,7 @@
|
|||||||
"env" : {
|
"env" : {
|
||||||
"DBUS_SESSION_BUS_ADDRESS" : "''",
|
"DBUS_SESSION_BUS_ADDRESS" : "''",
|
||||||
"GSK_RENDERER" : "opengl",
|
"GSK_RENDERER" : "opengl",
|
||||||
|
"GDK_DEBUG" : "vulkan-disable",
|
||||||
"G_ENABLE_DEBUG" : "true"
|
"G_ENABLE_DEBUG" : "true"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -114,6 +114,7 @@
|
|||||||
"builddir" : true,
|
"builddir" : true,
|
||||||
"config-opts" : [
|
"config-opts" : [
|
||||||
"--libdir=/app/lib",
|
"--libdir=/app/lib",
|
||||||
|
"-Dvulkan=disabled",
|
||||||
"-Dbuildtype=debugoptimized",
|
"-Dbuildtype=debugoptimized",
|
||||||
"-Dprofile=devel"
|
"-Dprofile=devel"
|
||||||
],
|
],
|
||||||
@@ -130,6 +131,7 @@
|
|||||||
"env" : {
|
"env" : {
|
||||||
"DBUS_SESSION_BUS_ADDRESS" : "''",
|
"DBUS_SESSION_BUS_ADDRESS" : "''",
|
||||||
"GSK_RENDERER" : "opengl",
|
"GSK_RENDERER" : "opengl",
|
||||||
|
"GDK_DEBUG" : "vulkan-disable",
|
||||||
"G_ENABLE_DEBUG" : "true"
|
"G_ENABLE_DEBUG" : "true"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,201 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
#
|
|
||||||
# SPDX-FileCopyrightText: 2022 Collabora Inc.
|
|
||||||
# 2023 Emmanuele Bassi
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
#
|
|
||||||
# Original author: Xavier Claessens <xclaesse@gmail.com>
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import textwrap
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
|
|
||||||
# Disable line length warnings as wrapping the C code templates would be hard
|
|
||||||
# flake8: noqa: E501
|
|
||||||
|
|
||||||
|
|
||||||
def gen_versions_macros(args, current_major_version, current_minor_version, current_micro_version):
|
|
||||||
with args.out_path.open("w", encoding="utf-8") as ofile, args.in_path.open(
|
|
||||||
"r", encoding="utf-8"
|
|
||||||
) as ifile:
|
|
||||||
for line in ifile.readlines():
|
|
||||||
if "@GDK_VERSIONS@" in line:
|
|
||||||
ofile.write(
|
|
||||||
textwrap.dedent(
|
|
||||||
f"""\
|
|
||||||
/**
|
|
||||||
* GDK_MAJOR_VERSION:
|
|
||||||
*
|
|
||||||
* The major version component of the library's version, e.g. "1" for "1.2.3".
|
|
||||||
*/
|
|
||||||
#define GDK_MAJOR_VERSION ({current_major_version})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GDK_MINOR_VERSION:
|
|
||||||
*
|
|
||||||
* The minor version component of the library's version, e.g. "2" for "1.2.3".
|
|
||||||
*/
|
|
||||||
#define GDK_MINOR_VERSION ({current_minor_version})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GDK_MICRO_VERSION:
|
|
||||||
*
|
|
||||||
* The micro version component of the library's version, e.g. "3" for "1.2.3".
|
|
||||||
*/
|
|
||||||
#define GDK_MICRO_VERSION ({current_micro_version})
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
for minor in range(0, current_minor_version + 2, 2):
|
|
||||||
ofile.write(
|
|
||||||
textwrap.dedent(
|
|
||||||
f"""\
|
|
||||||
/**
|
|
||||||
* GDK_VERSION_{current_major_version}_{minor}:
|
|
||||||
*
|
|
||||||
* A macro that evaluates to the {current_major_version}.{minor} version of GTK, in a format
|
|
||||||
* that can be used by the C pre-processor.
|
|
||||||
*
|
|
||||||
* Since: {current_major_version}.{minor}
|
|
||||||
*/
|
|
||||||
#define GDK_VERSION_{current_major_version}_{minor} (G_ENCODE_VERSION ({current_major_version}, {minor}))
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
ofile.write(line)
|
|
||||||
|
|
||||||
|
|
||||||
def gen_visibility_macros(args, current_major_version, current_minor_version, current_micro_version):
|
|
||||||
"""
|
|
||||||
Generates a set of macros for each minor stable version of GTK
|
|
||||||
|
|
||||||
- GDK_DEPRECATED
|
|
||||||
- GDK_DEPRECATED_IN_…
|
|
||||||
- GDK_DEPRECATED_MACRO_IN_…
|
|
||||||
- GDK_DEPRECATED_ENUMERATOR_IN_…
|
|
||||||
- GDK_DEPRECATED_TYPE_IN_…
|
|
||||||
|
|
||||||
- GDK_AVAILABLE_IN_ALL
|
|
||||||
- GDK_AVAILABLE_IN_…
|
|
||||||
- GDK_AVAILABLE_STATIC_INLINE_IN_…
|
|
||||||
- GDK_AVAILABLE_MACRO_IN_…
|
|
||||||
- GDK_AVAILABLE_ENUMERATOR_IN_…
|
|
||||||
- GDK_AVAILABLE_TYPE_IN_…
|
|
||||||
|
|
||||||
- GDK_UNAVAILABLE(maj,min)
|
|
||||||
- GDK_UNAVAILABLE_STATIC_INLINE(maj,min)
|
|
||||||
"""
|
|
||||||
|
|
||||||
ns = args.namespace
|
|
||||||
with args.out_path.open("w", encoding="utf-8") as f:
|
|
||||||
f.write(
|
|
||||||
textwrap.dedent(
|
|
||||||
f"""\
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined({ns}_STATIC_COMPILATION)
|
|
||||||
# define _{ns}_EXPORT __declspec(dllexport)
|
|
||||||
# define _{ns}_IMPORT __declspec(dllimport)
|
|
||||||
#elif __GNUC__ >= 4
|
|
||||||
# define _{ns}_EXPORT __attribute__((visibility("default")))
|
|
||||||
# define _{ns}_IMPORT
|
|
||||||
#else
|
|
||||||
# define _{ns}_EXPORT
|
|
||||||
# define _{ns}_IMPORT
|
|
||||||
#endif
|
|
||||||
#ifdef GTK_COMPILATION
|
|
||||||
# define _{ns}_API _{ns}_EXPORT
|
|
||||||
#else
|
|
||||||
# define _{ns}_API _{ns}_IMPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _{ns}_EXTERN _{ns}_API extern
|
|
||||||
|
|
||||||
#define {ns}_VAR _{ns}_EXTERN
|
|
||||||
#define {ns}_AVAILABLE_IN_ALL _{ns}_EXTERN
|
|
||||||
|
|
||||||
#ifdef GDK_DISABLE_DEPRECATION_WARNINGS
|
|
||||||
#define {ns}_DEPRECATED _{ns}_EXTERN
|
|
||||||
#define {ns}_DEPRECATED_FOR(f) _{ns}_EXTERN
|
|
||||||
#define {ns}_UNAVAILABLE(maj,min) _{ns}_EXTERN
|
|
||||||
#define {ns}_UNAVAILABLE_STATIC_INLINE(maj,min)
|
|
||||||
#else
|
|
||||||
#define {ns}_DEPRECATED G_DEPRECATED _{ns}_EXTERN
|
|
||||||
#define {ns}_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) _{ns}_EXTERN
|
|
||||||
#define {ns}_UNAVAILABLE(maj,min) G_UNAVAILABLE(maj,min) _{ns}_EXTERN
|
|
||||||
#define {ns}_UNAVAILABLE_STATIC_INLINE(maj,min) G_UNAVAILABLE(maj,min)
|
|
||||||
#endif
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
for minor in range(0, current_minor_version + 2, 2):
|
|
||||||
f.write(
|
|
||||||
textwrap.dedent(
|
|
||||||
f"""
|
|
||||||
#if GDK_VERSION_MIN_REQUIRED >= GDK_VERSION_4_{minor}
|
|
||||||
#define {ns}_DEPRECATED_IN_{current_major_version}_{minor} {ns}_DEPRECATED
|
|
||||||
#define {ns}_DEPRECATED_IN_{current_major_version}_{minor}_FOR(f) {ns}_DEPRECATED_FOR (f)
|
|
||||||
#define {ns}_DEPRECATED_MACRO_IN_{current_major_version}_{minor} GDK_DEPRECATED_MACRO
|
|
||||||
#define {ns}_DEPRECATED_MACRO_IN_{current_major_version}_{minor}_FOR(f) GDK_DEPRECATED_MACRO_FOR (f)
|
|
||||||
#define {ns}_DEPRECATED_ENUMERATOR_IN_{current_major_version}_{minor} GDK_DEPRECATED_ENUMERATOR
|
|
||||||
#define {ns}_DEPRECATED_ENUMERATOR_IN_{current_major_version}_{minor}_FOR(f) GDK_DEPRECATED_ENUMERATOR_FOR (f)
|
|
||||||
#define {ns}_DEPRECATED_TYPE_IN_{current_major_version}_{minor} GDK_DEPRECATED_TYPE
|
|
||||||
#define {ns}_DEPRECATED_TYPE_IN_{current_major_version}_{minor}_FOR(f) GDK_DEPRECATED_TYPE_FOR (f)
|
|
||||||
#else
|
|
||||||
#define {ns}_DEPRECATED_IN_{current_major_version}_{minor} _{ns}_EXTERN
|
|
||||||
#define {ns}_DEPRECATED_IN_{current_major_version}_{minor}_FOR(f) _{ns}_EXTERN
|
|
||||||
#define {ns}_DEPRECATED_MACRO_IN_{current_major_version}_{minor}
|
|
||||||
#define {ns}_DEPRECATED_MACRO_IN_{current_major_version}_{minor}_FOR(f)
|
|
||||||
#define {ns}_DEPRECATED_ENUMERATOR_IN_{current_major_version}_{minor}
|
|
||||||
#define {ns}_DEPRECATED_ENUMERATOR_IN_{current_major_version}_{minor}_FOR(f)
|
|
||||||
#define {ns}_DEPRECATED_TYPE_IN_{current_major_version}_{minor}
|
|
||||||
#define {ns}_DEPRECATED_TYPE_IN_{current_major_version}_{minor}_FOR(f)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GDK_VERSION_MAX_ALLOWED < GDK_VERSION_{current_major_version}_{minor}
|
|
||||||
#define {ns}_AVAILABLE_IN_{current_major_version}_{minor} {ns}_UNAVAILABLE ({current_major_version}, {minor})
|
|
||||||
#define {ns}_AVAILABLE_STATIC_INLINE_IN_{current_major_version}_{minor} GDK_UNAVAILABLE_STATIC_INLINE ({current_major_version}, {minor})
|
|
||||||
#define {ns}_AVAILABLE_MACRO_IN_{current_major_version}_{minor} GDK_UNAVAILABLE_MACRO ({current_major_version}, {minor})
|
|
||||||
#define {ns}_AVAILABLE_ENUMERATOR_IN_{current_major_version}_{minor} GDK_UNAVAILABLE_ENUMERATOR ({current_major_version}, {minor})
|
|
||||||
#define {ns}_AVAILABLE_TYPE_IN_{current_major_version}_{minor} GDK_UNAVAILABLE_TYPE ({current_major_version}, {minor})
|
|
||||||
#else
|
|
||||||
#define {ns}_AVAILABLE_IN_{current_major_version}_{minor} _{ns}_EXTERN
|
|
||||||
#define {ns}_AVAILABLE_STATIC_INLINE_IN_{current_major_version}_{minor}
|
|
||||||
#define {ns}_AVAILABLE_MACRO_IN_{current_major_version}_{minor}
|
|
||||||
#define {ns}_AVAILABLE_ENUMERATOR_IN_{current_major_version}_{minor}
|
|
||||||
#define {ns}_AVAILABLE_TYPE_IN_{current_major_version}_{minor}
|
|
||||||
#endif
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument("gtk_version", help="Current GLib version")
|
|
||||||
subparsers = parser.add_subparsers()
|
|
||||||
|
|
||||||
versions_parser = subparsers.add_parser(
|
|
||||||
"versions-macros", help="Generate versions macros"
|
|
||||||
)
|
|
||||||
versions_parser.add_argument("in_path", help="input file", type=Path)
|
|
||||||
versions_parser.add_argument("out_path", help="output file", type=Path)
|
|
||||||
versions_parser.set_defaults(func=gen_versions_macros)
|
|
||||||
|
|
||||||
visibility_parser = subparsers.add_parser(
|
|
||||||
"visibility-macros", help="Generate visibility macros"
|
|
||||||
)
|
|
||||||
visibility_parser.add_argument("namespace", help="Macro namespace")
|
|
||||||
visibility_parser.add_argument("out_path", help="output file", type=Path)
|
|
||||||
visibility_parser.set_defaults(func=gen_visibility_macros)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
version = [int(i) for i in args.gtk_version.split(".")]
|
|
||||||
args.func(args, version[0], version[1], version[2])
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
45
build-aux/meson/post-install.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/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]
|
||||||
|
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_mediamodule_dir = os.path.join(gtk_moduledir, 'media')
|
||||||
|
|
||||||
|
print('Compiling GSettings schemas...')
|
||||||
|
glib_compile_schemas = subprocess.check_output(['pkg-config',
|
||||||
|
'--variable=glib_compile_schemas',
|
||||||
|
'gio-2.0']).strip()
|
||||||
|
if not os.path.exists(glib_compile_schemas):
|
||||||
|
# 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.makedirs(gtk_printmodule_dir, exist_ok=True)
|
||||||
|
gio_querymodules = subprocess.check_output(['pkg-config',
|
||||||
|
'--variable=gio_querymodules',
|
||||||
|
'gio-2.0']).strip()
|
||||||
|
if not os.path.exists(gio_querymodules):
|
||||||
|
# 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 media backends...')
|
||||||
|
os.makedirs(gtk_mediamodule_dir, exist_ok=True)
|
||||||
|
subprocess.call([gio_querymodules, gtk_mediamodule_dir])
|
@@ -1,41 +0,0 @@
|
|||||||
#ifndef _MSC_VER
|
|
||||||
#pragma error "This header is for Microsoft VC or clang-cl only."
|
|
||||||
#endif /* _MSC_VER */
|
|
||||||
|
|
||||||
/* Make MSVC more pedantic, this is a recommended pragma list
|
|
||||||
* from _Win32_Programming_ by Rector and Newcomer.
|
|
||||||
*/
|
|
||||||
#ifndef __clang__
|
|
||||||
#pragma warning(error:4002) /* too many actual parameters for macro */
|
|
||||||
#pragma warning(error:4003) /* not enough actual parameters for macro */
|
|
||||||
#pragma warning(1:4010) /* single-line comment contains line-continuation character */
|
|
||||||
#pragma warning(error:4013) /* 'function' undefined; assuming extern returning int */
|
|
||||||
#pragma warning(1:4016) /* no function return type; using int as default */
|
|
||||||
#pragma warning(error:4020) /* too many actual parameters */
|
|
||||||
#pragma warning(error:4021) /* too few actual parameters */
|
|
||||||
#pragma warning(error:4027) /* function declared without formal parameter list */
|
|
||||||
#pragma warning(error:4029) /* declared formal parameter list different from definition */
|
|
||||||
#pragma warning(error:4033) /* 'function' must return a value */
|
|
||||||
#pragma warning(error:4035) /* 'function' : no return value */
|
|
||||||
#pragma warning(error:4045) /* array bounds overflow */
|
|
||||||
#pragma warning(error:4047) /* different levels of indirection */
|
|
||||||
#pragma warning(error:4049) /* terminating line number emission */
|
|
||||||
#pragma warning(error:4053) /* An expression of type void was used as an operand */
|
|
||||||
#pragma warning(error:4071) /* no function prototype given */
|
|
||||||
#pragma warning(disable:4101) /* unreferenced local variable */
|
|
||||||
#pragma warning(error:4150)
|
|
||||||
|
|
||||||
/* G_NORETURN */
|
|
||||||
#pragma warning(error:4646) /* function declared with __declspec(noreturn) has non-void return type */
|
|
||||||
#pragma warning(error:4715) /* 'function': not all control paths return a value */
|
|
||||||
#pragma warning(error:4098) /* 'void' function returning a value */
|
|
||||||
|
|
||||||
#pragma warning(disable:4244) /* No possible loss of data warnings */
|
|
||||||
#pragma warning(disable:4305) /* No truncation from int to char warnings */
|
|
||||||
|
|
||||||
#pragma warning(error:4819) /* The file contains a character that cannot be represented in the current code page */
|
|
||||||
#endif /* __clang__ */
|
|
||||||
|
|
||||||
/* work around Microsoft's premature attempt to deprecate the C-Library */
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
|
||||||
#define _CRT_NONSTDC_NO_WARNINGS
|
|
115
demos/constraint-editor/constraint-editor-application.c
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2019 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "constraint-editor-application.h"
|
||||||
|
#include "constraint-editor-window.h"
|
||||||
|
|
||||||
|
struct _ConstraintEditorApplication
|
||||||
|
{
|
||||||
|
GtkApplication parent_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(ConstraintEditorApplication, constraint_editor_application, GTK_TYPE_APPLICATION);
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_application_init (ConstraintEditorApplication *app)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
quit_activated (GSimpleAction *action,
|
||||||
|
GVariant *parameter,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
g_application_quit (G_APPLICATION (data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static GActionEntry app_entries[] =
|
||||||
|
{
|
||||||
|
{ "quit", quit_activated, NULL, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_application_startup (GApplication *app)
|
||||||
|
{
|
||||||
|
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
|
||||||
|
const char *open_accels[2] = { "<Ctrl>O", NULL };
|
||||||
|
GtkCssProvider *provider;
|
||||||
|
|
||||||
|
G_APPLICATION_CLASS (constraint_editor_application_parent_class)->startup (app);
|
||||||
|
|
||||||
|
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||||
|
app_entries, G_N_ELEMENTS (app_entries),
|
||||||
|
app);
|
||||||
|
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels);
|
||||||
|
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "win.open", open_accels);
|
||||||
|
|
||||||
|
provider = gtk_css_provider_new ();
|
||||||
|
gtk_css_provider_load_from_resource (provider, "/org/gtk/gtk4/constraint-editor/constraint-editor.css");
|
||||||
|
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||||
|
GTK_STYLE_PROVIDER (provider),
|
||||||
|
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_application_activate (GApplication *app)
|
||||||
|
{
|
||||||
|
ConstraintEditorWindow *win;
|
||||||
|
|
||||||
|
win = constraint_editor_window_new (CONSTRAINT_EDITOR_APPLICATION (app));
|
||||||
|
gtk_window_present (GTK_WINDOW (win));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_application_open (GApplication *app,
|
||||||
|
GFile **files,
|
||||||
|
int n_files,
|
||||||
|
const char *hint)
|
||||||
|
{
|
||||||
|
ConstraintEditorWindow *win;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n_files; i++)
|
||||||
|
{
|
||||||
|
win = constraint_editor_window_new (CONSTRAINT_EDITOR_APPLICATION (app));
|
||||||
|
constraint_editor_window_load (win, files[i]);
|
||||||
|
gtk_window_present (GTK_WINDOW (win));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_application_class_init (ConstraintEditorApplicationClass *class)
|
||||||
|
{
|
||||||
|
GApplicationClass *application_class = G_APPLICATION_CLASS (class);
|
||||||
|
|
||||||
|
application_class->startup = constraint_editor_application_startup;
|
||||||
|
application_class->activate = constraint_editor_application_activate;
|
||||||
|
application_class->open = constraint_editor_application_open;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstraintEditorApplication *
|
||||||
|
constraint_editor_application_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (CONSTRAINT_EDITOR_APPLICATION_TYPE,
|
||||||
|
"application-id", "org.gtk.gtk4.ConstraintEditor",
|
||||||
|
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||||
|
NULL);
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2022 Red Hat, Inc.
|
* Copyright © 2019 Red Hat, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@@ -19,17 +19,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gtk/gtkwidget.h>
|
#include <gtk/gtk.h>
|
||||||
#include <gtk/gtkexpression.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
#define CONSTRAINT_EDITOR_APPLICATION_TYPE (constraint_editor_application_get_type ())
|
||||||
|
|
||||||
#define GTK_TYPE_FILE_CHOOSER_CELL (gtk_file_chooser_cell_get_type ())
|
G_DECLARE_FINAL_TYPE (ConstraintEditorApplication, constraint_editor_application, CONSTRAINT, EDITOR_APPLICATION, GtkApplication)
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
|
||||||
G_DECLARE_FINAL_TYPE (GtkFileChooserCell, gtk_file_chooser_cell, GTK, FILE_CHOOSER_CELL, GtkWidget)
|
|
||||||
|
|
||||||
GtkFileChooserCell * gtk_file_chooser_cell_new (void);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
|
ConstraintEditorApplication *constraint_editor_application_new (void);
|
664
demos/constraint-editor/constraint-editor-window.c
Normal file
@@ -0,0 +1,664 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2019 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "constraint-editor-window.h"
|
||||||
|
#include "constraint-view.h"
|
||||||
|
#include "constraint-editor.h"
|
||||||
|
#include "guide-editor.h"
|
||||||
|
|
||||||
|
struct _ConstraintEditorWindow
|
||||||
|
{
|
||||||
|
GtkApplicationWindow parent_instance;
|
||||||
|
|
||||||
|
GtkWidget *paned;
|
||||||
|
GtkWidget *view;
|
||||||
|
GtkWidget *list;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(ConstraintEditorWindow, constraint_editor_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||||
|
|
||||||
|
static GtkConstraintTarget *
|
||||||
|
find_target (GListModel *model,
|
||||||
|
GtkConstraintTarget *orig)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
const char *model_name;
|
||||||
|
gpointer item;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (orig == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (GTK_IS_LABEL (orig))
|
||||||
|
name = gtk_label_get_label (GTK_LABEL (orig));
|
||||||
|
else if (GTK_IS_CONSTRAINT_GUIDE (orig))
|
||||||
|
name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (orig));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_warning ("Don't know how to handle %s targets", G_OBJECT_TYPE_NAME (orig));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (i = 0; i < g_list_model_get_n_items (model); i++)
|
||||||
|
{
|
||||||
|
item = g_list_model_get_item (model, i);
|
||||||
|
g_object_unref (item);
|
||||||
|
if (GTK_IS_WIDGET (item))
|
||||||
|
model_name = gtk_widget_get_name (GTK_WIDGET (item));
|
||||||
|
else
|
||||||
|
model_name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item));
|
||||||
|
|
||||||
|
if (strcmp (name, model_name) == 0)
|
||||||
|
return GTK_CONSTRAINT_TARGET (item);
|
||||||
|
}
|
||||||
|
g_warning ("Failed to find target '%s'", name);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
constraint_editor_window_load (ConstraintEditorWindow *self,
|
||||||
|
GFile *file)
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
GtkBuilder *builder;
|
||||||
|
GError *error = NULL;
|
||||||
|
GtkWidget *view;
|
||||||
|
GtkLayoutManager *layout;
|
||||||
|
GtkWidget *child;
|
||||||
|
const char *name;
|
||||||
|
gpointer item;
|
||||||
|
int i;
|
||||||
|
GListModel *list;
|
||||||
|
|
||||||
|
path = g_file_get_path (file);
|
||||||
|
|
||||||
|
builder = gtk_builder_new ();
|
||||||
|
if (!gtk_builder_add_from_file (builder, path, &error))
|
||||||
|
{
|
||||||
|
g_print ("Could not load %s: %s", path, error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
g_free (path);
|
||||||
|
g_object_unref (builder);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
view = GTK_WIDGET (gtk_builder_get_object (builder, "view"));
|
||||||
|
if (!GTK_IS_BOX (view))
|
||||||
|
{
|
||||||
|
g_print ("Could not load %s: No GtkBox named 'view'", path);
|
||||||
|
g_free (path);
|
||||||
|
g_object_unref (builder);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
layout = gtk_widget_get_layout_manager (view);
|
||||||
|
if (!GTK_IS_CONSTRAINT_LAYOUT (layout))
|
||||||
|
{
|
||||||
|
g_print ("Could not load %s: Widget 'view' does not use GtkConstraintLayout", path);
|
||||||
|
g_free (path);
|
||||||
|
g_object_unref (builder);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (child = gtk_widget_get_first_child (view);
|
||||||
|
child;
|
||||||
|
child = gtk_widget_get_next_sibling (child))
|
||||||
|
{
|
||||||
|
if (!GTK_IS_LABEL (child))
|
||||||
|
{
|
||||||
|
g_print ("Skipping non-GtkLabel child\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = gtk_label_get_label (GTK_LABEL (child));
|
||||||
|
constraint_view_add_child (CONSTRAINT_VIEW (self->view), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
list = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (layout));
|
||||||
|
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||||
|
{
|
||||||
|
GtkConstraintGuide *guide, *clone;
|
||||||
|
int w, h;
|
||||||
|
|
||||||
|
item = g_list_model_get_item (list, i);
|
||||||
|
guide = GTK_CONSTRAINT_GUIDE (item);
|
||||||
|
|
||||||
|
/* need to clone here, to attach to the right targets */
|
||||||
|
clone = gtk_constraint_guide_new ();
|
||||||
|
gtk_constraint_guide_set_name (clone, gtk_constraint_guide_get_name (guide));
|
||||||
|
gtk_constraint_guide_set_strength (clone, gtk_constraint_guide_get_strength (guide));
|
||||||
|
gtk_constraint_guide_get_min_size (guide, &w, &h);
|
||||||
|
gtk_constraint_guide_set_min_size (clone, w, h);
|
||||||
|
gtk_constraint_guide_get_nat_size (guide, &w, &h);
|
||||||
|
gtk_constraint_guide_set_nat_size (clone, w, h);
|
||||||
|
gtk_constraint_guide_get_max_size (guide, &w, &h);
|
||||||
|
gtk_constraint_guide_set_max_size (clone, w, h);
|
||||||
|
constraint_view_add_guide (CONSTRAINT_VIEW (self->view), clone);
|
||||||
|
g_object_unref (guide);
|
||||||
|
g_object_unref (clone);
|
||||||
|
}
|
||||||
|
g_object_unref (list);
|
||||||
|
|
||||||
|
list = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (layout));
|
||||||
|
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||||
|
{
|
||||||
|
GtkConstraint *constraint;
|
||||||
|
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),
|
||||||
|
gtk_constraint_get_target_attribute (constraint),
|
||||||
|
gtk_constraint_get_relation (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);
|
||||||
|
|
||||||
|
g_object_unref (constraint);
|
||||||
|
g_object_unref (clone);
|
||||||
|
}
|
||||||
|
g_object_unref (list);
|
||||||
|
|
||||||
|
g_free (path);
|
||||||
|
g_object_unref (builder);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
open_response_cb (GtkNativeDialog *dialog,
|
||||||
|
int response,
|
||||||
|
ConstraintEditorWindow *self)
|
||||||
|
{
|
||||||
|
gtk_native_dialog_hide (dialog);
|
||||||
|
|
||||||
|
if (response == GTK_RESPONSE_ACCEPT)
|
||||||
|
{
|
||||||
|
GFile *file;
|
||||||
|
|
||||||
|
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||||
|
constraint_editor_window_load (self, file);
|
||||||
|
g_object_unref (file);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_native_dialog_destroy (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
open_cb (GtkWidget *button,
|
||||||
|
ConstraintEditorWindow *self)
|
||||||
|
{
|
||||||
|
GtkFileChooserNative *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_file_chooser_native_new ("Open file",
|
||||||
|
GTK_WINDOW (self),
|
||||||
|
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||||
|
"_Load",
|
||||||
|
"_Cancel");
|
||||||
|
gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (dialog), TRUE);
|
||||||
|
|
||||||
|
GFile *cwd = g_file_new_for_path (".");
|
||||||
|
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), cwd, NULL);
|
||||||
|
g_object_unref (cwd);
|
||||||
|
|
||||||
|
g_signal_connect (dialog, "response", G_CALLBACK (open_response_cb), self);
|
||||||
|
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
serialize_child (GString *str,
|
||||||
|
int indent,
|
||||||
|
GtkWidget *child)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
name = gtk_widget_get_name (child);
|
||||||
|
g_string_append_printf (str, "%*s<child>\n", indent, "");
|
||||||
|
g_string_append_printf (str, "%*s <object class=\"GtkLabel\" id=\"%s\">\n", indent, "", name);
|
||||||
|
g_string_append_printf (str, "%*s <property name=\"label\">%s</property>\n", indent, "", name);
|
||||||
|
g_string_append_printf (str, "%*s </object>\n", indent, "");
|
||||||
|
g_string_append_printf (str, "%*s</child>\n", indent, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
serialize_model (GListModel *list)
|
||||||
|
{
|
||||||
|
GString *str = g_string_new ("");
|
||||||
|
int i;
|
||||||
|
|
||||||
|
g_string_append (str, "<interface>\n");
|
||||||
|
g_string_append (str, " <object class=\"GtkBox\" id=\"view\">\n");
|
||||||
|
g_string_append (str, " <property name=\"layout-manager\">\n");
|
||||||
|
g_string_append (str, " <object class=\"GtkConstraintLayout\">\n");
|
||||||
|
g_string_append (str, " <constraints>\n");
|
||||||
|
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||||
|
{
|
||||||
|
gpointer item = g_list_model_get_item (list, i);
|
||||||
|
g_object_unref (item);
|
||||||
|
if (GTK_IS_CONSTRAINT (item))
|
||||||
|
constraint_editor_serialize_constraint (str, 10, GTK_CONSTRAINT (item));
|
||||||
|
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||||
|
guide_editor_serialize_guide (str, 10, GTK_CONSTRAINT_GUIDE (item));
|
||||||
|
}
|
||||||
|
g_string_append (str, " </constraints>\n");
|
||||||
|
g_string_append (str, " </object>\n");
|
||||||
|
g_string_append (str, " </property>\n");
|
||||||
|
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||||
|
{
|
||||||
|
gpointer item = g_list_model_get_item (list, i);
|
||||||
|
g_object_unref (item);
|
||||||
|
if (GTK_IS_WIDGET (item))
|
||||||
|
serialize_child (str, 4, GTK_WIDGET (item));
|
||||||
|
}
|
||||||
|
g_string_append (str, " </object>\n");
|
||||||
|
g_string_append (str, "</interface>\n");
|
||||||
|
|
||||||
|
return g_string_free (str, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
save_response_cb (GtkNativeDialog *dialog,
|
||||||
|
int response,
|
||||||
|
ConstraintEditorWindow *self)
|
||||||
|
{
|
||||||
|
gtk_native_dialog_hide (dialog);
|
||||||
|
|
||||||
|
if (response == GTK_RESPONSE_ACCEPT)
|
||||||
|
{
|
||||||
|
GListModel *model;
|
||||||
|
GFile *file;
|
||||||
|
char *text;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
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),
|
||||||
|
NULL, FALSE,
|
||||||
|
G_FILE_CREATE_NONE,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
if (error != NULL)
|
||||||
|
{
|
||||||
|
GtkWidget *message_dialog;
|
||||||
|
|
||||||
|
message_dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self))),
|
||||||
|
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_INFO,
|
||||||
|
GTK_BUTTONS_OK,
|
||||||
|
"Saving failed");
|
||||||
|
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog),
|
||||||
|
"%s", error->message);
|
||||||
|
g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
|
||||||
|
gtk_widget_show (message_dialog);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (text);
|
||||||
|
g_object_unref (file);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_native_dialog_destroy (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
save_cb (GtkWidget *button,
|
||||||
|
ConstraintEditorWindow *self)
|
||||||
|
{
|
||||||
|
GtkFileChooserNative *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_file_chooser_native_new ("Save constraints",
|
||||||
|
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
|
||||||
|
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||||
|
"_Save",
|
||||||
|
"_Cancel");
|
||||||
|
gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (dialog), TRUE);
|
||||||
|
|
||||||
|
GFile *cwd = g_file_new_for_path (".");
|
||||||
|
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), cwd, NULL);
|
||||||
|
g_object_unref (cwd);
|
||||||
|
|
||||||
|
g_signal_connect (dialog, "response", G_CALLBACK (save_response_cb), self);
|
||||||
|
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_window_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
gtk_widget_dispose_template (GTK_WIDGET (object), CONSTRAINT_EDITOR_WINDOW_TYPE);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (constraint_editor_window_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int child_counter;
|
||||||
|
static int guide_counter;
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_child (ConstraintEditorWindow *win)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
child_counter++;
|
||||||
|
name = g_strdup_printf ("Child %d", child_counter);
|
||||||
|
constraint_view_add_child (CONSTRAINT_VIEW (win->view), name);
|
||||||
|
g_free (name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_guide (ConstraintEditorWindow *win)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
GtkConstraintGuide *guide;
|
||||||
|
|
||||||
|
guide_counter++;
|
||||||
|
name = g_strdup_printf ("Guide %d", guide_counter);
|
||||||
|
guide = gtk_constraint_guide_new ();
|
||||||
|
gtk_constraint_guide_set_name (guide, name);
|
||||||
|
g_free (name);
|
||||||
|
|
||||||
|
constraint_view_add_guide (CONSTRAINT_VIEW (win->view), guide);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_done (ConstraintEditor *editor,
|
||||||
|
GtkConstraint *constraint,
|
||||||
|
ConstraintEditorWindow *win)
|
||||||
|
{
|
||||||
|
GtkConstraint *old_constraint;
|
||||||
|
|
||||||
|
g_object_get (editor, "constraint", &old_constraint, NULL);
|
||||||
|
|
||||||
|
if (old_constraint)
|
||||||
|
constraint_view_remove_constraint (CONSTRAINT_VIEW (win->view), old_constraint);
|
||||||
|
|
||||||
|
constraint_view_add_constraint (CONSTRAINT_VIEW (win->view), constraint);
|
||||||
|
|
||||||
|
g_clear_object (&old_constraint);
|
||||||
|
|
||||||
|
gtk_window_destroy (GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
edit_constraint (ConstraintEditorWindow *win,
|
||||||
|
GtkConstraint *constraint)
|
||||||
|
{
|
||||||
|
GtkWidget *window;
|
||||||
|
ConstraintEditor *editor;
|
||||||
|
GListModel *model;
|
||||||
|
|
||||||
|
window = gtk_window_new ();
|
||||||
|
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (win));
|
||||||
|
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||||
|
if (constraint)
|
||||||
|
gtk_window_set_title (GTK_WINDOW (window), "Edit Constraint");
|
||||||
|
else
|
||||||
|
gtk_window_set_title (GTK_WINDOW (window), "Create Constraint");
|
||||||
|
|
||||||
|
model = constraint_view_get_model (CONSTRAINT_VIEW (win->view));
|
||||||
|
|
||||||
|
editor = constraint_editor_new (model, constraint);
|
||||||
|
|
||||||
|
gtk_window_set_child (GTK_WINDOW (window), GTK_WIDGET (editor));
|
||||||
|
|
||||||
|
g_signal_connect (editor, "done", G_CALLBACK (constraint_editor_done), win);
|
||||||
|
|
||||||
|
gtk_widget_show (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_constraint (ConstraintEditorWindow *win)
|
||||||
|
{
|
||||||
|
edit_constraint (win, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
guide_editor_done (GuideEditor *editor,
|
||||||
|
GtkConstraintGuide *guide,
|
||||||
|
ConstraintEditorWindow *win)
|
||||||
|
{
|
||||||
|
gtk_window_destroy (GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
edit_guide (ConstraintEditorWindow *win,
|
||||||
|
GtkConstraintGuide *guide)
|
||||||
|
{
|
||||||
|
GtkWidget *window;
|
||||||
|
GuideEditor *editor;
|
||||||
|
|
||||||
|
window = gtk_window_new ();
|
||||||
|
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||||
|
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (win));
|
||||||
|
gtk_window_set_title (GTK_WINDOW (window), "Edit Guide");
|
||||||
|
|
||||||
|
editor = guide_editor_new (guide);
|
||||||
|
gtk_window_set_child (GTK_WINDOW (window), GTK_WIDGET (editor));
|
||||||
|
|
||||||
|
g_signal_connect (editor, "done", G_CALLBACK (guide_editor_done), win);
|
||||||
|
gtk_widget_show (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
row_activated (GtkListBox *list,
|
||||||
|
GtkListBoxRow *row,
|
||||||
|
ConstraintEditorWindow *win)
|
||||||
|
{
|
||||||
|
GObject *item;
|
||||||
|
|
||||||
|
item = G_OBJECT (g_object_get_data (G_OBJECT (row), "item"));
|
||||||
|
|
||||||
|
if (GTK_IS_CONSTRAINT (item))
|
||||||
|
edit_constraint (win, GTK_CONSTRAINT (item));
|
||||||
|
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||||
|
edit_guide (win, GTK_CONSTRAINT_GUIDE (item));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_window_class_init (ConstraintEditorWindowClass *class)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||||
|
|
||||||
|
object_class->dispose = constraint_editor_window_dispose;
|
||||||
|
|
||||||
|
gtk_widget_class_set_template_from_resource (widget_class,
|
||||||
|
"/org/gtk/gtk4/constraint-editor/constraint-editor-window.ui");
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, paned);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, view);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, list);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, open_cb);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, save_cb);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, add_child);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, add_guide);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, add_constraint);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, row_activated);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
row_edit (GtkButton *button,
|
||||||
|
ConstraintEditorWindow *win)
|
||||||
|
{
|
||||||
|
GtkWidget *row;
|
||||||
|
GObject *item;
|
||||||
|
|
||||||
|
row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
|
||||||
|
item = (GObject *)g_object_get_data (G_OBJECT (row), "item");
|
||||||
|
if (GTK_IS_CONSTRAINT (item))
|
||||||
|
edit_constraint (win, GTK_CONSTRAINT (item));
|
||||||
|
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||||
|
edit_guide (win, GTK_CONSTRAINT_GUIDE (item));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mark_constraints_invalid (ConstraintEditorWindow *win,
|
||||||
|
gpointer removed)
|
||||||
|
{
|
||||||
|
GtkWidget *child;
|
||||||
|
GObject *item;
|
||||||
|
|
||||||
|
for (child = gtk_widget_get_first_child (win->list);
|
||||||
|
child;
|
||||||
|
child = gtk_widget_get_next_sibling (child))
|
||||||
|
{
|
||||||
|
item = (GObject *)g_object_get_data (G_OBJECT (child), "item");
|
||||||
|
if (GTK_IS_CONSTRAINT (item))
|
||||||
|
{
|
||||||
|
GtkConstraint *constraint = GTK_CONSTRAINT (item);
|
||||||
|
|
||||||
|
if (gtk_constraint_get_target (constraint) == (GtkConstraintTarget *)removed ||
|
||||||
|
gtk_constraint_get_source (constraint) == (GtkConstraintTarget *)removed)
|
||||||
|
{
|
||||||
|
GtkWidget *button;
|
||||||
|
button = (GtkWidget *)g_object_get_data (G_OBJECT (child), "edit");
|
||||||
|
gtk_button_set_icon_name (GTK_BUTTON (button), "dialog-warning-symbolic");
|
||||||
|
gtk_widget_set_tooltip_text (button, "Constraint is invalid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
row_delete (GtkButton *button,
|
||||||
|
ConstraintEditorWindow *win)
|
||||||
|
{
|
||||||
|
GtkWidget *row;
|
||||||
|
GObject *item;
|
||||||
|
|
||||||
|
row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
|
||||||
|
item = (GObject *)g_object_get_data (G_OBJECT (row), "item");
|
||||||
|
if (GTK_IS_CONSTRAINT (item))
|
||||||
|
constraint_view_remove_constraint (CONSTRAINT_VIEW (win->view),
|
||||||
|
GTK_CONSTRAINT (item));
|
||||||
|
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||||
|
{
|
||||||
|
mark_constraints_invalid (win, item);
|
||||||
|
constraint_view_remove_guide (CONSTRAINT_VIEW (win->view),
|
||||||
|
GTK_CONSTRAINT_GUIDE (item));
|
||||||
|
}
|
||||||
|
else if (GTK_IS_WIDGET (item))
|
||||||
|
{
|
||||||
|
mark_constraints_invalid (win, item);
|
||||||
|
constraint_view_remove_child (CONSTRAINT_VIEW (win->view),
|
||||||
|
GTK_WIDGET (item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkWidget *
|
||||||
|
create_widget_func (gpointer item,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ConstraintEditorWindow *win = user_data;
|
||||||
|
const char *name;
|
||||||
|
char *freeme = NULL;
|
||||||
|
GtkWidget *row, *box, *label, *button;
|
||||||
|
|
||||||
|
if (GTK_IS_WIDGET (item))
|
||||||
|
name = gtk_widget_get_name (GTK_WIDGET (item));
|
||||||
|
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||||
|
name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item));
|
||||||
|
else if (GTK_IS_CONSTRAINT (item))
|
||||||
|
name = freeme = constraint_editor_constraint_to_string (GTK_CONSTRAINT (item));
|
||||||
|
else
|
||||||
|
name = "";
|
||||||
|
|
||||||
|
row = gtk_list_box_row_new ();
|
||||||
|
g_object_set_data_full (G_OBJECT (row), "item", g_object_ref (item), g_object_unref);
|
||||||
|
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||||
|
label = gtk_label_new (name);
|
||||||
|
if (GTK_IS_WIDGET (item) || GTK_IS_CONSTRAINT_GUIDE (item))
|
||||||
|
g_object_bind_property (item, "name",
|
||||||
|
label, "label",
|
||||||
|
G_BINDING_DEFAULT);
|
||||||
|
gtk_widget_set_margin_start (label, 10);
|
||||||
|
gtk_widget_set_margin_end (label, 10);
|
||||||
|
gtk_widget_set_margin_top (label, 10);
|
||||||
|
gtk_widget_set_margin_bottom (label, 10);
|
||||||
|
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||||
|
gtk_widget_set_hexpand (label, TRUE);
|
||||||
|
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), box);
|
||||||
|
gtk_box_append (GTK_BOX (box), label);
|
||||||
|
|
||||||
|
if (GTK_IS_CONSTRAINT (item) || GTK_IS_CONSTRAINT_GUIDE (item))
|
||||||
|
{
|
||||||
|
button = gtk_button_new_from_icon_name ("document-edit-symbolic");
|
||||||
|
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
|
||||||
|
g_signal_connect (button, "clicked", G_CALLBACK (row_edit), win);
|
||||||
|
g_object_set_data (G_OBJECT (row), "edit", button);
|
||||||
|
gtk_box_append (GTK_BOX (box), button);
|
||||||
|
button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
|
||||||
|
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
|
||||||
|
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
|
||||||
|
gtk_box_append (GTK_BOX (box), button);
|
||||||
|
}
|
||||||
|
else if (GTK_IS_WIDGET (item))
|
||||||
|
{
|
||||||
|
button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
|
||||||
|
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
|
||||||
|
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
|
||||||
|
gtk_box_append (GTK_BOX (box), button);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (freeme);
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_window_init (ConstraintEditorWindow *self)
|
||||||
|
{
|
||||||
|
gtk_widget_init_template (GTK_WIDGET (self));
|
||||||
|
|
||||||
|
gtk_list_box_bind_model (GTK_LIST_BOX (self->list),
|
||||||
|
constraint_view_get_model (CONSTRAINT_VIEW (self->view)),
|
||||||
|
create_widget_func,
|
||||||
|
self,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstraintEditorWindow *
|
||||||
|
constraint_editor_window_new (ConstraintEditorApplication *application)
|
||||||
|
{
|
||||||
|
return g_object_new (CONSTRAINT_EDITOR_WINDOW_TYPE,
|
||||||
|
"application", application,
|
||||||
|
NULL);
|
||||||
|
}
|
34
demos/constraint-editor/constraint-editor-window.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2019 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "constraint-editor-application.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define CONSTRAINT_EDITOR_WINDOW_TYPE (constraint_editor_window_get_type ())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (ConstraintEditorWindow, constraint_editor_window, CONSTRAINT, EDITOR_WINDOW, GtkApplicationWindow)
|
||||||
|
|
||||||
|
ConstraintEditorWindow * constraint_editor_window_new (ConstraintEditorApplication *application);
|
||||||
|
|
||||||
|
gboolean constraint_editor_window_load (ConstraintEditorWindow *self,
|
||||||
|
GFile *file);
|
77
demos/constraint-editor/constraint-editor-window.ui
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<template class="ConstraintEditorWindow" parent="GtkApplicationWindow">
|
||||||
|
<property name="title" translatable="yes">GTK Constraint Editor</property>
|
||||||
|
<property name="default-width">1024</property>
|
||||||
|
<property name="default-height">768</property>
|
||||||
|
<child type="titlebar">
|
||||||
|
<object class="GtkHeaderBar" id="header">
|
||||||
|
<child type="start">
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="icon-name">document-open-symbolic</property>
|
||||||
|
<property name="tooltip-text">Open ui file</property>
|
||||||
|
<signal name="clicked" handler="open_cb"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child type="start">
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="icon-name">document-save-symbolic</property>
|
||||||
|
<property name="tooltip-text">Save to ui file</property>
|
||||||
|
<signal name="clicked" handler="save_cb"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkPaned" id="paned">
|
||||||
|
<property name="orientation">horizontal</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="orientation">horizontal</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="label">Add Child</property>
|
||||||
|
<signal name="clicked" handler="add_child" swapped="yes"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="label">Add Guide</property>
|
||||||
|
<signal name="clicked" handler="add_guide" swapped="yes"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton">
|
||||||
|
<property name="label">Add Constraint</property>
|
||||||
|
<signal name="clicked" handler="add_constraint" swapped="yes"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="hscrollbar-policy">never</property>
|
||||||
|
<property name="vscrollbar-policy">automatic</property>
|
||||||
|
<property name="vexpand">1</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkListBox" id="list">
|
||||||
|
<property name="show-separators">1</property>
|
||||||
|
<property name="selection-mode">none</property>
|
||||||
|
<signal name="row-activated" handler="row_activated"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="ConstraintView" id="view">
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</template>
|
||||||
|
</interface>
|
681
demos/constraint-editor/constraint-editor.c
Normal file
@@ -0,0 +1,681 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2019 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "constraint-editor.h"
|
||||||
|
|
||||||
|
struct _ConstraintEditor
|
||||||
|
{
|
||||||
|
GtkWidget parent_instance;
|
||||||
|
|
||||||
|
GtkWidget *grid;
|
||||||
|
GtkWidget *target;
|
||||||
|
GtkWidget *target_attr;
|
||||||
|
GtkWidget *relation;
|
||||||
|
GtkWidget *source;
|
||||||
|
GtkWidget *source_attr;
|
||||||
|
GtkWidget *multiplier;
|
||||||
|
GtkWidget *constant;
|
||||||
|
GtkWidget *strength;
|
||||||
|
GtkWidget *preview;
|
||||||
|
GtkWidget *button;
|
||||||
|
|
||||||
|
GtkConstraint *constraint;
|
||||||
|
GListModel *model;
|
||||||
|
|
||||||
|
gboolean constructed;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_MODEL = 1,
|
||||||
|
PROP_CONSTRAINT,
|
||||||
|
LAST_PROP
|
||||||
|
};
|
||||||
|
|
||||||
|
static GParamSpec *pspecs[LAST_PROP];
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DONE,
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals[LAST_SIGNAL];
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(ConstraintEditor, constraint_editor, GTK_TYPE_WIDGET);
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
get_target_name (GtkConstraintTarget *target)
|
||||||
|
{
|
||||||
|
if (target == NULL)
|
||||||
|
return "super";
|
||||||
|
else if (GTK_IS_WIDGET (target))
|
||||||
|
return gtk_widget_get_name (GTK_WIDGET (target));
|
||||||
|
else if (GTK_IS_CONSTRAINT_GUIDE (target))
|
||||||
|
return gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (target));
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_target_combo (GListModel *model,
|
||||||
|
GtkWidget *combo,
|
||||||
|
gboolean is_source)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "super", "Super");
|
||||||
|
|
||||||
|
if (model)
|
||||||
|
{
|
||||||
|
for (i = 0; i < g_list_model_get_n_items (model); i++)
|
||||||
|
{
|
||||||
|
GObject *item = g_list_model_get_object (model, i);
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
if (GTK_IS_CONSTRAINT (item))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
name = get_target_name (GTK_CONSTRAINT_TARGET (item));
|
||||||
|
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), name, name);
|
||||||
|
g_object_unref (item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_attribute_combo (GtkWidget *combo,
|
||||||
|
gboolean is_source)
|
||||||
|
{
|
||||||
|
if (is_source)
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "none", "None");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "left", "Left");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "right", "Right");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "top", "Top");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "bottom", "Bottom");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "start", "Start");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "end", "End");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "width", "Width");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "height", "Height");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "center-x", "Center X");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "center-y", "Center Y");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "baseline", "Baseline");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_relation_combo (GtkWidget *combo)
|
||||||
|
{
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "le", "≤");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "eq", "=");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "ge", "≥");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_strength_combo (GtkWidget *combo)
|
||||||
|
{
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "weak", "Weak");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "medium", "Medium");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "strong", "Strong");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "required", "Required");
|
||||||
|
}
|
||||||
|
|
||||||
|
static gpointer
|
||||||
|
get_target (GListModel *model,
|
||||||
|
const char *id)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (id == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (strcmp ("super", id) == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < g_list_model_get_n_items (model); i++)
|
||||||
|
{
|
||||||
|
GObject *item = g_list_model_get_object (model, i);
|
||||||
|
g_object_unref (item);
|
||||||
|
if (GTK_IS_CONSTRAINT (item))
|
||||||
|
continue;
|
||||||
|
else if (GTK_IS_WIDGET (item))
|
||||||
|
{
|
||||||
|
if (strcmp (id, gtk_widget_get_name (GTK_WIDGET (item))) == 0)
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||||
|
{
|
||||||
|
if (strcmp (id, gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item))) == 0)
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkConstraintAttribute
|
||||||
|
get_target_attr (const char *id)
|
||||||
|
{
|
||||||
|
GtkConstraintAttribute attr;
|
||||||
|
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_ATTRIBUTE);
|
||||||
|
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||||
|
attr = value->value;
|
||||||
|
g_type_class_unref (class);
|
||||||
|
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
get_attr_nick (GtkConstraintAttribute attr)
|
||||||
|
{
|
||||||
|
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_ATTRIBUTE);
|
||||||
|
GEnumValue *value = g_enum_get_value (class, attr);
|
||||||
|
const char *nick = value->value_nick;
|
||||||
|
g_type_class_unref (class);
|
||||||
|
|
||||||
|
return nick;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkConstraintRelation
|
||||||
|
get_relation (const char *id)
|
||||||
|
{
|
||||||
|
GtkConstraintRelation relation;
|
||||||
|
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_RELATION);
|
||||||
|
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||||
|
relation = value->value;
|
||||||
|
g_type_class_unref (class);
|
||||||
|
|
||||||
|
return relation;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
get_relation_nick (GtkConstraintRelation relation)
|
||||||
|
{
|
||||||
|
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_RELATION);
|
||||||
|
GEnumValue *value = g_enum_get_value (class, relation);
|
||||||
|
const char *nick = value->value_nick;
|
||||||
|
g_type_class_unref (class);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
GtkConstraintStrength strength;
|
||||||
|
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||||
|
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||||
|
strength = value->value;
|
||||||
|
g_type_class_unref (class);
|
||||||
|
|
||||||
|
return strength;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
get_strength_nick (GtkConstraintStrength strength)
|
||||||
|
{
|
||||||
|
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||||
|
GEnumValue *value = g_enum_get_value (class, strength);
|
||||||
|
const char *nick = value->value_nick;
|
||||||
|
g_type_class_unref (class);
|
||||||
|
|
||||||
|
return nick;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
constraint_editor_serialize_constraint (GString *str,
|
||||||
|
int indent,
|
||||||
|
GtkConstraint *constraint)
|
||||||
|
{
|
||||||
|
const char *target;
|
||||||
|
const char *target_attr;
|
||||||
|
const char *relation;
|
||||||
|
const char *source;
|
||||||
|
const char *source_attr;
|
||||||
|
double multiplier;
|
||||||
|
double constant;
|
||||||
|
const char *strength;
|
||||||
|
|
||||||
|
target = get_target_name (gtk_constraint_get_target (constraint));
|
||||||
|
target_attr = get_attr_nick (gtk_constraint_get_target_attribute (constraint));
|
||||||
|
relation = get_relation_nick (gtk_constraint_get_relation (constraint));
|
||||||
|
source = get_target_name (gtk_constraint_get_source (constraint));
|
||||||
|
source_attr = get_attr_nick (gtk_constraint_get_source_attribute (constraint));
|
||||||
|
multiplier = gtk_constraint_get_multiplier (constraint);
|
||||||
|
constant = gtk_constraint_get_constant (constraint);
|
||||||
|
strength = get_strength_nick (gtk_constraint_get_strength (constraint));
|
||||||
|
|
||||||
|
g_string_append_printf (str, "%*s<constraint target=\"%s\" target-attribute=\"%s\"\n", indent, "", target, target_attr);
|
||||||
|
g_string_append_printf (str, "%*s relation=\"%s\"\n", indent, "", relation);
|
||||||
|
if (strcmp (source_attr, "none") != 0)
|
||||||
|
{
|
||||||
|
g_string_append_printf (str, "%*s source=\"%s\" source-attribute=\"%s\"\n", indent, "", source, source_attr);
|
||||||
|
g_string_append_printf (str, "%*s multiplier=\"%g\"\n", indent, "", multiplier);
|
||||||
|
}
|
||||||
|
g_string_append_printf (str, "%*s constant=\"%g\"\n", indent, "", constant);
|
||||||
|
g_string_append_printf (str, "%*s strength=\"%s\" />\n", indent, "", strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_constraint (GtkButton *button,
|
||||||
|
ConstraintEditor *editor)
|
||||||
|
{
|
||||||
|
const char *id;
|
||||||
|
gpointer target;
|
||||||
|
GtkConstraintAttribute target_attr;
|
||||||
|
gpointer source;
|
||||||
|
GtkConstraintAttribute source_attr;
|
||||||
|
GtkConstraintRelation relation;
|
||||||
|
double multiplier;
|
||||||
|
double constant;
|
||||||
|
int strength;
|
||||||
|
GtkConstraint *constraint;
|
||||||
|
|
||||||
|
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target));
|
||||||
|
target = get_target (editor->model, id);
|
||||||
|
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target_attr));
|
||||||
|
target_attr = get_target_attr (id);
|
||||||
|
|
||||||
|
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
|
||||||
|
source = get_target (editor->model, id);
|
||||||
|
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||||
|
source_attr = get_target_attr (id);
|
||||||
|
|
||||||
|
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->relation));
|
||||||
|
relation = get_relation (id);
|
||||||
|
|
||||||
|
multiplier = g_ascii_strtod (gtk_editable_get_text (GTK_EDITABLE (editor->multiplier)), NULL);
|
||||||
|
|
||||||
|
constant = g_ascii_strtod (gtk_editable_get_text (GTK_EDITABLE (editor->constant)), NULL);
|
||||||
|
|
||||||
|
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->strength));
|
||||||
|
strength = get_strength (id);
|
||||||
|
|
||||||
|
constraint = gtk_constraint_new (target, target_attr,
|
||||||
|
relation,
|
||||||
|
source, source_attr,
|
||||||
|
multiplier,
|
||||||
|
constant,
|
||||||
|
strength);
|
||||||
|
g_signal_emit (editor, signals[DONE], 0, constraint);
|
||||||
|
g_object_unref (constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
source_attr_changed (ConstraintEditor *editor)
|
||||||
|
{
|
||||||
|
const char *id;
|
||||||
|
|
||||||
|
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||||
|
if (strcmp (id, "none") == 0)
|
||||||
|
{
|
||||||
|
gtk_combo_box_set_active (GTK_COMBO_BOX (editor->source), -1);
|
||||||
|
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "");
|
||||||
|
gtk_widget_set_sensitive (editor->source, FALSE);
|
||||||
|
gtk_widget_set_sensitive (editor->multiplier, FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_widget_set_sensitive (editor->source, TRUE);
|
||||||
|
gtk_widget_set_sensitive (editor->multiplier, TRUE);
|
||||||
|
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
constraint_editor_constraint_to_string (GtkConstraint *constraint)
|
||||||
|
{
|
||||||
|
GString *str;
|
||||||
|
const char *name;
|
||||||
|
const char *attr;
|
||||||
|
const char *relation;
|
||||||
|
double c, m;
|
||||||
|
|
||||||
|
str = g_string_new ("");
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
if (name == NULL)
|
||||||
|
name = "[ ]";
|
||||||
|
|
||||||
|
g_string_append_printf (str, "%s.%s %s ", name, attr, relation);
|
||||||
|
|
||||||
|
c = gtk_constraint_get_constant (constraint);
|
||||||
|
|
||||||
|
attr = get_attr_nick (gtk_constraint_get_source_attribute (constraint));
|
||||||
|
if (strcmp (attr, "none") != 0)
|
||||||
|
{
|
||||||
|
name = get_target_name (gtk_constraint_get_source (constraint));
|
||||||
|
m = gtk_constraint_get_multiplier (constraint);
|
||||||
|
|
||||||
|
if (name == NULL)
|
||||||
|
name = "[ ]";
|
||||||
|
|
||||||
|
g_string_append_printf (str, "%s.%s", name, attr);
|
||||||
|
|
||||||
|
if (m != 1.0)
|
||||||
|
g_string_append_printf (str, " × %g", m);
|
||||||
|
|
||||||
|
if (c > 0.0)
|
||||||
|
g_string_append_printf (str, " + %g", c);
|
||||||
|
else if (c < 0.0)
|
||||||
|
g_string_append_printf (str, " - %g", -c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_string_append_printf (str, "%g", c);
|
||||||
|
|
||||||
|
return g_string_free (str, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_preview (ConstraintEditor *editor)
|
||||||
|
{
|
||||||
|
GString *str;
|
||||||
|
const char *name;
|
||||||
|
const char *attr;
|
||||||
|
char *relation;
|
||||||
|
const char *multiplier;
|
||||||
|
const char *constant;
|
||||||
|
double c, m;
|
||||||
|
|
||||||
|
if (!editor->constructed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
str = g_string_new ("");
|
||||||
|
|
||||||
|
name = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target));
|
||||||
|
attr = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target_attr));
|
||||||
|
relation = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (editor->relation));
|
||||||
|
|
||||||
|
if (name == NULL)
|
||||||
|
name = "[ ]";
|
||||||
|
|
||||||
|
g_string_append_printf (str, "%s.%s %s ", name, attr, relation);
|
||||||
|
g_free (relation);
|
||||||
|
|
||||||
|
constant = gtk_editable_get_text (GTK_EDITABLE (editor->constant));
|
||||||
|
c = g_ascii_strtod (constant, NULL);
|
||||||
|
|
||||||
|
attr = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||||
|
if (strcmp (attr, "none") != 0)
|
||||||
|
{
|
||||||
|
name = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
|
||||||
|
multiplier = gtk_editable_get_text (GTK_EDITABLE (editor->multiplier));
|
||||||
|
m = g_ascii_strtod (multiplier, NULL);
|
||||||
|
|
||||||
|
if (name == NULL)
|
||||||
|
name = "[ ]";
|
||||||
|
|
||||||
|
g_string_append_printf (str, "%s.%s", name, attr);
|
||||||
|
|
||||||
|
if (m != 1.0)
|
||||||
|
g_string_append_printf (str, " × %g", m);
|
||||||
|
|
||||||
|
if (c > 0.0)
|
||||||
|
g_string_append_printf (str, " + %g", c);
|
||||||
|
else if (c < 0.0)
|
||||||
|
g_string_append_printf (str, " - %g", -c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_string_append_printf (str, "%g", c);
|
||||||
|
|
||||||
|
gtk_label_set_label (GTK_LABEL (editor->preview), str->str);
|
||||||
|
|
||||||
|
g_string_free (str, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)))
|
||||||
|
gtk_widget_set_sensitive (editor->button, TRUE);
|
||||||
|
else
|
||||||
|
gtk_widget_set_sensitive (editor->button, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_init (ConstraintEditor *editor)
|
||||||
|
{
|
||||||
|
gtk_widget_init_template (GTK_WIDGET (editor));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_constructed (GObject *object)
|
||||||
|
{
|
||||||
|
ConstraintEditor *editor = CONSTRAINT_EDITOR (object);
|
||||||
|
|
||||||
|
constraint_target_combo (editor->model, editor->target, FALSE);
|
||||||
|
constraint_attribute_combo (editor->target_attr, FALSE);
|
||||||
|
constraint_relation_combo (editor->relation);
|
||||||
|
constraint_target_combo (editor->model, editor->source, TRUE);
|
||||||
|
constraint_attribute_combo (editor->source_attr, TRUE);
|
||||||
|
|
||||||
|
constraint_strength_combo (editor->strength);
|
||||||
|
|
||||||
|
if (editor->constraint)
|
||||||
|
{
|
||||||
|
GtkConstraintTarget *target;
|
||||||
|
GtkConstraintAttribute attr;
|
||||||
|
GtkConstraintRelation relation;
|
||||||
|
GtkConstraintStrength strength;
|
||||||
|
const char *nick;
|
||||||
|
char *val;
|
||||||
|
double multiplier;
|
||||||
|
double constant;
|
||||||
|
|
||||||
|
target = gtk_constraint_get_target (editor->constraint);
|
||||||
|
nick = get_target_name (target);
|
||||||
|
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target), nick);
|
||||||
|
|
||||||
|
attr = gtk_constraint_get_target_attribute (editor->constraint);
|
||||||
|
nick = get_attr_nick (attr);
|
||||||
|
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target_attr), nick);
|
||||||
|
|
||||||
|
target = gtk_constraint_get_source (editor->constraint);
|
||||||
|
nick = get_target_name (target);
|
||||||
|
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source), nick);
|
||||||
|
|
||||||
|
attr = gtk_constraint_get_source_attribute (editor->constraint);
|
||||||
|
nick = get_attr_nick (attr);
|
||||||
|
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source_attr), nick);
|
||||||
|
|
||||||
|
relation = gtk_constraint_get_relation (editor->constraint);
|
||||||
|
nick = get_relation_nick (relation);
|
||||||
|
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->relation), nick);
|
||||||
|
|
||||||
|
multiplier = gtk_constraint_get_multiplier (editor->constraint);
|
||||||
|
val = g_strdup_printf ("%g", multiplier);
|
||||||
|
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), val);
|
||||||
|
g_free (val);
|
||||||
|
|
||||||
|
constant = gtk_constraint_get_constant (editor->constraint);
|
||||||
|
val = g_strdup_printf ("%g", constant);
|
||||||
|
gtk_editable_set_text (GTK_EDITABLE (editor->constant), val);
|
||||||
|
g_free (val);
|
||||||
|
|
||||||
|
strength = gtk_constraint_get_strength (editor->constraint);
|
||||||
|
nick = get_strength_nick (strength);
|
||||||
|
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), nick);
|
||||||
|
|
||||||
|
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target_attr), "left");
|
||||||
|
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source_attr), "left");
|
||||||
|
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->relation), "eq");
|
||||||
|
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), "required");
|
||||||
|
|
||||||
|
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "1.0");
|
||||||
|
gtk_editable_set_text (GTK_EDITABLE (editor->constant), "0.0");
|
||||||
|
|
||||||
|
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
|
||||||
|
}
|
||||||
|
|
||||||
|
editor->constructed = TRUE;
|
||||||
|
update_preview (editor);
|
||||||
|
update_button (editor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_set_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ConstraintEditor *self = CONSTRAINT_EDITOR (object);
|
||||||
|
|
||||||
|
switch (property_id)
|
||||||
|
{
|
||||||
|
case PROP_MODEL:
|
||||||
|
self->model = g_value_dup_object (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_CONSTRAINT:
|
||||||
|
self->constraint = g_value_dup_object (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_get_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
ConstraintEditor *self = CONSTRAINT_EDITOR (object);
|
||||||
|
|
||||||
|
switch (property_id)
|
||||||
|
{
|
||||||
|
case PROP_MODEL:
|
||||||
|
g_value_set_object (value, self->model);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PROP_CONSTRAINT:
|
||||||
|
g_value_set_object (value, self->constraint);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
ConstraintEditor *self = (ConstraintEditor *)object;
|
||||||
|
|
||||||
|
g_clear_object (&self->model);
|
||||||
|
g_clear_object (&self->constraint);
|
||||||
|
|
||||||
|
gtk_widget_dispose_template (GTK_WIDGET (object), CONSTRAINT_EDITOR_TYPE);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (constraint_editor_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_editor_class_init (ConstraintEditorClass *class)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||||
|
|
||||||
|
object_class->constructed = constraint_editor_constructed;
|
||||||
|
object_class->dispose = constraint_editor_dispose;
|
||||||
|
object_class->set_property = constraint_editor_set_property;
|
||||||
|
object_class->get_property = constraint_editor_get_property;
|
||||||
|
|
||||||
|
pspecs[PROP_CONSTRAINT] =
|
||||||
|
g_param_spec_object ("constraint", "constraint", "constraint",
|
||||||
|
GTK_TYPE_CONSTRAINT,
|
||||||
|
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
|
||||||
|
|
||||||
|
pspecs[PROP_MODEL] =
|
||||||
|
g_param_spec_object ("model", "model", "model",
|
||||||
|
G_TYPE_LIST_MODEL,
|
||||||
|
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
|
||||||
|
|
||||||
|
g_object_class_install_properties (object_class, LAST_PROP, pspecs);
|
||||||
|
|
||||||
|
signals[DONE] =
|
||||||
|
g_signal_new ("done",
|
||||||
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL, NULL,
|
||||||
|
NULL,
|
||||||
|
G_TYPE_NONE, 1, GTK_TYPE_CONSTRAINT);
|
||||||
|
|
||||||
|
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||||
|
|
||||||
|
gtk_widget_class_set_template_from_resource (widget_class,
|
||||||
|
"/org/gtk/gtk4/constraint-editor/constraint-editor.ui");
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, grid);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, target);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, target_attr);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, relation);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, source);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, source_attr);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, multiplier);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, constant);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, strength);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, preview);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, button);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, update_preview);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, update_button);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, create_constraint);
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, source_attr_changed);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstraintEditor *
|
||||||
|
constraint_editor_new (GListModel *model,
|
||||||
|
GtkConstraint *constraint)
|
||||||
|
{
|
||||||
|
return g_object_new (CONSTRAINT_EDITOR_TYPE,
|
||||||
|
"model", model,
|
||||||
|
"constraint", constraint,
|
||||||
|
NULL);
|
||||||
|
}
|
12
demos/constraint-editor/constraint-editor.css
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
constraintview {
|
||||||
|
background: black;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
constraintview .child {
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
constraintview .guide {
|
||||||
|
background: blue;
|
||||||
|
}
|
9
demos/constraint-editor/constraint-editor.gresource.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<gresources>
|
||||||
|
<gresource prefix="/org/gtk/gtk4/constraint-editor">
|
||||||
|
<file preprocess="xml-stripblanks">constraint-editor-window.ui</file>
|
||||||
|
<file preprocess="xml-stripblanks">constraint-editor.ui</file>
|
||||||
|
<file preprocess="xml-stripblanks">guide-editor.ui</file>
|
||||||
|
<file>constraint-editor.css</file>
|
||||||
|
</gresource>
|
||||||
|
</gresources>
|
34
demos/constraint-editor/constraint-editor.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2019 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#define CONSTRAINT_EDITOR_TYPE (constraint_editor_get_type ())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (ConstraintEditor, constraint_editor, CONSTRAINT, EDITOR, GtkWidget)
|
||||||
|
|
||||||
|
ConstraintEditor * constraint_editor_new (GListModel *model,
|
||||||
|
GtkConstraint *constraint);
|
||||||
|
|
||||||
|
void constraint_editor_serialize_constraint (GString *str,
|
||||||
|
int indent,
|
||||||
|
GtkConstraint *constraint);
|
||||||
|
char *constraint_editor_constraint_to_string (GtkConstraint *constraint);
|
167
demos/constraint-editor/constraint-editor.ui
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<template class="ConstraintEditor" parent="GtkWidget">
|
||||||
|
<child>
|
||||||
|
<object class="GtkGrid" id="grid">
|
||||||
|
<property name="margin-start">20</property>
|
||||||
|
<property name="margin-end">20</property>
|
||||||
|
<property name="margin-top">20</property>
|
||||||
|
<property name="margin-bottom">20</property>
|
||||||
|
<property name="row-spacing">10</property>
|
||||||
|
<property name="column-spacing">10</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Target</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBoxText" id="target">
|
||||||
|
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||||
|
<signal name="changed" handler="update_button" swapped="yes"/>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBoxText" id="target_attr">
|
||||||
|
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||||
|
<layout>
|
||||||
|
<property name="column">2</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Relation</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">2</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBoxText" id="relation">
|
||||||
|
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">2</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Source</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">3</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBoxText" id="source">
|
||||||
|
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||||
|
<signal name="changed" handler="update_button" swapped="yes"/>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">3</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<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>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Multiplier</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">4</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="multiplier">
|
||||||
|
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">4</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Constant</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">5</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="constant">
|
||||||
|
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">5</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Strength</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">6</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBoxText" id="strength">
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">6</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="preview">
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">7</property>
|
||||||
|
<property name="column-span">2</property>
|
||||||
|
</layout>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="scale" value="1.44"/>
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button">
|
||||||
|
<property name="label">Create</property>
|
||||||
|
<signal name="clicked" handler="create_constraint"/>
|
||||||
|
<layout>
|
||||||
|
<property name="column">2</property>
|
||||||
|
<property name="row">8</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</template>
|
||||||
|
</interface>
|
93
demos/constraint-editor/constraint-view-child.c
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2019 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "constraint-view-child.h"
|
||||||
|
|
||||||
|
struct _ConstraintViewChild
|
||||||
|
{
|
||||||
|
GObject parent_instance;
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_NAME = 1,
|
||||||
|
LAST_PROP
|
||||||
|
};
|
||||||
|
|
||||||
|
static GParamSpec props[LAST_PROP];
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ConstraintViewChild, constraint_view_child, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_view_child_init (ConstraintViewChild *child)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_view_child_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
ConstraintViewChild *child = CONSTRAINT_VIEW_CHILD (object);
|
||||||
|
|
||||||
|
g_free (child->name);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (constraint_view_child_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_view_child_set_property (GObject *object,
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_view_child_class_init (ConstraintViewChildClass *class)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
|
||||||
|
object_class->finalize = constraint_view_child_finalize;
|
||||||
|
object_class->get_property = constraint_view_child_get_property;
|
||||||
|
object_class->set_property = constraint_view_child_set_property;
|
||||||
|
|
||||||
|
props[PROP_NAME] =
|
||||||
|
g_param_spec_string ("name", "name", "name",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
|
||||||
|
g_object_class_install_properties (object_class, LAST_PROP, props);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CONSTRAINT_VIEW_CHILD_TYPE (constraint_view_get_type ())
|
||||||
|
|
||||||
|
G_DECLARE_TYPE (ConstraintViewChild, constraint_view_child, CONSTRAINT, VIEW_CHILD, GObject)
|
||||||
|
|
||||||
|
#define CONSTRAINT_VIEW_WIDGET_TYPE (constraint_view_widget_get_type ())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (ConstraintViewWidget, constraint_view_widget, CONSTRAINT, VIEW_WIDGET, ConstraintViewChild)
|
||||||
|
|
||||||
|
ConstraintViewWidget * constraint_view_widget_new (void);
|
||||||
|
|
||||||
|
#define CONSTRAINT_VIEW_GUIDE_TYPE (constraint_view_guide_get_type ())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (ConstraintViewGuide, constraint_view_guide, CONSTRAINT, VIEW_GUIDE, ConstraintViewChild)
|
||||||
|
|
||||||
|
ConstraintViewGuide * constraint_view_guide_new (void);
|
||||||
|
|
||||||
|
#define CONSTRAINT_VIEW_CONSTRAINT_TYPE (constraint_view_constraint_get_type ())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (ConstraintViewConstraint, constraint_view_constraint, CONSTRAINT, VIEW_CONSTRAINT, ConstraintViewChild)
|
||||||
|
|
||||||
|
ConstraintViewGuide * constraint_view_constraint_new (void);
|
44
demos/constraint-editor/constraint-view-child.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2019 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#define CONSTRAINT_VIEW_CHILD_TYPE (constraint_view_get_type ())
|
||||||
|
|
||||||
|
G_DECLARE_TYPE (ConstraintViewChild, constraint_view_child, CONSTRAINT, VIEW_CHILD, GObject)
|
||||||
|
|
||||||
|
#define CONSTRAINT_VIEW_WIDGET_TYPE (constraint_view_widget_get_type ())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (ConstraintViewWidget, constraint_view_widget, CONSTRAINT, VIEW_WIDGET, ConstraintViewChild)
|
||||||
|
|
||||||
|
ConstraintViewWidget * constraint_view_widget_new (void);
|
||||||
|
|
||||||
|
#define CONSTRAINT_VIEW_GUIDE_TYPE (constraint_view_guide_get_type ())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (ConstraintViewGuide, constraint_view_guide, CONSTRAINT, VIEW_GUIDE, ConstraintViewChild)
|
||||||
|
|
||||||
|
ConstraintViewGuide * constraint_view_guide_new (void);
|
||||||
|
|
||||||
|
#define CONSTRAINT_VIEW_CONSTRAINT_TYPE (constraint_view_constraint_get_type ())
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE (ConstraintViewConstraint, constraint_view_constraint, CONSTRAINT, VIEW_CONSTRAINT, ConstraintViewChild)
|
||||||
|
|
||||||
|
ConstraintViewGuide * constraint_view_constraint_new (void);
|
345
demos/constraint-editor/constraint-view.c
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
/* Copyright (C) 2019 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 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include "constraint-view.h"
|
||||||
|
|
||||||
|
struct _ConstraintView
|
||||||
|
{
|
||||||
|
GtkWidget parent;
|
||||||
|
|
||||||
|
GListModel *model;
|
||||||
|
|
||||||
|
GtkWidget *drag_widget;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (ConstraintView, constraint_view, GTK_TYPE_WIDGET);
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_view_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
ConstraintView *view = CONSTRAINT_VIEW (object);
|
||||||
|
GtkWidget *child;
|
||||||
|
|
||||||
|
while ((child = gtk_widget_get_first_child (GTK_WIDGET (view))) != NULL)
|
||||||
|
gtk_widget_unparent (child);
|
||||||
|
|
||||||
|
g_clear_object (&view->model);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (constraint_view_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_view_class_init (ConstraintViewClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||||
|
|
||||||
|
object_class->dispose = constraint_view_dispose;
|
||||||
|
|
||||||
|
gtk_widget_class_set_css_name (widget_class, "constraintview");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_weak_position (ConstraintView *self,
|
||||||
|
GtkWidget *child,
|
||||||
|
double x,
|
||||||
|
double y)
|
||||||
|
{
|
||||||
|
GtkLayoutManager *manager;
|
||||||
|
GtkConstraint *constraint;
|
||||||
|
|
||||||
|
manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||||
|
constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "x-constraint");
|
||||||
|
if (constraint)
|
||||||
|
{
|
||||||
|
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||||
|
constraint);
|
||||||
|
g_object_set_data (G_OBJECT (child), "x-constraint", NULL);
|
||||||
|
}
|
||||||
|
if (x != -100)
|
||||||
|
{
|
||||||
|
constraint = gtk_constraint_new_constant (child,
|
||||||
|
GTK_CONSTRAINT_ATTRIBUTE_CENTER_X,
|
||||||
|
GTK_CONSTRAINT_RELATION_EQ,
|
||||||
|
x,
|
||||||
|
GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||||
|
g_object_set_data (G_OBJECT (constraint), "internal", (char *)"yes");
|
||||||
|
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||||
|
constraint);
|
||||||
|
g_object_set_data (G_OBJECT (child), "x-constraint", constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "y-constraint");
|
||||||
|
if (constraint)
|
||||||
|
{
|
||||||
|
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||||
|
constraint);
|
||||||
|
g_object_set_data (G_OBJECT (child), "y-constraint", NULL);
|
||||||
|
}
|
||||||
|
if (y != -100)
|
||||||
|
{
|
||||||
|
constraint = gtk_constraint_new_constant (child,
|
||||||
|
GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y,
|
||||||
|
GTK_CONSTRAINT_RELATION_EQ,
|
||||||
|
y,
|
||||||
|
GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||||
|
g_object_set_data (G_OBJECT (constraint), "internal", (char *)"yes");
|
||||||
|
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||||
|
constraint);
|
||||||
|
g_object_set_data (G_OBJECT (child), "y-constraint", constraint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drag_begin (GtkGestureDrag *drag,
|
||||||
|
double start_x,
|
||||||
|
double start_y,
|
||||||
|
ConstraintView *self)
|
||||||
|
{
|
||||||
|
GtkWidget *widget;
|
||||||
|
|
||||||
|
widget = gtk_widget_pick (GTK_WIDGET (self), start_x, start_y, GTK_PICK_DEFAULT);
|
||||||
|
|
||||||
|
if (GTK_IS_LABEL (widget))
|
||||||
|
{
|
||||||
|
widget = gtk_widget_get_ancestor (widget, GTK_TYPE_FRAME);
|
||||||
|
if (widget &&
|
||||||
|
gtk_widget_get_parent (widget) == (GtkWidget *)self)
|
||||||
|
{
|
||||||
|
self->drag_widget = widget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drag_update (GtkGestureDrag *drag,
|
||||||
|
double offset_x,
|
||||||
|
double offset_y,
|
||||||
|
ConstraintView *self)
|
||||||
|
{
|
||||||
|
double x, y;
|
||||||
|
|
||||||
|
if (!self->drag_widget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gtk_gesture_drag_get_start_point (drag, &x, &y);
|
||||||
|
update_weak_position (self, self->drag_widget, x + offset_x, y + offset_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drag_end (GtkGestureDrag *drag,
|
||||||
|
double offset_x,
|
||||||
|
double offset_y,
|
||||||
|
ConstraintView *self)
|
||||||
|
{
|
||||||
|
self->drag_widget = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
omit_internal (gpointer item, gpointer user_data)
|
||||||
|
{
|
||||||
|
if (g_object_get_data (G_OBJECT (item), "internal"))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constraint_view_init (ConstraintView *self)
|
||||||
|
{
|
||||||
|
GtkLayoutManager *manager;
|
||||||
|
GtkEventController *controller;
|
||||||
|
GListStore *list;
|
||||||
|
GListModel *all_children;
|
||||||
|
GListModel *all_constraints;
|
||||||
|
GListModel *guides;
|
||||||
|
GListModel *children;
|
||||||
|
GListModel *constraints;
|
||||||
|
GtkFilter *filter;
|
||||||
|
|
||||||
|
manager = gtk_constraint_layout_new ();
|
||||||
|
gtk_widget_set_layout_manager (GTK_WIDGET (self), manager);
|
||||||
|
|
||||||
|
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));
|
||||||
|
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));
|
||||||
|
children = (GListModel *)gtk_filter_list_model_new (all_children, filter);
|
||||||
|
|
||||||
|
list = g_list_store_new (G_TYPE_LIST_MODEL);
|
||||||
|
g_list_store_append (list, children);
|
||||||
|
g_list_store_append (list, guides);
|
||||||
|
g_list_store_append (list, constraints);
|
||||||
|
g_object_unref (children);
|
||||||
|
g_object_unref (guides);
|
||||||
|
g_object_unref (constraints);
|
||||||
|
|
||||||
|
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (list)));
|
||||||
|
|
||||||
|
controller = (GtkEventController *)gtk_gesture_drag_new ();
|
||||||
|
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
|
||||||
|
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
|
||||||
|
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_end), self);
|
||||||
|
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstraintView *
|
||||||
|
constraint_view_new (void)
|
||||||
|
{
|
||||||
|
return g_object_new (CONSTRAINT_VIEW_TYPE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
constraint_view_add_child (ConstraintView *view,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
GtkWidget *frame;
|
||||||
|
GtkWidget *label;
|
||||||
|
|
||||||
|
label = gtk_label_new (name);
|
||||||
|
frame = gtk_frame_new (NULL);
|
||||||
|
gtk_widget_add_css_class (frame, "child");
|
||||||
|
gtk_widget_set_name (frame, name);
|
||||||
|
gtk_frame_set_child (GTK_FRAME (frame), label);
|
||||||
|
gtk_widget_set_parent (frame, GTK_WIDGET (view));
|
||||||
|
|
||||||
|
update_weak_position (view, frame, 100, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
constraint_view_remove_child (ConstraintView *view,
|
||||||
|
GtkWidget *child)
|
||||||
|
{
|
||||||
|
update_weak_position (view, child, -100, -100);
|
||||||
|
gtk_widget_unparent (child);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
constraint_view_add_guide (ConstraintView *view,
|
||||||
|
GtkConstraintGuide *guide)
|
||||||
|
{
|
||||||
|
GtkConstraintLayout *layout;
|
||||||
|
GtkWidget *frame;
|
||||||
|
GtkWidget *label;
|
||||||
|
const char *name;
|
||||||
|
GtkConstraint *constraint;
|
||||||
|
struct {
|
||||||
|
const char *name;
|
||||||
|
GtkConstraintAttribute attr;
|
||||||
|
} names[] = {
|
||||||
|
{ "left-constraint", GTK_CONSTRAINT_ATTRIBUTE_LEFT },
|
||||||
|
{ "top-constraint", GTK_CONSTRAINT_ATTRIBUTE_TOP },
|
||||||
|
{ "width-constraint", GTK_CONSTRAINT_ATTRIBUTE_WIDTH },
|
||||||
|
{ "height-constraint", GTK_CONSTRAINT_ATTRIBUTE_HEIGHT },
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
name = gtk_constraint_guide_get_name (guide);
|
||||||
|
label = gtk_label_new (name);
|
||||||
|
g_object_bind_property (guide, "name",
|
||||||
|
label, "label",
|
||||||
|
G_BINDING_DEFAULT);
|
||||||
|
|
||||||
|
frame = gtk_frame_new (NULL);
|
||||||
|
gtk_widget_add_css_class (frame, "guide");
|
||||||
|
g_object_set_data (G_OBJECT (frame), "internal", (char *)"yes");
|
||||||
|
gtk_frame_set_child (GTK_FRAME (frame), label);
|
||||||
|
gtk_widget_insert_after (frame, GTK_WIDGET (view), NULL);
|
||||||
|
|
||||||
|
g_object_set_data (G_OBJECT (guide), "frame", frame);
|
||||||
|
|
||||||
|
layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
|
||||||
|
gtk_constraint_layout_add_guide (layout, g_object_ref (guide));
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (names); i++)
|
||||||
|
{
|
||||||
|
constraint = gtk_constraint_new (frame,
|
||||||
|
names[i].attr,
|
||||||
|
GTK_CONSTRAINT_RELATION_EQ,
|
||||||
|
guide,
|
||||||
|
names[i].attr,
|
||||||
|
1.0, 0.0,
|
||||||
|
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||||
|
g_object_set_data (G_OBJECT (constraint), "internal", (char *)"yes");
|
||||||
|
gtk_constraint_layout_add_constraint (layout, constraint);
|
||||||
|
g_object_set_data (G_OBJECT (guide), names[i].name, constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
update_weak_position (view, frame, 150, 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
constraint_view_remove_guide (ConstraintView *view,
|
||||||
|
GtkConstraintGuide *guide)
|
||||||
|
{
|
||||||
|
GtkConstraintLayout *layout;
|
||||||
|
GtkWidget *frame;
|
||||||
|
GtkConstraint *constraint;
|
||||||
|
const char *names[] = {
|
||||||
|
"left-constraint",
|
||||||
|
"top-constraint",
|
||||||
|
"width-constraint",
|
||||||
|
"height-constraint"
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (names); i++)
|
||||||
|
{
|
||||||
|
constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), names[i]);
|
||||||
|
gtk_constraint_layout_remove_constraint (layout, constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame = (GtkWidget *)g_object_get_data (G_OBJECT (guide), "frame");
|
||||||
|
update_weak_position (view, frame, -100, -100);
|
||||||
|
gtk_widget_unparent (frame);
|
||||||
|
|
||||||
|
gtk_constraint_layout_remove_guide (layout, guide);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
constraint_view_add_constraint (ConstraintView *view,
|
||||||
|
GtkConstraint *constraint)
|
||||||
|
{
|
||||||
|
GtkLayoutManager *manager;
|
||||||
|
|
||||||
|
manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
|
||||||
|
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||||
|
g_object_ref (constraint));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
constraint_view_remove_constraint (ConstraintView *view,
|
||||||
|
GtkConstraint *constraint)
|
||||||
|
{
|
||||||
|
GtkLayoutManager *manager;
|
||||||
|
|
||||||
|
manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
|
||||||
|
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||||
|
constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
GListModel *
|
||||||
|
constraint_view_get_model (ConstraintView *view)
|
||||||
|
{
|
||||||
|
return view->model;
|
||||||
|
}
|
45
demos/constraint-editor/constraint-view.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2019 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#define CONSTRAINT_VIEW_TYPE (constraint_view_get_type ())
|
||||||
|
|
||||||
|
G_MODULE_EXPORT
|
||||||
|
G_DECLARE_FINAL_TYPE (ConstraintView, constraint_view, CONSTRAINT, VIEW, GtkWidget)
|
||||||
|
|
||||||
|
ConstraintView * constraint_view_new (void);
|
||||||
|
|
||||||
|
void constraint_view_add_child (ConstraintView *view,
|
||||||
|
const char *name);
|
||||||
|
void constraint_view_remove_child (ConstraintView *view,
|
||||||
|
GtkWidget *child);
|
||||||
|
void constraint_view_add_guide (ConstraintView *view,
|
||||||
|
GtkConstraintGuide *guide);
|
||||||
|
void constraint_view_remove_guide (ConstraintView *view,
|
||||||
|
GtkConstraintGuide *guide);
|
||||||
|
void constraint_view_guide_changed (ConstraintView *view,
|
||||||
|
GtkConstraintGuide *guide);
|
||||||
|
void constraint_view_add_constraint (ConstraintView *view,
|
||||||
|
GtkConstraint *constraint);
|
||||||
|
void constraint_view_remove_constraint (ConstraintView *view,
|
||||||
|
GtkConstraint *constraint);
|
||||||
|
GListModel * constraint_view_get_model (ConstraintView *view);
|
356
demos/constraint-editor/guide-editor.c
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2019 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "guide-editor.h"
|
||||||
|
|
||||||
|
struct _GuideEditor
|
||||||
|
{
|
||||||
|
GtkWidget parent_instance;
|
||||||
|
|
||||||
|
GtkWidget *grid;
|
||||||
|
GtkWidget *name;
|
||||||
|
GtkWidget *min_width;
|
||||||
|
GtkWidget *min_height;
|
||||||
|
GtkWidget *nat_width;
|
||||||
|
GtkWidget *nat_height;
|
||||||
|
GtkWidget *max_width;
|
||||||
|
GtkWidget *max_height;
|
||||||
|
GtkWidget *strength;
|
||||||
|
GtkWidget *button;
|
||||||
|
|
||||||
|
GtkConstraintGuide *guide;
|
||||||
|
|
||||||
|
gboolean constructed;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PROP_GUIDE = 1,
|
||||||
|
LAST_PROP
|
||||||
|
};
|
||||||
|
|
||||||
|
static GParamSpec *pspecs[LAST_PROP];
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DONE,
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals[LAST_SIGNAL];
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(GuideEditor, guide_editor, GTK_TYPE_WIDGET);
|
||||||
|
|
||||||
|
static void
|
||||||
|
guide_strength_combo (GtkWidget *combo)
|
||||||
|
{
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "weak", "Weak");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "medium", "Medium");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "strong", "Strong");
|
||||||
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "required", "Required");
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkConstraintStrength
|
||||||
|
get_strength (const char *id)
|
||||||
|
{
|
||||||
|
GtkConstraintStrength strength;
|
||||||
|
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||||
|
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||||
|
strength = value->value;
|
||||||
|
g_type_class_unref (class);
|
||||||
|
|
||||||
|
return strength;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
get_strength_nick (GtkConstraintStrength strength)
|
||||||
|
{
|
||||||
|
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||||
|
GEnumValue *value = g_enum_get_value (class, strength);
|
||||||
|
const char *nick = value->value_nick;
|
||||||
|
g_type_class_unref (class);
|
||||||
|
|
||||||
|
return nick;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
guide_editor_serialize_guide (GString *str,
|
||||||
|
int indent,
|
||||||
|
GtkConstraintGuide *guide)
|
||||||
|
{
|
||||||
|
int min_width, min_height;
|
||||||
|
int nat_width, nat_height;
|
||||||
|
int max_width, max_height;
|
||||||
|
const char *name;
|
||||||
|
const char *strength;
|
||||||
|
|
||||||
|
gtk_constraint_guide_get_min_size (guide, &min_width, &min_height);
|
||||||
|
gtk_constraint_guide_get_nat_size (guide, &nat_width, &nat_height);
|
||||||
|
gtk_constraint_guide_get_max_size (guide, &max_width, &max_height);
|
||||||
|
name = gtk_constraint_guide_get_name (guide);
|
||||||
|
strength = get_strength_nick (gtk_constraint_guide_get_strength (guide));
|
||||||
|
|
||||||
|
g_string_append_printf (str, "%*s<guide min-width=\"%d\" min-height=\"%d\"\n", indent, "", min_width, min_height);
|
||||||
|
g_string_append_printf (str, "%*s nat-width=\"%d\" nat-height=\"%d\"\n", indent, "", nat_width, nat_height);
|
||||||
|
g_string_append_printf (str, "%*s max-width=\"%d\" max-height=\"%d\"\n", indent, "", max_width, max_height);
|
||||||
|
g_string_append_printf (str, "%*s name=\"%s\" strength=\"%s\" />\n", indent, "", name, strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_guide (GtkButton *button,
|
||||||
|
GuideEditor *editor)
|
||||||
|
{
|
||||||
|
const char *id;
|
||||||
|
int strength;
|
||||||
|
const char *name;
|
||||||
|
int w, h;
|
||||||
|
GtkConstraintGuide *guide;
|
||||||
|
|
||||||
|
if (editor->guide)
|
||||||
|
guide = g_object_ref (editor->guide);
|
||||||
|
else
|
||||||
|
guide = gtk_constraint_guide_new ();
|
||||||
|
|
||||||
|
name = gtk_editable_get_text (GTK_EDITABLE (editor->name));
|
||||||
|
gtk_constraint_guide_set_name (guide, name);
|
||||||
|
|
||||||
|
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->min_width));
|
||||||
|
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->min_height));
|
||||||
|
gtk_constraint_guide_set_min_size (guide, w, h);
|
||||||
|
|
||||||
|
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->nat_width));
|
||||||
|
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->nat_height));
|
||||||
|
gtk_constraint_guide_set_nat_size (guide, w, h);
|
||||||
|
|
||||||
|
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->max_width));
|
||||||
|
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->max_height));
|
||||||
|
gtk_constraint_guide_set_max_size (guide, w, h);
|
||||||
|
|
||||||
|
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->strength));
|
||||||
|
strength = get_strength (id);
|
||||||
|
gtk_constraint_guide_set_strength (guide, strength);
|
||||||
|
|
||||||
|
g_signal_emit (editor, signals[DONE], 0, guide);
|
||||||
|
g_object_unref (guide);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
guide_editor_init (GuideEditor *editor)
|
||||||
|
{
|
||||||
|
gtk_widget_init_template (GTK_WIDGET (editor));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int guide_counter;
|
||||||
|
|
||||||
|
static int
|
||||||
|
min_input (GtkSpinButton *spin_button,
|
||||||
|
double *new_val)
|
||||||
|
{
|
||||||
|
if (strcmp (gtk_editable_get_text (GTK_EDITABLE (spin_button)), "") == 0)
|
||||||
|
{
|
||||||
|
*new_val = 0.0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
max_input (GtkSpinButton *spin_button,
|
||||||
|
double *new_val)
|
||||||
|
{
|
||||||
|
if (strcmp (gtk_editable_get_text (GTK_EDITABLE (spin_button)), "") == 0)
|
||||||
|
{
|
||||||
|
*new_val = G_MAXINT;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
guide_editor_constructed (GObject *object)
|
||||||
|
{
|
||||||
|
GuideEditor *editor = GUIDE_EDITOR (object);
|
||||||
|
|
||||||
|
guide_strength_combo (editor->strength);
|
||||||
|
|
||||||
|
g_signal_connect (editor->min_width, "input", G_CALLBACK (min_input), NULL);
|
||||||
|
|
||||||
|
g_signal_connect (editor->min_height, "input", G_CALLBACK (min_input), NULL);
|
||||||
|
|
||||||
|
g_signal_connect (editor->max_width, "input", G_CALLBACK (max_input), NULL);
|
||||||
|
|
||||||
|
g_signal_connect (editor->max_height, "input", G_CALLBACK (max_input), NULL);
|
||||||
|
|
||||||
|
if (editor->guide)
|
||||||
|
{
|
||||||
|
GtkConstraintStrength strength;
|
||||||
|
const char *nick;
|
||||||
|
int w, h;
|
||||||
|
|
||||||
|
nick = gtk_constraint_guide_get_name (editor->guide);
|
||||||
|
if (nick)
|
||||||
|
gtk_editable_set_text (GTK_EDITABLE (editor->name), nick);
|
||||||
|
|
||||||
|
gtk_constraint_guide_get_min_size (editor->guide, &w, &h);
|
||||||
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), w);
|
||||||
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_height), h);
|
||||||
|
|
||||||
|
gtk_constraint_guide_get_nat_size (editor->guide, &w, &h);
|
||||||
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_width), w);
|
||||||
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_height), h);
|
||||||
|
|
||||||
|
gtk_constraint_guide_get_max_size (editor->guide, &w, &h);
|
||||||
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_width), w);
|
||||||
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), h);
|
||||||
|
|
||||||
|
strength = gtk_constraint_guide_get_strength (editor->guide);
|
||||||
|
nick = get_strength_nick (strength);
|
||||||
|
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), nick);
|
||||||
|
|
||||||
|
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
guide_counter++;
|
||||||
|
name = g_strdup_printf ("Guide %d", guide_counter);
|
||||||
|
gtk_editable_set_text (GTK_EDITABLE (editor->name), name);
|
||||||
|
g_free (name);
|
||||||
|
|
||||||
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), 0.0);
|
||||||
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_height), 0.0);
|
||||||
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_width), 0.0);
|
||||||
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_height), 0.0);
|
||||||
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_width), G_MAXINT);
|
||||||
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), G_MAXINT);
|
||||||
|
|
||||||
|
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), "medium");
|
||||||
|
|
||||||
|
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
|
||||||
|
}
|
||||||
|
|
||||||
|
editor->constructed = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
guide_editor_set_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
const GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GuideEditor *self = GUIDE_EDITOR (object);
|
||||||
|
|
||||||
|
switch (property_id)
|
||||||
|
{
|
||||||
|
case PROP_GUIDE:
|
||||||
|
self->guide = g_value_dup_object (value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
guide_editor_get_property (GObject *object,
|
||||||
|
guint property_id,
|
||||||
|
GValue *value,
|
||||||
|
GParamSpec *pspec)
|
||||||
|
{
|
||||||
|
GuideEditor *self = GUIDE_EDITOR (object);
|
||||||
|
|
||||||
|
switch (property_id)
|
||||||
|
{
|
||||||
|
case PROP_GUIDE:
|
||||||
|
g_value_set_object (value, self->guide);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
guide_editor_dispose (GObject *object)
|
||||||
|
{
|
||||||
|
GuideEditor *self = (GuideEditor *)object;
|
||||||
|
|
||||||
|
g_clear_object (&self->guide);
|
||||||
|
|
||||||
|
gtk_widget_dispose_template (GTK_WIDGET (self), GUIDE_EDITOR_TYPE);
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (guide_editor_parent_class)->dispose (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
guide_editor_class_init (GuideEditorClass *class)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||||
|
|
||||||
|
object_class->constructed = guide_editor_constructed;
|
||||||
|
object_class->dispose = guide_editor_dispose;
|
||||||
|
object_class->set_property = guide_editor_set_property;
|
||||||
|
object_class->get_property = guide_editor_get_property;
|
||||||
|
|
||||||
|
pspecs[PROP_GUIDE] =
|
||||||
|
g_param_spec_object ("guide", "guide", "guide",
|
||||||
|
GTK_TYPE_CONSTRAINT_GUIDE,
|
||||||
|
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
|
||||||
|
|
||||||
|
g_object_class_install_properties (object_class, LAST_PROP, pspecs);
|
||||||
|
|
||||||
|
signals[DONE] =
|
||||||
|
g_signal_new ("done",
|
||||||
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL, NULL,
|
||||||
|
NULL,
|
||||||
|
G_TYPE_NONE, 1, GTK_TYPE_CONSTRAINT_GUIDE);
|
||||||
|
|
||||||
|
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||||
|
|
||||||
|
gtk_widget_class_set_template_from_resource (widget_class,
|
||||||
|
"/org/gtk/gtk4/constraint-editor/guide-editor.ui");
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GuideEditor, grid);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GuideEditor, name);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GuideEditor, min_width);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GuideEditor, min_height);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GuideEditor, nat_width);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GuideEditor, nat_height);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GuideEditor, max_width);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GuideEditor, max_height);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GuideEditor, strength);
|
||||||
|
gtk_widget_class_bind_template_child (widget_class, GuideEditor, button);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_callback (widget_class, create_guide);
|
||||||
|
}
|
||||||
|
|
||||||
|
GuideEditor *
|
||||||
|
guide_editor_new (GtkConstraintGuide *guide)
|
||||||
|
{
|
||||||
|
return g_object_new (GUIDE_EDITOR_TYPE,
|
||||||
|
"guide", guide,
|
||||||
|
NULL);
|
||||||
|
}
|
@@ -1,8 +1,5 @@
|
|||||||
/* gtkatspi.h: AT-SPI
|
/*
|
||||||
*
|
* Copyright © 2019 Red Hat, Inc
|
||||||
* Copyright 2024 Igalia S.L.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@@ -15,15 +12,21 @@
|
|||||||
* Lesser General Public License for more details.
|
* Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
* 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/>.
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Authors: Matthias Clasen
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#define __GTKATSPI_H_INSIDE__
|
#define GUIDE_EDITOR_TYPE (guide_editor_get_type ())
|
||||||
|
|
||||||
#include <gtk/a11y/gtkatspisocket.h>
|
G_DECLARE_FINAL_TYPE (GuideEditor, guide_editor, GUIDE, EDITOR, GtkWidget)
|
||||||
|
|
||||||
#undef __GTKATSPI_H_INSIDE__
|
GuideEditor * guide_editor_new (GtkConstraintGuide *guide);
|
||||||
|
|
||||||
|
void guide_editor_serialize_guide (GString *str,
|
||||||
|
int indent,
|
||||||
|
GtkConstraintGuide *guide);
|
191
demos/constraint-editor/guide-editor.ui
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<object class="GtkAdjustment" id="min_width_adj">
|
||||||
|
<property name="lower">0</property>
|
||||||
|
<property name="upper">2147483647</property>
|
||||||
|
<property name="step-increment">1</property>
|
||||||
|
<property name="page-increment">10</property>
|
||||||
|
<property name="page-size">0</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkAdjustment" id="min_height_adj">
|
||||||
|
<property name="lower">0</property>
|
||||||
|
<property name="upper">2147483647</property>
|
||||||
|
<property name="step-increment">1</property>
|
||||||
|
<property name="page-increment">10</property>
|
||||||
|
<property name="page-size">0</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkAdjustment" id="nat_width_adj">
|
||||||
|
<property name="lower">0</property>
|
||||||
|
<property name="upper">2147483647</property>
|
||||||
|
<property name="step-increment">1</property>
|
||||||
|
<property name="page-increment">10</property>
|
||||||
|
<property name="page-size">0</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkAdjustment" id="nat_height_adj">
|
||||||
|
<property name="lower">0</property>
|
||||||
|
<property name="upper">2147483647</property>
|
||||||
|
<property name="step-increment">1</property>
|
||||||
|
<property name="page-increment">10</property>
|
||||||
|
<property name="page-size">0</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkAdjustment" id="max_width_adj">
|
||||||
|
<property name="lower">0</property>
|
||||||
|
<property name="upper">2147483647</property>
|
||||||
|
<property name="step-increment">1</property>
|
||||||
|
<property name="page-increment">10</property>
|
||||||
|
<property name="page-size">0</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkAdjustment" id="max_height_adj">
|
||||||
|
<property name="lower">0</property>
|
||||||
|
<property name="upper">2147483647</property>
|
||||||
|
<property name="step-increment">1</property>
|
||||||
|
<property name="page-increment">10</property>
|
||||||
|
<property name="page-size">0</property>
|
||||||
|
</object>
|
||||||
|
<template class="GuideEditor" parent="GtkWidget">
|
||||||
|
<child>
|
||||||
|
<object class="GtkGrid" id="grid">
|
||||||
|
<property name="margin-start">20</property>
|
||||||
|
<property name="margin-end">20</property>
|
||||||
|
<property name="margin-top">20</property>
|
||||||
|
<property name="margin-bottom">20</property>
|
||||||
|
<property name="row-spacing">10</property>
|
||||||
|
<property name="column-spacing">10</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Name</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">0</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="name">
|
||||||
|
<property name="max-width-chars">20</property>
|
||||||
|
<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="label">Min Size</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSpinButton" id="min_width">
|
||||||
|
<property name="adjustment">min_width_adj</property>
|
||||||
|
<property name="max-width-chars">5</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSpinButton" id="min_height">
|
||||||
|
<property name="adjustment">min_height_adj</property>
|
||||||
|
<property name="max-width-chars">5</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">2</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Nat Size</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">2</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSpinButton" id="nat_width">
|
||||||
|
<property name="adjustment">nat_width_adj</property>
|
||||||
|
<property name="max-width-chars">5</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">2</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSpinButton" id="nat_height">
|
||||||
|
<property name="adjustment">nat_height_adj</property>
|
||||||
|
<property name="max-width-chars">5</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">2</property>
|
||||||
|
<property name="row">2</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Max Size</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">3</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSpinButton" id="max_width">
|
||||||
|
<property name="adjustment">max_width_adj</property>
|
||||||
|
<property name="max-width-chars">5</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">3</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSpinButton" id="max_height">
|
||||||
|
<property name="adjustment">max_height_adj</property>
|
||||||
|
<property name="max-width-chars">5</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">2</property>
|
||||||
|
<property name="row">3</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">Strength</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">4</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkComboBoxText" id="strength">
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">4</property>
|
||||||
|
<property name="column-span">2</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button">
|
||||||
|
<property name="label">Create</property>
|
||||||
|
<signal name="clicked" handler="create_guide"/>
|
||||||
|
<layout>
|
||||||
|
<property name="column">2</property>
|
||||||
|
<property name="row">5</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</template>
|
||||||
|
</interface>
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2023 Red Hat, Inc.
|
* Copyright © 2019 Red Hat, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@@ -17,16 +17,12 @@
|
|||||||
* Authors: Matthias Clasen <mclasen@redhat.com>
|
* Authors: Matthias Clasen <mclasen@redhat.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#include "config.h"
|
||||||
|
|
||||||
#include "inspectoroverlay.h"
|
#include <constraint-editor-application.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GTK_TYPE_A11Y_OVERLAY (gtk_a11y_overlay_get_type ())
|
|
||||||
G_DECLARE_FINAL_TYPE (GtkA11yOverlay, gtk_a11y_overlay, GTK, A11Y_OVERLAY, GtkInspectorOverlay)
|
|
||||||
|
|
||||||
GtkInspectorOverlay * gtk_a11y_overlay_new (void);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
return g_application_run (G_APPLICATION (constraint_editor_application_new ()), argc, argv);
|
||||||
|
}
|
23
demos/constraint-editor/meson.build
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
constraint_editor_sources = [
|
||||||
|
'main.c',
|
||||||
|
'constraint-editor-application.c',
|
||||||
|
'constraint-editor-window.c',
|
||||||
|
'constraint-view.c',
|
||||||
|
'constraint-editor.c',
|
||||||
|
'guide-editor.c',
|
||||||
|
]
|
||||||
|
|
||||||
|
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
|
||||||
|
'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,
|
||||||
|
win_subsystem: 'windows',
|
||||||
|
link_args: extra_demo_ldflags,
|
||||||
|
install: false,
|
||||||
|
)
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -33,12 +33,22 @@ static void create_window (GApplication *app, const char *contents);
|
|||||||
static void
|
static void
|
||||||
show_action_dialog (GSimpleAction *action)
|
show_action_dialog (GSimpleAction *action)
|
||||||
{
|
{
|
||||||
GtkAlertDialog *dialog;
|
const char *name;
|
||||||
|
GtkWidget *dialog;
|
||||||
|
|
||||||
dialog = gtk_alert_dialog_new ("You activated action: \"%s\"",
|
name = g_action_get_name (G_ACTION (action));
|
||||||
g_action_get_name (G_ACTION (action)));
|
|
||||||
gtk_alert_dialog_show (dialog, NULL);
|
dialog = gtk_message_dialog_new (NULL,
|
||||||
g_object_unref (dialog);
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_INFO,
|
||||||
|
GTK_BUTTONS_CLOSE,
|
||||||
|
"You activated action: \"%s\"",
|
||||||
|
name);
|
||||||
|
|
||||||
|
g_signal_connect (dialog, "response",
|
||||||
|
G_CALLBACK (gtk_window_destroy), NULL);
|
||||||
|
|
||||||
|
gtk_widget_show (dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -57,7 +67,7 @@ show_action_infobar (GSimpleAction *action,
|
|||||||
text = g_strdup_printf ("You activated radio action: \"%s\".\n"
|
text = g_strdup_printf ("You activated radio action: \"%s\".\n"
|
||||||
"Current value: %s", name, value);
|
"Current value: %s", name, value);
|
||||||
gtk_label_set_text (GTK_LABEL (window->message), text);
|
gtk_label_set_text (GTK_LABEL (window->message), text);
|
||||||
gtk_widget_set_visible (window->infobar, TRUE);
|
gtk_widget_show (window->infobar);
|
||||||
g_free (text);
|
g_free (text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,38 +90,43 @@ activate_new (GSimpleAction *action,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
open_response_cb (GObject *source,
|
open_response_cb (GtkNativeDialog *dialog,
|
||||||
GAsyncResult *result,
|
int response_id,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
|
GtkFileChooserNative *native = user_data;
|
||||||
GApplication *app = G_APPLICATION (user_data);
|
GApplication *app = g_object_get_data (G_OBJECT (native), "app");
|
||||||
|
GtkWidget *message_dialog;
|
||||||
GFile *file;
|
GFile *file;
|
||||||
|
char *contents;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
file = gtk_file_dialog_open_finish (dialog, result, &error);
|
if (response_id == GTK_RESPONSE_ACCEPT)
|
||||||
if (file)
|
|
||||||
{
|
{
|
||||||
char *contents;
|
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (native));
|
||||||
|
|
||||||
if (g_file_load_contents (file, NULL, &contents, NULL, NULL, &error))
|
if (g_file_load_contents (file, NULL, &contents, NULL, NULL, &error))
|
||||||
{
|
{
|
||||||
create_window (app, contents);
|
create_window (app, contents);
|
||||||
g_free (contents);
|
g_free (contents);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message_dialog = gtk_message_dialog_new (NULL,
|
||||||
|
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_ERROR,
|
||||||
|
GTK_BUTTONS_CLOSE,
|
||||||
|
"Error loading file: \"%s\"",
|
||||||
|
error->message);
|
||||||
|
g_signal_connect (message_dialog, "response",
|
||||||
|
G_CALLBACK (gtk_window_destroy), NULL);
|
||||||
|
gtk_widget_show (message_dialog);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error)
|
gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (native));
|
||||||
{
|
g_object_unref (native);
|
||||||
GtkAlertDialog *alert;
|
|
||||||
|
|
||||||
alert = gtk_alert_dialog_new ("Error loading file: \"%s\"", error->message);
|
|
||||||
gtk_alert_dialog_show (alert, NULL);
|
|
||||||
g_object_unref (alert);
|
|
||||||
g_error_free (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref (app);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -121,11 +136,21 @@ activate_open (GSimpleAction *action,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GApplication *app = user_data;
|
GApplication *app = user_data;
|
||||||
GtkFileDialog *dialog;
|
GtkFileChooserNative *native;
|
||||||
|
|
||||||
dialog = gtk_file_dialog_new ();
|
native = gtk_file_chooser_native_new ("Open File",
|
||||||
gtk_file_dialog_open (dialog, NULL, NULL, open_response_cb, g_object_ref (app));
|
NULL,
|
||||||
g_object_unref (dialog);
|
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||||
|
"_Open",
|
||||||
|
"_Cancel");
|
||||||
|
|
||||||
|
g_object_set_data_full (G_OBJECT (native), "app", g_object_ref (app), g_object_unref);
|
||||||
|
g_signal_connect (native,
|
||||||
|
"response",
|
||||||
|
G_CALLBACK (open_response_cb),
|
||||||
|
native);
|
||||||
|
|
||||||
|
gtk_native_dialog_show (GTK_NATIVE_DIALOG (native));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -214,41 +239,6 @@ activate_quit (GSimpleAction *action,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
delete_messages (gpointer data)
|
|
||||||
{
|
|
||||||
g_list_free_full ((GList *)data, g_free);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pop_message (GtkWidget *status)
|
|
||||||
{
|
|
||||||
GList *messages = (GList *) g_object_steal_data (G_OBJECT (status), "messages");
|
|
||||||
|
|
||||||
if (messages)
|
|
||||||
{
|
|
||||||
char *message = messages->data;
|
|
||||||
messages = g_list_remove (messages, message);
|
|
||||||
|
|
||||||
g_object_set_data_full (G_OBJECT (status), "messages",
|
|
||||||
messages, delete_messages);
|
|
||||||
|
|
||||||
gtk_label_set_label (GTK_LABEL (status), message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
push_message (GtkWidget *status,
|
|
||||||
const char *message)
|
|
||||||
{
|
|
||||||
GList *messages = (GList *) g_object_steal_data (G_OBJECT (status), "messages");
|
|
||||||
|
|
||||||
gtk_label_set_label (GTK_LABEL (status), message);
|
|
||||||
messages = g_list_prepend (messages, g_strdup (message));
|
|
||||||
g_object_set_data_full (G_OBJECT (status), "messages",
|
|
||||||
messages, delete_messages);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_statusbar (GtkTextBuffer *buffer,
|
update_statusbar (GtkTextBuffer *buffer,
|
||||||
DemoApplicationWindow *window)
|
DemoApplicationWindow *window)
|
||||||
@@ -259,7 +249,7 @@ update_statusbar (GtkTextBuffer *buffer,
|
|||||||
GtkTextIter iter;
|
GtkTextIter iter;
|
||||||
|
|
||||||
/* clear any previous message, underflow is allowed */
|
/* clear any previous message, underflow is allowed */
|
||||||
pop_message (window->status);
|
gtk_statusbar_pop (GTK_STATUSBAR (window->status), 0);
|
||||||
|
|
||||||
count = gtk_text_buffer_get_char_count (buffer);
|
count = gtk_text_buffer_get_char_count (buffer);
|
||||||
|
|
||||||
@@ -273,7 +263,7 @@ update_statusbar (GtkTextBuffer *buffer,
|
|||||||
msg = g_strdup_printf ("Cursor at row %d column %d - %d chars in document",
|
msg = g_strdup_printf ("Cursor at row %d column %d - %d chars in document",
|
||||||
row, col, count);
|
row, col, count);
|
||||||
|
|
||||||
push_message (window->status, msg);
|
gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, msg);
|
||||||
|
|
||||||
g_free (msg);
|
g_free (msg);
|
||||||
}
|
}
|
||||||
@@ -330,7 +320,7 @@ static GActionEntry win_entries[] = {
|
|||||||
static void
|
static void
|
||||||
clicked_cb (GtkWidget *widget, DemoApplicationWindow *window)
|
clicked_cb (GtkWidget *widget, DemoApplicationWindow *window)
|
||||||
{
|
{
|
||||||
gtk_widget_set_visible (window->infobar, FALSE);
|
gtk_widget_hide (window->infobar);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -76,13 +76,8 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="status">
|
<object class="GtkStatusbar" id="status">
|
||||||
<property name="hexpand">1</property>
|
<property name="hexpand">1</property>
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="margin-start">2</property>
|
|
||||||
<property name="margin-end">2</property>
|
|
||||||
<property name="margin-top">2</property>
|
|
||||||
<property name="margin-bottom">2</property>
|
|
||||||
<layout>
|
<layout>
|
||||||
<property name="column">0</property>
|
<property name="column">0</property>
|
||||||
<property name="row">3</property>
|
<property name="row">3</property>
|
||||||
|
@@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
||||||
|
|
||||||
static GtkWidget *progress_bar = NULL;
|
static GtkWidget *progress_bar = NULL;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -142,6 +140,7 @@ create_page3 (GtkWidget *assistant)
|
|||||||
|
|
||||||
label = gtk_label_new ("This is a confirmation page, press 'Apply' to apply changes");
|
label = gtk_label_new ("This is a confirmation page, press 'Apply' to apply changes");
|
||||||
|
|
||||||
|
gtk_widget_show (label);
|
||||||
gtk_assistant_append_page (GTK_ASSISTANT (assistant), label);
|
gtk_assistant_append_page (GTK_ASSISTANT (assistant), label);
|
||||||
gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), label, GTK_ASSISTANT_PAGE_CONFIRM);
|
gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), label, GTK_ASSISTANT_PAGE_CONFIRM);
|
||||||
gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), label, TRUE);
|
gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), label, TRUE);
|
||||||
@@ -158,14 +157,11 @@ create_page4 (GtkWidget *assistant)
|
|||||||
gtk_widget_set_margin_start (progress_bar, 40);
|
gtk_widget_set_margin_start (progress_bar, 40);
|
||||||
gtk_widget_set_margin_end (progress_bar, 40);
|
gtk_widget_set_margin_end (progress_bar, 40);
|
||||||
|
|
||||||
|
gtk_widget_show (progress_bar);
|
||||||
gtk_assistant_append_page (GTK_ASSISTANT (assistant), progress_bar);
|
gtk_assistant_append_page (GTK_ASSISTANT (assistant), progress_bar);
|
||||||
gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), progress_bar, GTK_ASSISTANT_PAGE_PROGRESS);
|
gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), progress_bar, GTK_ASSISTANT_PAGE_PROGRESS);
|
||||||
gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), progress_bar, "Applying changes");
|
gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), progress_bar, "Applying changes");
|
||||||
|
|
||||||
gtk_accessible_update_property (GTK_ACCESSIBLE (progress_bar),
|
|
||||||
GTK_ACCESSIBLE_PROPERTY_LABEL, "Applying changes",
|
|
||||||
-1);
|
|
||||||
|
|
||||||
/* This prevents the assistant window from being
|
/* This prevents the assistant window from being
|
||||||
* closed while we're "busy" applying changes.
|
* closed while we're "busy" applying changes.
|
||||||
*/
|
*/
|
||||||
@@ -203,7 +199,7 @@ do_assistant (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (assistant))
|
if (!gtk_widget_get_visible (assistant))
|
||||||
gtk_widget_set_visible (assistant, TRUE);
|
gtk_widget_show (assistant);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (assistant));
|
gtk_window_destroy (GTK_WINDOW (assistant));
|
||||||
|
|
||||||
|
26
demos/gtk-demo/background.glsl
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
uniform float u_time;
|
||||||
|
|
||||||
|
void
|
||||||
|
mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
|
||||||
|
{
|
||||||
|
vec2 pos = (fragCoord.xy * 2.0 - resolution.xy)/ min (resolution.x, resolution.y) ;
|
||||||
|
|
||||||
|
float t0 = sin ((u_time + 0.00)*1.0);
|
||||||
|
float t1 = sin ((u_time + 0.30)*0.4);
|
||||||
|
float t2 = cos ((u_time + 0.23)*0.9);
|
||||||
|
float t3 = cos ((u_time + 0.41)*0.6);
|
||||||
|
float t4 = cos ((u_time + 0.11)*0.3);
|
||||||
|
|
||||||
|
vec2 p0 = vec2 (t1, t0) ;
|
||||||
|
vec2 p1 = vec2 (t2, t3) ;
|
||||||
|
vec2 p2 = vec2 (t4, t3) ;
|
||||||
|
|
||||||
|
float r = 1.0/distance (pos, p0);
|
||||||
|
float g = 1.0/distance (pos, p1);
|
||||||
|
float b = 1.0/distance (pos, p2);
|
||||||
|
float sum = r + g + b;
|
||||||
|
|
||||||
|
float alpha = 1.0 - pow (1.0/(sum), 40.0)*pow (10.0, 40.0*0.7);
|
||||||
|
|
||||||
|
fragColor = vec4 (r*0.5, g*0.5, b*0.5, 1.0) * alpha;
|
||||||
|
}
|
@@ -116,8 +116,7 @@ effective_align (GtkAlign align,
|
|||||||
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_START : GTK_ALIGN_END;
|
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_START : GTK_ALIGN_END;
|
||||||
case GTK_ALIGN_FILL:
|
case GTK_ALIGN_FILL:
|
||||||
case GTK_ALIGN_CENTER:
|
case GTK_ALIGN_CENTER:
|
||||||
case GTK_ALIGN_BASELINE_FILL:
|
case GTK_ALIGN_BASELINE:
|
||||||
case GTK_ALIGN_BASELINE_CENTER:
|
|
||||||
default:
|
default:
|
||||||
return align;
|
return align;
|
||||||
}
|
}
|
||||||
@@ -259,8 +258,7 @@ blur_overlay_get_child_position (BlurOverlay *overlay,
|
|||||||
case GTK_ALIGN_END:
|
case GTK_ALIGN_END:
|
||||||
alloc->x += width - alloc->width;
|
alloc->x += width - alloc->width;
|
||||||
break;
|
break;
|
||||||
case GTK_ALIGN_BASELINE_FILL:
|
case GTK_ALIGN_BASELINE:
|
||||||
case GTK_ALIGN_BASELINE_CENTER:
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
break;
|
break;
|
||||||
@@ -283,8 +281,7 @@ blur_overlay_get_child_position (BlurOverlay *overlay,
|
|||||||
case GTK_ALIGN_END:
|
case GTK_ALIGN_END:
|
||||||
alloc->y += height - alloc->height;
|
alloc->y += height - alloc->height;
|
||||||
break;
|
break;
|
||||||
case GTK_ALIGN_BASELINE_FILL:
|
case GTK_ALIGN_BASELINE:
|
||||||
case GTK_ALIGN_BASELINE_CENTER:
|
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
break;
|
break;
|
||||||
@@ -300,13 +297,12 @@ blur_overlay_snapshot (GtkWidget *widget,
|
|||||||
GtkWidget *main_widget;
|
GtkWidget *main_widget;
|
||||||
GskRenderNode *main_widget_node = NULL;
|
GskRenderNode *main_widget_node = NULL;
|
||||||
GtkWidget *child;
|
GtkWidget *child;
|
||||||
int width, height;
|
GtkAllocation main_alloc;
|
||||||
cairo_region_t *clip = NULL;
|
cairo_region_t *clip = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
main_widget = BLUR_OVERLAY (widget)->main_widget;
|
main_widget = BLUR_OVERLAY (widget)->main_widget;
|
||||||
width = gtk_widget_get_width (widget);
|
gtk_widget_get_allocation (widget, &main_alloc);
|
||||||
height = gtk_widget_get_height (widget);
|
|
||||||
|
|
||||||
for (child = gtk_widget_get_first_child (widget);
|
for (child = gtk_widget_get_first_child (widget);
|
||||||
child != NULL;
|
child != NULL;
|
||||||
@@ -319,7 +315,7 @@ blur_overlay_snapshot (GtkWidget *widget,
|
|||||||
|
|
||||||
if (blur > 0)
|
if (blur > 0)
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t rect;
|
GtkAllocation alloc;
|
||||||
graphene_rect_t bounds;
|
graphene_rect_t bounds;
|
||||||
|
|
||||||
if (main_widget_node == NULL)
|
if (main_widget_node == NULL)
|
||||||
@@ -331,8 +327,8 @@ blur_overlay_snapshot (GtkWidget *widget,
|
|||||||
main_widget_node = gtk_snapshot_free_to_node (child_snapshot);
|
main_widget_node = gtk_snapshot_free_to_node (child_snapshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_compute_bounds (child, gtk_widget_get_parent (child), &bounds))
|
gtk_widget_get_allocation (child, &alloc);
|
||||||
graphene_rect_init (&bounds, 0, 0, 0, 0);
|
graphene_rect_init (&bounds, alloc.x, alloc.y, alloc.width, alloc.height);
|
||||||
gtk_snapshot_push_blur (snapshot, blur);
|
gtk_snapshot_push_blur (snapshot, blur);
|
||||||
gtk_snapshot_push_clip (snapshot, &bounds);
|
gtk_snapshot_push_clip (snapshot, &bounds);
|
||||||
gtk_snapshot_append_node (snapshot, main_widget_node);
|
gtk_snapshot_append_node (snapshot, main_widget_node);
|
||||||
@@ -341,17 +337,13 @@ blur_overlay_snapshot (GtkWidget *widget,
|
|||||||
|
|
||||||
if (clip == NULL)
|
if (clip == NULL)
|
||||||
{
|
{
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
rect.x = rect.y = 0;
|
rect.x = rect.y = 0;
|
||||||
rect.width = width;
|
rect.width = main_alloc.width;
|
||||||
rect.height = height;
|
rect.height = main_alloc.height;
|
||||||
clip = cairo_region_create_rectangle (&rect);
|
clip = cairo_region_create_rectangle (&rect);
|
||||||
}
|
}
|
||||||
|
cairo_region_subtract_rectangle (clip, (cairo_rectangle_int_t *)&alloc);
|
||||||
rect.x = floor (bounds.origin.x);
|
|
||||||
rect.y = floor (bounds.origin.y);
|
|
||||||
rect.width = ceil (bounds.origin.x + bounds.size.width - rect.x);
|
|
||||||
rect.height = ceil (bounds.origin.y + bounds.size.height - rect.y);
|
|
||||||
cairo_region_subtract_rectangle (clip, &rect);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,7 +18,8 @@
|
|||||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#ifndef __BLUR_OVERLAY_H__
|
||||||
|
#define __BLUR_OVERLAY_H__
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
@@ -50,12 +51,18 @@ struct _BlurOverlayClass
|
|||||||
GtkAllocation *allocation);
|
GtkAllocation *allocation);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
GType blur_overlay_get_type (void) G_GNUC_CONST;
|
GType blur_overlay_get_type (void) G_GNUC_CONST;
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
GtkWidget *blur_overlay_new (void);
|
GtkWidget *blur_overlay_new (void);
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
void blur_overlay_add_overlay (BlurOverlay *overlay,
|
void blur_overlay_add_overlay (BlurOverlay *overlay,
|
||||||
GtkWidget *widget,
|
GtkWidget *widget,
|
||||||
double blur);
|
double blur);
|
||||||
|
GDK_AVAILABLE_IN_ALL
|
||||||
void blur_overlay_set_child (BlurOverlay *overlay,
|
void blur_overlay_set_child (BlurOverlay *overlay,
|
||||||
GtkWidget *widget);
|
GtkWidget *widget);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __BLUR_OVERLAY_H__ */
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/* Builder
|
/* Builder
|
||||||
* #Keywords: GMenu, GtkPopoverMenuBar, GtkBuilder, GtkShortcutController, toolbar
|
* #Keywords: GMenu, GtkPopoverMenuBar, GtkBuilder, GtkStatusBar, GtkShortcutController, toolbar
|
||||||
*
|
*
|
||||||
* Demonstrates a traditional interface, loaded from a XML description,
|
* Demonstrates a traditional interface, loaded from a XML description,
|
||||||
* and shows how to connect actions to the menu items and toolbar buttons.
|
* and shows how to connect actions to the menu items and toolbar buttons.
|
||||||
@@ -37,30 +37,22 @@ remove_timeout (gpointer data)
|
|||||||
g_source_remove (id);
|
g_source_remove (id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static gboolean
|
||||||
pop_message (gpointer data)
|
pop_status (gpointer data)
|
||||||
{
|
{
|
||||||
GtkWidget *status = data;
|
gtk_statusbar_pop (GTK_STATUSBAR (data), 0);
|
||||||
|
g_object_set_data (G_OBJECT (data), "timeout", NULL);
|
||||||
gtk_label_set_label (GTK_LABEL (status), "");
|
|
||||||
g_object_set_data (G_OBJECT (status), "timeout", GUINT_TO_POINTER (0));
|
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
status_message (GtkWidget *status,
|
status_message (GtkStatusbar *status,
|
||||||
const char *text)
|
const char *text)
|
||||||
{
|
{
|
||||||
guint id;
|
guint id;
|
||||||
|
|
||||||
id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (status), "timeout"));
|
gtk_statusbar_push (GTK_STATUSBAR (status), 0, text);
|
||||||
if (id)
|
id = g_timeout_add (5000, pop_status, status);
|
||||||
g_source_remove (id);
|
|
||||||
|
|
||||||
gtk_label_set_text (GTK_LABEL (status), text);
|
|
||||||
|
|
||||||
id = g_timeout_add (5000, pop_message, status);
|
|
||||||
|
|
||||||
g_object_set_data_full (G_OBJECT (status), "timeout", GUINT_TO_POINTER (id), remove_timeout);
|
g_object_set_data_full (G_OBJECT (status), "timeout", GUINT_TO_POINTER (id), remove_timeout);
|
||||||
}
|
}
|
||||||
@@ -73,7 +65,7 @@ help_activate (GSimpleAction *action,
|
|||||||
GtkWidget *status;
|
GtkWidget *status;
|
||||||
|
|
||||||
status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status"));
|
status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status"));
|
||||||
status_message (status, "Help not available");
|
status_message (GTK_STATUSBAR (status), "Help not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -86,7 +78,7 @@ not_implemented (GSimpleAction *action,
|
|||||||
|
|
||||||
text = g_strdup_printf ("Action “%s” not implemented", g_action_get_name (G_ACTION (action)));
|
text = g_strdup_printf ("Action “%s” not implemented", g_action_get_name (G_ACTION (action)));
|
||||||
status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status"));
|
status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status"));
|
||||||
status_message (status, text);
|
status_message (GTK_STATUSBAR (status), text);
|
||||||
g_free (text);
|
g_free (text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +168,7 @@ do_builder (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -1,5 +1,4 @@
|
|||||||
/* Clipboard
|
/* Clipboard
|
||||||
* #Keywords: drag-and-drop, dnd
|
|
||||||
*
|
*
|
||||||
* GdkClipboard is used for clipboard handling. This demo shows how to
|
* GdkClipboard is used for clipboard handling. This demo shows how to
|
||||||
* copy and paste text, images, colors or files to and from the clipboard.
|
* copy and paste text, images, colors or files to and from the clipboard.
|
||||||
@@ -51,10 +50,10 @@ copy_button_clicked (GtkStack *source_stack,
|
|||||||
}
|
}
|
||||||
else if (strcmp (visible_child_name, "Color") == 0)
|
else if (strcmp (visible_child_name, "Color") == 0)
|
||||||
{
|
{
|
||||||
const GdkRGBA *color;
|
GdkRGBA color;
|
||||||
|
|
||||||
color = gtk_color_dialog_button_get_rgba (GTK_COLOR_DIALOG_BUTTON (visible_child));
|
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (visible_child), &color);
|
||||||
gdk_clipboard_set (clipboard, GDK_TYPE_RGBA, color);
|
gdk_clipboard_set (clipboard, GDK_TYPE_RGBA, &color);
|
||||||
}
|
}
|
||||||
else if (strcmp (visible_child_name, "File") == 0)
|
else if (strcmp (visible_child_name, "File") == 0)
|
||||||
{
|
{
|
||||||
@@ -216,71 +215,37 @@ file_button_set_file (GtkButton *button,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
file_chooser_response (GObject *source,
|
file_chooser_response (GtkNativeDialog *dialog,
|
||||||
GAsyncResult *result,
|
int response,
|
||||||
gpointer user_data)
|
GtkButton *button)
|
||||||
{
|
{
|
||||||
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
|
gtk_native_dialog_hide (dialog);
|
||||||
GtkButton *button = GTK_BUTTON (user_data);
|
|
||||||
GFile *file;
|
|
||||||
|
|
||||||
file = gtk_file_dialog_open_finish (dialog, result, NULL);
|
if (response == GTK_RESPONSE_ACCEPT)
|
||||||
if (file)
|
|
||||||
{
|
{
|
||||||
|
GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||||
file_button_set_file (button, file);
|
file_button_set_file (button, file);
|
||||||
g_object_unref (file);
|
g_object_unref (file);
|
||||||
|
|
||||||
update_copy_button_sensitivity (gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_STACK));
|
update_copy_button_sensitivity (gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_STACK));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gtk_native_dialog_destroy (dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
open_file_cb (GtkWidget *button)
|
open_file_cb (GtkWidget *button)
|
||||||
{
|
{
|
||||||
GtkFileDialog *dialog;
|
GtkFileChooserNative *chooser;
|
||||||
|
|
||||||
dialog = gtk_file_dialog_new ();
|
chooser = gtk_file_chooser_native_new ("Choose a file",
|
||||||
|
GTK_WINDOW (gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW)),
|
||||||
|
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||||
|
"_Open",
|
||||||
|
"_Cancel");
|
||||||
|
|
||||||
gtk_file_dialog_open (dialog,
|
g_signal_connect (chooser, "response", G_CALLBACK (file_chooser_response), button);
|
||||||
GTK_WINDOW (gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW)),
|
gtk_native_dialog_show (GTK_NATIVE_DIALOG (chooser));
|
||||||
NULL,
|
|
||||||
file_chooser_response, button);
|
|
||||||
|
|
||||||
g_object_unref (dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
folder_chooser_response (GObject *source,
|
|
||||||
GAsyncResult *result,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
|
|
||||||
GtkButton *button = GTK_BUTTON (user_data);
|
|
||||||
GFile *file;
|
|
||||||
|
|
||||||
file = gtk_file_dialog_select_folder_finish (dialog, result, NULL);
|
|
||||||
if (file)
|
|
||||||
{
|
|
||||||
file_button_set_file (button, file);
|
|
||||||
g_object_unref (file);
|
|
||||||
|
|
||||||
update_copy_button_sensitivity (gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_STACK));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
open_folder_cb (GtkWidget *button)
|
|
||||||
{
|
|
||||||
GtkFileDialog *dialog;
|
|
||||||
|
|
||||||
dialog = gtk_file_dialog_new ();
|
|
||||||
|
|
||||||
gtk_file_dialog_select_folder (dialog,
|
|
||||||
GTK_WINDOW (gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW)),
|
|
||||||
NULL,
|
|
||||||
folder_chooser_response, button);
|
|
||||||
|
|
||||||
g_object_unref (dialog);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -381,7 +346,6 @@ do_clipboard (GtkWidget *do_widget)
|
|||||||
gtk_builder_cscope_add_callback (scope, source_changed_cb);
|
gtk_builder_cscope_add_callback (scope, source_changed_cb);
|
||||||
gtk_builder_cscope_add_callback (scope, text_changed_cb);
|
gtk_builder_cscope_add_callback (scope, text_changed_cb);
|
||||||
gtk_builder_cscope_add_callback (scope, open_file_cb);
|
gtk_builder_cscope_add_callback (scope, open_file_cb);
|
||||||
gtk_builder_cscope_add_callback (scope, open_folder_cb);
|
|
||||||
gtk_builder_cscope_add_callback (scope, on_drop);
|
gtk_builder_cscope_add_callback (scope, on_drop);
|
||||||
gtk_builder_cscope_add_callback (scope, drag_prepare);
|
gtk_builder_cscope_add_callback (scope, drag_prepare);
|
||||||
builder = gtk_builder_new ();
|
builder = gtk_builder_new ();
|
||||||
@@ -405,7 +369,7 @@ do_clipboard (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -4,9 +4,6 @@
|
|||||||
<object class="GtkWindow" id="window">
|
<object class="GtkWindow" id="window">
|
||||||
<property name="resizable">1</property>
|
<property name="resizable">1</property>
|
||||||
<property name="title">Clipboard</property>
|
<property name="title">Clipboard</property>
|
||||||
<accessibility>
|
|
||||||
<relation name="described-by">label</relation>
|
|
||||||
</accessibility>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
@@ -16,7 +13,7 @@
|
|||||||
<property name="margin-bottom">12</property>
|
<property name="margin-bottom">12</property>
|
||||||
<property name="spacing">12</property>
|
<property name="spacing">12</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="label">
|
<object class="GtkLabel">
|
||||||
<property name="label">“Copy” will copy the selected data the clipboard, “Paste” will show the current clipboard contents. You can also drag the data to the bottom.</property>
|
<property name="label">“Copy” will copy the selected data the clipboard, “Paste” will show the current clipboard contents. You can also drag the data to the bottom.</property>
|
||||||
<property name="wrap">1</property>
|
<property name="wrap">1</property>
|
||||||
<property name="max-width-chars">40</property>
|
<property name="max-width-chars">40</property>
|
||||||
@@ -27,9 +24,6 @@
|
|||||||
<property name="spacing">12</property>
|
<property name="spacing">12</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkDropDown" id="source_chooser">
|
<object class="GtkDropDown" id="source_chooser">
|
||||||
<accessibility>
|
|
||||||
<property name="label">Source Type</property>
|
|
||||||
</accessibility>
|
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<property name="model">
|
<property name="model">
|
||||||
<object class="GtkStringList">
|
<object class="GtkStringList">
|
||||||
@@ -38,7 +32,6 @@
|
|||||||
<item>Color</item>
|
<item>Color</item>
|
||||||
<item>Image</item>
|
<item>Image</item>
|
||||||
<item>File</item>
|
<item>File</item>
|
||||||
<item>Folder</item>
|
|
||||||
</items>
|
</items>
|
||||||
</object>
|
</object>
|
||||||
</property>
|
</property>
|
||||||
@@ -60,9 +53,6 @@
|
|||||||
<property name="name">Text</property>
|
<property name="name">Text</property>
|
||||||
<property name="child">
|
<property name="child">
|
||||||
<object class="GtkEntry" id="source_text">
|
<object class="GtkEntry" id="source_text">
|
||||||
<accessibility>
|
|
||||||
<property name="label">Text Drag Source</property>
|
|
||||||
</accessibility>
|
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<signal name="notify::text" handler="text_changed_cb" object="copy_button"/>
|
<signal name="notify::text" handler="text_changed_cb" object="copy_button"/>
|
||||||
<property name="text">Copy this!</property>
|
<property name="text">Copy this!</property>
|
||||||
@@ -74,14 +64,7 @@
|
|||||||
<object class="GtkStackPage">
|
<object class="GtkStackPage">
|
||||||
<property name="name">Color</property>
|
<property name="name">Color</property>
|
||||||
<property name="child">
|
<property name="child">
|
||||||
<object class="GtkColorDialogButton" id="source_color">
|
<object class="GtkColorButton" id="source_color">
|
||||||
<accessibility>
|
|
||||||
<property name="label">Color Drag Source</property>
|
|
||||||
</accessibility>
|
|
||||||
<property name="dialog">
|
|
||||||
<object class="GtkColorDialog">
|
|
||||||
</object>
|
|
||||||
</property>
|
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<property name="rgba">purple</property>
|
<property name="rgba">purple</property>
|
||||||
</object>
|
</object>
|
||||||
@@ -99,17 +82,14 @@
|
|||||||
</style>
|
</style>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkToggleButton" id="image_rose">
|
<object class="GtkToggleButton" id="image_rose">
|
||||||
<accessibility>
|
|
||||||
<property name="label">Photo Drag Source</property>
|
|
||||||
</accessibility>
|
|
||||||
<property name="active">1</property>
|
<property name="active">1</property>
|
||||||
<child>
|
<child>
|
||||||
|
<object class="GtkDragSource">
|
||||||
|
<signal name="prepare" handler="drag_prepare"/>
|
||||||
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<accessibility>
|
|
||||||
<property name="label">Portland Rose Photo</property>
|
|
||||||
</accessibility>
|
|
||||||
<style>
|
<style>
|
||||||
<class name="large-icons"/>
|
<class name="large-icons"/>
|
||||||
</style>
|
</style>
|
||||||
@@ -120,9 +100,6 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkToggleButton" id="image_floppy">
|
<object class="GtkToggleButton" id="image_floppy">
|
||||||
<accessibility>
|
|
||||||
<property name="label">Icon Drag Source</property>
|
|
||||||
</accessibility>
|
|
||||||
<property name="group">image_rose</property>
|
<property name="group">image_rose</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkDragSource">
|
<object class="GtkDragSource">
|
||||||
@@ -131,9 +108,6 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<accessibility>
|
|
||||||
<property name="label">Floppy Buddy Icon</property>
|
|
||||||
</accessibility>
|
|
||||||
<style>
|
<style>
|
||||||
<class name="large-icons"/>
|
<class name="large-icons"/>
|
||||||
</style>
|
</style>
|
||||||
@@ -144,9 +118,6 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkToggleButton" id="image_logo">
|
<object class="GtkToggleButton" id="image_logo">
|
||||||
<accessibility>
|
|
||||||
<property name="label">SVG Drag Source</property>
|
|
||||||
</accessibility>
|
|
||||||
<property name="group">image_floppy</property>
|
<property name="group">image_floppy</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkDragSource">
|
<object class="GtkDragSource">
|
||||||
@@ -155,9 +126,6 @@
|
|||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<accessibility>
|
|
||||||
<property name="label">gtk-demo logo</property>
|
|
||||||
</accessibility>
|
|
||||||
<style>
|
<style>
|
||||||
<class name="large-icons"/>
|
<class name="large-icons"/>
|
||||||
</style>
|
</style>
|
||||||
@@ -175,9 +143,6 @@
|
|||||||
<property name="name">File</property>
|
<property name="name">File</property>
|
||||||
<property name="child">
|
<property name="child">
|
||||||
<object class="GtkButton" id="source_file">
|
<object class="GtkButton" id="source_file">
|
||||||
<accessibility>
|
|
||||||
<property name="label">File Drag Source</property>
|
|
||||||
</accessibility>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkDragSource">
|
<object class="GtkDragSource">
|
||||||
<property name="propagation-phase">capture</property>
|
<property name="propagation-phase">capture</property>
|
||||||
@@ -197,33 +162,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<object class="GtkStackPage">
|
|
||||||
<property name="name">Folder</property>
|
|
||||||
<property name="child">
|
|
||||||
<object class="GtkButton" id="source_folder">
|
|
||||||
<accessibility>
|
|
||||||
<property name="label">Folder Drag Source</property>
|
|
||||||
</accessibility>
|
|
||||||
<child>
|
|
||||||
<object class="GtkDragSource">
|
|
||||||
<property name="propagation-phase">capture</property>
|
|
||||||
<signal name="prepare" handler="drag_prepare"/>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<property name="child">
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label">—</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="ellipsize">start</property>
|
|
||||||
</object>
|
|
||||||
</property>
|
|
||||||
<signal name="clicked" handler="open_folder_cb"/>
|
|
||||||
</object>
|
|
||||||
</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
@@ -258,7 +196,7 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="paste_label">
|
<object class="GtkLabel">
|
||||||
<property name="xalign">0</property>
|
<property name="xalign">0</property>
|
||||||
<binding name="label">
|
<binding name="label">
|
||||||
<lookup name="visible-child-name" type="GtkStack">
|
<lookup name="visible-child-name" type="GtkStack">
|
||||||
@@ -285,9 +223,6 @@
|
|||||||
<property name="name">Text</property>
|
<property name="name">Text</property>
|
||||||
<property name="child">
|
<property name="child">
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<accessibility>
|
|
||||||
<relation name="labelled-by">paste_label</relation>
|
|
||||||
</accessibility>
|
|
||||||
<property name="halign">end</property>
|
<property name="halign">end</property>
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<property name="xalign">0</property>
|
<property name="xalign">0</property>
|
||||||
@@ -301,9 +236,6 @@
|
|||||||
<property name="name">Image</property>
|
<property name="name">Image</property>
|
||||||
<property name="child">
|
<property name="child">
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
<accessibility>
|
|
||||||
<relation name="labelled-by">paste_label</relation>
|
|
||||||
</accessibility>
|
|
||||||
<property name="halign">end</property>
|
<property name="halign">end</property>
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<style>
|
<style>
|
||||||
@@ -322,9 +254,6 @@
|
|||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkColorSwatch">
|
<object class="GtkColorSwatch">
|
||||||
<accessibility>
|
|
||||||
<relation name="labelled-by">paste_label</relation>
|
|
||||||
</accessibility>
|
|
||||||
<property name="accessible-role">img</property>
|
<property name="accessible-role">img</property>
|
||||||
<property name="can-focus">0</property>
|
<property name="can-focus">0</property>
|
||||||
<property name="selectable">0</property>
|
<property name="selectable">0</property>
|
||||||
@@ -340,9 +269,6 @@
|
|||||||
<property name="name">File</property>
|
<property name="name">File</property>
|
||||||
<property name="child">
|
<property name="child">
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<accessibility>
|
|
||||||
<relation name="labelled-by">paste_label</relation>
|
|
||||||
</accessibility>
|
|
||||||
<property name="halign">end</property>
|
<property name="halign">end</property>
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<property name="xalign">0</property>
|
<property name="xalign">0</property>
|
||||||
|
226
demos/gtk-demo/cogs2.glsl
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
uniform float iTime;
|
||||||
|
|
||||||
|
// Originally from: https://www.shadertoy.com/view/3ljyDD
|
||||||
|
// License CC0: Hexagonal tiling + cog wheels
|
||||||
|
// Nothing fancy, just hexagonal tiling + cog wheels
|
||||||
|
|
||||||
|
#define PI 3.141592654
|
||||||
|
#define TAU (2.0*PI)
|
||||||
|
#define MROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
|
||||||
|
|
||||||
|
float hash(in vec2 co) {
|
||||||
|
return fract(sin(dot(co.xy ,vec2(12.9898,58.233))) * 13758.5453);
|
||||||
|
}
|
||||||
|
|
||||||
|
float pcos(float a) {
|
||||||
|
return 0.5 + 0.5*cos(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rot(inout vec2 p, float a) {
|
||||||
|
float c = cos(a);
|
||||||
|
float s = sin(a);
|
||||||
|
p = vec2(c*p.x + s*p.y, -s*p.x + c*p.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
float modPolar(inout vec2 p, float repetitions) {
|
||||||
|
float angle = 2.0*PI/repetitions;
|
||||||
|
float a = atan(p.y, p.x) + angle/2.;
|
||||||
|
float r = length(p);
|
||||||
|
float c = floor(a/angle);
|
||||||
|
a = mod(a,angle) - angle/2.;
|
||||||
|
p = vec2(cos(a), sin(a))*r;
|
||||||
|
// For an odd number of repetitions, fix cell index of the cell in -x direction
|
||||||
|
// (cell index would be e.g. -5 and 5 in the two halves of the cell):
|
||||||
|
if (abs(c) >= (repetitions/2.0)) c = abs(c);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
float pmin(float a, float b, float k) {
|
||||||
|
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
|
||||||
|
return mix( b, a, h ) - k*h*(1.0-h);
|
||||||
|
}
|
||||||
|
|
||||||
|
const vec2 sz = vec2(1.0, sqrt(3.0));
|
||||||
|
const vec2 hsz = 0.5*sz;
|
||||||
|
const float smallCount = 16.0;
|
||||||
|
|
||||||
|
vec2 hextile(inout vec2 p) {
|
||||||
|
// See Art of Code: Hexagonal Tiling Explained!
|
||||||
|
// https://www.youtube.com/watch?v=VmrIDyYiJBA
|
||||||
|
|
||||||
|
vec2 p1 = mod(p, sz)-hsz;
|
||||||
|
vec2 p2 = mod(p - hsz*1.0, sz)-hsz;
|
||||||
|
vec2 p3 = mix(p2, p1, vec2(length(p1) < length(p2)));
|
||||||
|
vec2 n = p3 - p;
|
||||||
|
p = p3;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
float circle(vec2 p, float r) {
|
||||||
|
return length(p) - r;
|
||||||
|
}
|
||||||
|
|
||||||
|
float box(vec2 p, vec2 b) {
|
||||||
|
vec2 d = abs(p)-b;
|
||||||
|
return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float unevenCapsule(vec2 p, float r1, float r2, float h) {
|
||||||
|
p.x = abs(p.x);
|
||||||
|
float b = (r1-r2)/h;
|
||||||
|
float a = sqrt(1.0-b*b);
|
||||||
|
float k = dot(p,vec2(-b,a));
|
||||||
|
if( k < 0.0 ) return length(p) - r1;
|
||||||
|
if( k > a*h ) return length(p-vec2(0.0,h)) - r2;
|
||||||
|
return dot(p, vec2(a,b) ) - r1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float cogwheel(vec2 p, float innerRadius, float outerRadius, float cogs, float holes) {
|
||||||
|
float cogWidth = 0.25*innerRadius*TAU/cogs;
|
||||||
|
|
||||||
|
float d0 = circle(p, innerRadius);
|
||||||
|
|
||||||
|
vec2 icp = p;
|
||||||
|
modPolar(icp, holes);
|
||||||
|
icp -= vec2(innerRadius*0.55, 0.0);
|
||||||
|
float d1 = circle(icp, innerRadius*0.25);
|
||||||
|
|
||||||
|
vec2 cp = p;
|
||||||
|
modPolar(cp, cogs);
|
||||||
|
cp -= vec2(innerRadius, 0.0);
|
||||||
|
float d2 = unevenCapsule(cp.yx, cogWidth, cogWidth*0.75, (outerRadius-innerRadius));
|
||||||
|
|
||||||
|
float d3 = circle(p, innerRadius*0.20);
|
||||||
|
|
||||||
|
float d = 1E6;
|
||||||
|
d = min(d, d0);
|
||||||
|
d = pmin(d, d2, 0.5*cogWidth);
|
||||||
|
d = min(d, d2);
|
||||||
|
d = max(d, -d1);
|
||||||
|
d = max(d, -d3);
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ccell1(vec2 p, float r) {
|
||||||
|
float d = 1E6;
|
||||||
|
const float bigCount = 60.0;
|
||||||
|
|
||||||
|
vec2 cp0 = p;
|
||||||
|
rot(cp0, -iTime*TAU/bigCount);
|
||||||
|
float d0 = cogwheel(cp0, 0.36, 0.38, bigCount, 5.0);
|
||||||
|
|
||||||
|
vec2 cp1 = p;
|
||||||
|
float nm = modPolar(cp1, 6.0);
|
||||||
|
|
||||||
|
cp1 -= vec2(0.5, 0.0);
|
||||||
|
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
|
||||||
|
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
|
||||||
|
|
||||||
|
d = min(d, d0);
|
||||||
|
d = min(d, d1);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ccell2(vec2 p, float r) {
|
||||||
|
float d = 1E6;
|
||||||
|
vec2 cp0 = p;
|
||||||
|
float nm = modPolar(cp0, 6.0);
|
||||||
|
vec2 cp1 = cp0;
|
||||||
|
const float off = 0.275;
|
||||||
|
const float count = smallCount + 2.0;
|
||||||
|
cp0 -= vec2(off, 0.0);
|
||||||
|
rot(cp0, 0.+TAU*nm/2.0 - iTime*TAU/count);
|
||||||
|
float d0 = cogwheel(cp0, 0.09, 0.105, count, 5.0);
|
||||||
|
|
||||||
|
|
||||||
|
cp1 -= vec2(0.5, 0.0);
|
||||||
|
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
|
||||||
|
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
|
||||||
|
|
||||||
|
float l = length(p);
|
||||||
|
float d2 = l - (off+0.055);
|
||||||
|
float d3 = d2 + 0.020;;
|
||||||
|
|
||||||
|
vec2 tp0 = p;
|
||||||
|
modPolar(tp0, 60.0);
|
||||||
|
tp0.x -= off;
|
||||||
|
float d4 = box(tp0, vec2(0.0125, 0.005));
|
||||||
|
|
||||||
|
float ctime = -(iTime*0.05 + r)*TAU;
|
||||||
|
|
||||||
|
vec2 tp1 = p;
|
||||||
|
rot(tp1, ctime*12.0);
|
||||||
|
tp1.x -= 0.13;
|
||||||
|
float d5 = box(tp1, vec2(0.125, 0.005));
|
||||||
|
|
||||||
|
vec2 tp2 = p;
|
||||||
|
rot(tp2, ctime);
|
||||||
|
tp2.x -= 0.13*0.5;
|
||||||
|
float d6 = box(tp2, vec2(0.125*0.5, 0.0075));
|
||||||
|
|
||||||
|
float d7 = l - 0.025;
|
||||||
|
float d8 = l - 0.0125;
|
||||||
|
|
||||||
|
d = min(d, d0);
|
||||||
|
d = min(d, d1);
|
||||||
|
d = min(d, d2);
|
||||||
|
d = max(d, -d3);
|
||||||
|
d = min(d, d4);
|
||||||
|
d = min(d, d5);
|
||||||
|
d = min(d, d6);
|
||||||
|
d = min(d, d7);
|
||||||
|
d = max(d, -d8);
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
float df(vec2 p, float scale, inout vec2 nn) {
|
||||||
|
p /= scale;
|
||||||
|
nn = hextile(p);
|
||||||
|
nn = floor(nn + 0.5);
|
||||||
|
float r = hash(nn);
|
||||||
|
|
||||||
|
float d;;
|
||||||
|
|
||||||
|
if (r < 0.5) {
|
||||||
|
d = ccell1(p, r);
|
||||||
|
} else {
|
||||||
|
d = ccell2(p, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
return d*scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 postProcess(vec3 col, vec2 q) {
|
||||||
|
//col = saturate(col);
|
||||||
|
col=pow(clamp(col,0.0,1.0),vec3(0.75));
|
||||||
|
col=col*0.6+0.4*col*col*(3.0-2.0*col); // contrast
|
||||||
|
col=mix(col, vec3(dot(col, vec3(0.33))), -0.4); // satuation
|
||||||
|
col*=0.5+0.5*pow(19.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7); // vigneting
|
||||||
|
return col;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv) {
|
||||||
|
vec2 q = fragCoord/resolution.xy;
|
||||||
|
vec2 p = -1.0 + 2.0*q;
|
||||||
|
p.x *= resolution.x/resolution.y;
|
||||||
|
float tm = iTime*0.1;
|
||||||
|
p += vec2(cos(tm), sin(tm*sqrt(0.5)));
|
||||||
|
float z = mix(0.5, 1.0, pcos(tm*sqrt(0.3)));
|
||||||
|
float aa = 4.0 / resolution.y;
|
||||||
|
|
||||||
|
vec2 nn = vec2(0.0);
|
||||||
|
float d = df(p, z, nn);
|
||||||
|
|
||||||
|
vec3 col = vec3(160.0)/vec3(255.0);
|
||||||
|
vec3 baseCol = vec3(0.3);
|
||||||
|
vec4 logoCol = vec4(baseCol, 1.0)*smoothstep(-aa, 0.0, -d);
|
||||||
|
col = mix(col, logoCol.xyz, pow(logoCol.w, 8.0));
|
||||||
|
col += 0.4*pow(abs(sin(20.0*d)), 0.6);
|
||||||
|
|
||||||
|
col = postProcess(col, q);
|
||||||
|
|
||||||
|
fragColor = vec4(col, 1.0);
|
||||||
|
}
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.4 KiB |
@@ -11,8 +11,6 @@
|
|||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ICON_NAME_COL,
|
ICON_NAME_COL,
|
||||||
@@ -449,7 +447,7 @@ do_combobox (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -277,7 +277,7 @@ do_constraints (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -66,7 +66,7 @@ do_constraints_builder (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -229,7 +229,7 @@ do_constraints_interactive (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -152,7 +152,7 @@ do_constraints_vfl (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1019 B After Width: | Height: | Size: 985 B |
27
demos/gtk-demo/crosswarp.glsl
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
uniform float progress;
|
||||||
|
uniform sampler2D u_texture1;
|
||||||
|
uniform sampler2D u_texture2;
|
||||||
|
|
||||||
|
vec4 getFromColor (vec2 uv) {
|
||||||
|
return GskTexture(u_texture1, uv);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 getToColor (vec2 uv) {
|
||||||
|
return GskTexture(u_texture2, uv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Source: https://gl-transitions.com/editor/crosswarp
|
||||||
|
// Author: Eke Péter <peterekepeter@gmail.com>
|
||||||
|
// License: MIT
|
||||||
|
|
||||||
|
vec4 transition(vec2 p) {
|
||||||
|
float x = progress;
|
||||||
|
x=smoothstep(.0,1.0,(x*2.0+p.x-1.0));
|
||||||
|
return mix(getFromColor((p-.5)*(1.-x)+.5), getToColor((p-.5)*x+.5), x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
|
||||||
|
{
|
||||||
|
fragColor = transition(uv);
|
||||||
|
}
|
@@ -1,16 +1,20 @@
|
|||||||
/* Theming/CSS Accordion
|
/* Theming/CSS Accordion
|
||||||
*
|
*
|
||||||
* A simple accordion demo written using CSS transitions and multiple backgrounds
|
* A simple accordion demo written using CSS transitions and multiple backgrounds
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_provider (GtkWidget *window,
|
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||||
GtkStyleProvider *provider)
|
|
||||||
{
|
{
|
||||||
gtk_style_context_remove_provider_for_display (gtk_widget_get_display (window), provider);
|
GtkWidget *child;
|
||||||
|
|
||||||
|
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||||
|
for (child = gtk_widget_get_first_child (widget);
|
||||||
|
child != NULL;
|
||||||
|
child = gtk_widget_get_next_sibling (child))
|
||||||
|
apply_css (child, provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
@@ -20,8 +24,8 @@ do_css_accordion (GtkWidget *do_widget)
|
|||||||
|
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
GtkWidget *container, *styled_box, *child;
|
GtkWidget *container, *child;
|
||||||
GtkCssProvider *provider;
|
GtkStyleProvider *provider;
|
||||||
|
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new ();
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "CSS Accordion");
|
gtk_window_set_title (GTK_WINDOW (window), "CSS Accordion");
|
||||||
@@ -29,13 +33,10 @@ do_css_accordion (GtkWidget *do_widget)
|
|||||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 300);
|
gtk_window_set_default_size (GTK_WINDOW (window), 600, 300);
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||||
|
|
||||||
styled_box = gtk_frame_new (NULL);
|
|
||||||
gtk_window_set_child (GTK_WINDOW (window), styled_box);
|
|
||||||
gtk_widget_add_css_class (styled_box, "accordion");
|
|
||||||
container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||||
gtk_widget_set_halign (container, GTK_ALIGN_CENTER);
|
gtk_widget_set_halign (container, GTK_ALIGN_CENTER);
|
||||||
gtk_widget_set_valign (container, GTK_ALIGN_CENTER);
|
gtk_widget_set_valign (container, GTK_ALIGN_CENTER);
|
||||||
gtk_frame_set_child (GTK_FRAME (styled_box), container);
|
gtk_window_set_child (GTK_WINDOW (window), container);
|
||||||
|
|
||||||
child = gtk_button_new_with_label ("This");
|
child = gtk_button_new_with_label ("This");
|
||||||
gtk_box_append (GTK_BOX (container), child);
|
gtk_box_append (GTK_BOX (container), child);
|
||||||
@@ -55,20 +56,14 @@ do_css_accordion (GtkWidget *do_widget)
|
|||||||
child = gtk_button_new_with_label (":-)");
|
child = gtk_button_new_with_label (":-)");
|
||||||
gtk_box_append (GTK_BOX (container), child);
|
gtk_box_append (GTK_BOX (container), child);
|
||||||
|
|
||||||
provider = gtk_css_provider_new ();
|
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||||
gtk_css_provider_load_from_resource (provider, "/css_accordion/css_accordion.css");
|
gtk_css_provider_load_from_resource (GTK_CSS_PROVIDER (provider), "/css_accordion/css_accordion.css");
|
||||||
|
|
||||||
gtk_style_context_add_provider_for_display (gtk_widget_get_display (window),
|
apply_css (window, provider);
|
||||||
GTK_STYLE_PROVIDER (provider),
|
|
||||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
|
||||||
|
|
||||||
g_signal_connect (window, "destroy",
|
|
||||||
G_CALLBACK (destroy_provider), provider);
|
|
||||||
g_object_unref (provider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
.accordion, .accordion * {
|
@import url("resource://css_accordion/reset.css");
|
||||||
all: unset;
|
|
||||||
|
|
||||||
|
* {
|
||||||
transition-property: color, background-color, border-color, background-image, padding, border-width;
|
transition-property: color, background-color, border-color, background-image, padding, border-width;
|
||||||
transition-duration: 1s;
|
transition-duration: 1s;
|
||||||
|
|
||||||
font: 20px Cantarell;
|
font: 20px Cantarell;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion {
|
window {
|
||||||
background: linear-gradient(153deg, #151515, #151515 5px, transparent 5px) 0 0,
|
background: linear-gradient(153deg, #151515, #151515 5px, transparent 5px) 0 0,
|
||||||
linear-gradient(333deg, #151515, #151515 5px, transparent 5px) 10px 5px,
|
linear-gradient(333deg, #151515, #151515 5px, transparent 5px) 10px 5px,
|
||||||
linear-gradient(153deg, #222, #222 5px, transparent 5px) 0 5px,
|
linear-gradient(153deg, #222, #222 5px, transparent 5px) 0 5px,
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
background-size: 20px 20px;
|
background-size: 20px 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion button {
|
button {
|
||||||
color: black;
|
color: black;
|
||||||
background-color: #bbb;
|
background-color: #bbb;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
@@ -28,25 +28,25 @@
|
|||||||
padding: 12px 4px;
|
padding: 12px 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion button:first-child {
|
button:first-child {
|
||||||
border-radius: 5px 0 0 5px;
|
border-radius: 5px 0 0 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion button:last-child {
|
button:last-child {
|
||||||
border-radius: 0 5px 5px 0;
|
border-radius: 0 5px 5px 0;
|
||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion button:hover {
|
button:hover {
|
||||||
padding: 12px 48px;
|
padding: 12px 48px;
|
||||||
background-color: #4870bc;
|
background-color: #4870bc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion button *:hover {
|
button *:hover {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion button:hover:active,
|
button:hover:active,
|
||||||
.accordion button:active {
|
button:active {
|
||||||
background-color: #993401;
|
background-color: #993401;
|
||||||
}
|
}
|
||||||
|
@@ -47,23 +47,20 @@ css_text_changed (GtkTextBuffer *buffer,
|
|||||||
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
||||||
|
|
||||||
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||||
gtk_css_provider_load_from_string (provider, text);
|
gtk_css_provider_load_from_data (provider, text, -1);
|
||||||
g_free (text);
|
g_free (text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
clear_provider (gpointer data)
|
|
||||||
{
|
|
||||||
GtkStyleProvider *provider = data;
|
|
||||||
|
|
||||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||||
{
|
{
|
||||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
|
GtkWidget *child;
|
||||||
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
|
|
||||||
|
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||||
|
for (child = gtk_widget_get_first_child (widget);
|
||||||
|
child != NULL;
|
||||||
|
child = gtk_widget_get_next_sibling (child))
|
||||||
|
apply_css (child, provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
@@ -82,7 +79,6 @@ do_css_basics (GtkWidget *do_widget)
|
|||||||
gtk_window_set_title (GTK_WINDOW (window), "CSS Basics");
|
gtk_window_set_title (GTK_WINDOW (window), "CSS Basics");
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
||||||
gtk_widget_add_css_class (window, "demo");
|
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||||
|
|
||||||
text = gtk_text_buffer_new (NULL);
|
text = gtk_text_buffer_new (NULL);
|
||||||
@@ -117,7 +113,7 @@ do_css_basics (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -4,24 +4,23 @@
|
|||||||
* anymore. :)
|
* anymore. :)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This resets all properties to their defaults values
|
/* This CSS resets all properties to their defaults values
|
||||||
* and overrides all user settings and the theme in use
|
* and overrides all user settings and the theme in use */
|
||||||
*/
|
@import url("resource://css_basics/reset.css");
|
||||||
@import url("resource://css_shadows/reset.css");
|
|
||||||
|
|
||||||
/* Set a very futuristic style by default */
|
/* Set a very futuristic style by default */
|
||||||
.demo * {
|
* {
|
||||||
color: green;
|
color: green;
|
||||||
font-family: Monospace;
|
font-family: Monospace;
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.demo {
|
window {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure selections are visible */
|
/* Make sure selections are visible */
|
||||||
.demo selection {
|
selection {
|
||||||
background-color: darkGreen;
|
background-color: darkGreen;
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
@@ -50,7 +50,7 @@ update_css_for_blend_mode (GtkCssProvider *provider,
|
|||||||
blend_mode,
|
blend_mode,
|
||||||
blend_mode);
|
blend_mode);
|
||||||
|
|
||||||
gtk_css_provider_load_from_string (provider, css);
|
gtk_css_provider_load_from_data (provider, css, -1);
|
||||||
|
|
||||||
g_bytes_unref (bytes);
|
g_bytes_unref (bytes);
|
||||||
g_free (css);
|
g_free (css);
|
||||||
@@ -139,7 +139,7 @@ do_css_blendmodes (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -48,23 +48,33 @@ css_text_changed (GtkTextBuffer *buffer,
|
|||||||
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
||||||
|
|
||||||
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||||
gtk_css_provider_load_from_string (provider, text);
|
gtk_css_provider_load_from_data (provider, text, -1);
|
||||||
g_free (text);
|
g_free (text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clear_provider (gpointer data)
|
drawing_area_draw (GtkDrawingArea *da,
|
||||||
|
cairo_t *cr,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
GtkStyleProvider *provider = data;
|
GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET (da));
|
||||||
|
|
||||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
|
gtk_render_background (context, cr, 0, 0, width, height);
|
||||||
|
gtk_render_frame (context, cr, 0, 0, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||||
{
|
{
|
||||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
|
GtkWidget *child;
|
||||||
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
|
|
||||||
|
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||||
|
for (child = gtk_widget_get_first_child (widget);
|
||||||
|
child != NULL;
|
||||||
|
child = gtk_widget_get_next_sibling (child))
|
||||||
|
apply_css (child, provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
@@ -83,17 +93,16 @@ do_css_multiplebgs (GtkWidget *do_widget)
|
|||||||
gtk_window_set_title (GTK_WINDOW (window), "Multiple Backgrounds");
|
gtk_window_set_title (GTK_WINDOW (window), "Multiple Backgrounds");
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
||||||
gtk_widget_add_css_class (window, "demo");
|
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||||
|
|
||||||
overlay = gtk_overlay_new ();
|
overlay = gtk_overlay_new ();
|
||||||
gtk_window_set_child (GTK_WINDOW (window), overlay);
|
gtk_window_set_child (GTK_WINDOW (window), overlay);
|
||||||
|
|
||||||
child = gtk_drawing_area_new ();
|
child = gtk_drawing_area_new ();
|
||||||
/* Don't set a draw_func, since we are only interested in CSS drawing,
|
|
||||||
* which happens automatically.
|
|
||||||
*/
|
|
||||||
gtk_widget_set_name (child, "canvas");
|
gtk_widget_set_name (child, "canvas");
|
||||||
|
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (child),
|
||||||
|
drawing_area_draw,
|
||||||
|
NULL, NULL);
|
||||||
gtk_overlay_set_child (GTK_OVERLAY (overlay), child);
|
gtk_overlay_set_child (GTK_OVERLAY (overlay), child);
|
||||||
|
|
||||||
child = gtk_button_new ();
|
child = gtk_button_new ();
|
||||||
@@ -144,7 +153,7 @@ do_css_multiplebgs (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -49,23 +49,20 @@ css_text_changed (GtkTextBuffer *buffer,
|
|||||||
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
||||||
|
|
||||||
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||||
gtk_css_provider_load_from_string (provider, text);
|
gtk_css_provider_load_from_data (provider, text, -1);
|
||||||
g_free (text);
|
g_free (text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
clear_provider (gpointer data)
|
|
||||||
{
|
|
||||||
GtkStyleProvider *provider = data;
|
|
||||||
|
|
||||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||||
{
|
{
|
||||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
|
GtkWidget *child;
|
||||||
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
|
|
||||||
|
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||||
|
for (child = gtk_widget_get_first_child (widget);
|
||||||
|
child != NULL;
|
||||||
|
child = gtk_widget_get_next_sibling (child))
|
||||||
|
apply_css (child, provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
@@ -84,7 +81,6 @@ do_css_pixbufs (GtkWidget *do_widget)
|
|||||||
gtk_window_set_title (GTK_WINDOW (window), "Animated Backgrounds");
|
gtk_window_set_title (GTK_WINDOW (window), "Animated Backgrounds");
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
||||||
gtk_widget_add_css_class (window, "demo");
|
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||||
|
|
||||||
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
||||||
@@ -126,7 +122,7 @@ do_css_pixbufs (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -50,7 +50,7 @@
|
|||||||
100% { background-size: 12px, 96px, 12px, 96px, 12px, 96px, 12px, 96px, auto; }
|
100% { background-size: 12px, 96px, 12px, 96px, 12px, 96px, 12px, 96px, auto; }
|
||||||
}
|
}
|
||||||
|
|
||||||
window.demo {
|
window {
|
||||||
background-image: url("resource://css_pixbufs/images/apple-red.png"),
|
background-image: url("resource://css_pixbufs/images/apple-red.png"),
|
||||||
url("resource://css_pixbufs/images/gnome-applets.png"),
|
url("resource://css_pixbufs/images/gnome-applets.png"),
|
||||||
url("resource://css_pixbufs/images/gnome-calendar.png"),
|
url("resource://css_pixbufs/images/gnome-calendar.png"),
|
||||||
@@ -66,11 +66,11 @@ window.demo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make the text editor has a nice style */
|
/* Make the text editor has a nice style */
|
||||||
window.demo .view, scrollbar, separator {
|
.view, scrollbar, separator {
|
||||||
color: black;
|
color: black;
|
||||||
background-color: rgba(255,255,255,0.5);
|
background-color: rgba(255,255,255,0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.demo .view:selected {
|
.view:selected {
|
||||||
background-color: rgba(127,127,255,0.5);
|
background-color: rgba(127,127,255,0.5);
|
||||||
}
|
}
|
||||||
|
@@ -46,23 +46,20 @@ css_text_changed (GtkTextBuffer *buffer,
|
|||||||
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
|
||||||
|
|
||||||
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||||
gtk_css_provider_load_from_string (provider, text);
|
gtk_css_provider_load_from_data (provider, text, -1);
|
||||||
g_free (text);
|
g_free (text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
clear_provider (gpointer data)
|
|
||||||
{
|
|
||||||
GtkStyleProvider *provider = data;
|
|
||||||
|
|
||||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||||
{
|
{
|
||||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
|
GtkWidget *child;
|
||||||
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
|
|
||||||
|
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||||
|
for (child = gtk_widget_get_first_child (widget);
|
||||||
|
child != NULL;
|
||||||
|
child = gtk_widget_get_next_sibling (child))
|
||||||
|
apply_css (child, provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkWidget *
|
static GtkWidget *
|
||||||
@@ -102,7 +99,6 @@ do_css_shadows (GtkWidget *do_widget)
|
|||||||
gtk_window_set_title (GTK_WINDOW (window), "Shadows");
|
gtk_window_set_title (GTK_WINDOW (window), "Shadows");
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
||||||
gtk_widget_add_css_class (window, "demo");
|
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||||
|
|
||||||
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
||||||
@@ -144,7 +140,7 @@ do_css_shadows (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_window_present (GTK_WINDOW (window));
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -5,13 +5,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* This CSS resets all properties to their defaults values
|
/* This CSS resets all properties to their defaults values
|
||||||
* and overrides all user settings and the theme in use
|
* and overrides all user settings and the theme in use */
|
||||||
*/
|
|
||||||
@import url("resource://css_shadows/reset.css");
|
@import url("resource://css_shadows/reset.css");
|
||||||
@import url("resource://css_shadows/cssview.css");
|
@import url("resource://css_shadows/cssview.css");
|
||||||
|
|
||||||
/* Get a nice background for the window */
|
/* Get a nice background for the window */
|
||||||
window.demo.background {
|
.background {
|
||||||
background-color: #4870bc;
|
background-color: #4870bc;
|
||||||
background-image: linear-gradient(to left, transparent, rgba(255,255,255,.07) 50%, transparent 50%),
|
background-image: linear-gradient(to left, transparent, rgba(255,255,255,.07) 50%, transparent 50%),
|
||||||
linear-gradient(to left, transparent, rgba(255,255,255,.13) 50%, transparent 50%),
|
linear-gradient(to left, transparent, rgba(255,255,255,.13) 50%, transparent 50%),
|
||||||
@@ -20,7 +19,7 @@ window.demo.background {
|
|||||||
background-size: 29px, 59px, 73px, 109px;
|
background-size: 29px, 59px, 73px, 109px;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.demo button {
|
button {
|
||||||
color: black;
|
color: black;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
@@ -28,15 +27,18 @@ window.demo button {
|
|||||||
border: 1px transparent solid;
|
border: 1px transparent solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.demo button:hover {
|
button:hover {
|
||||||
text-shadow: 3px 3px 5px alpha(black, 0.75);
|
text-shadow: 3px 3px 5px alpha(black, 0.75);
|
||||||
-gtk-icon-shadow: 3px 3px 5px alpha(black, 0.75);
|
-gtk-icon-shadow: 3px 3px 5px alpha(black, 0.75);
|
||||||
box-shadow: 3px 3px 5px alpha(black, 0.5) inset;
|
box-shadow: 3px 3px 5px alpha(black, 0.5) inset;
|
||||||
border: solid 1px alpha(black, 0.75);
|
border: solid 1px alpha(black, 0.75);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.demo button:active {
|
button:active {
|
||||||
padding: 11px 9px 9px 11px;
|
padding: 11px 9px 9px 11px;
|
||||||
text-shadow: 1px 1px 2.5px alpha(black, 0.6);
|
text-shadow: 1px 1px 2.5px alpha(black, 0.6);
|
||||||
-gtk-icon-shadow: 1px 1px 2.5px alpha(black, 0.6);
|
-gtk-icon-shadow: 1px 1px 2.5px alpha(black, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
/* Make the text editor has a nice style */
|
/* Make the text editor has a nice style */
|
||||||
window.demo .view {
|
.view {
|
||||||
color: #2e3436;
|
color: #2e3436;
|
||||||
font-family: Monospace;
|
font-family: Monospace;
|
||||||
background-color: alpha(white, 0.30);
|
background-color: alpha(white, 0.30);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.demo .view:selected {
|
.view:selected {
|
||||||
color: white;
|
color: white;
|
||||||
background-color: #4a90d9;
|
background-color: #4a90d9;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.demo scrollbar trough,
|
scrollbar trough,
|
||||||
.scrollbars-junction {
|
.scrollbars-junction {
|
||||||
background-color: alpha(white, 0.80);
|
background-color: alpha(white, 0.80);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.demo scrollbar slider {
|
scrollbar slider {
|
||||||
border-width: 3px;
|
border-width: 3px;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
@@ -24,11 +24,11 @@ window.demo scrollbar slider {
|
|||||||
background-color: #999;
|
background-color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.demo scrollbar slider:hover {
|
scrollbar slider:hover {
|
||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.demo paned separator {
|
paned separator {
|
||||||
background-color: alpha(white, 0.80);
|
background-color: alpha(white, 0.80);
|
||||||
background-image: linear-gradient(transparent, transparent 1px, #999 1px, #999 4px, transparent 4px);
|
background-image: linear-gradient(transparent, transparent 1px, #999 1px, #999 4px, transparent 4px);
|
||||||
background-size: 40px auto;
|
background-size: 40px auto;
|
||||||
@@ -36,6 +36,6 @@ window.demo paned separator {
|
|||||||
background-position: center;
|
background-position: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.demo paned separator:hover {
|
paned separator:hover {
|
||||||
background-image: linear-gradient(transparent, transparent 1px, #555 1px, #555 4px, transparent 4px);
|
background-image: linear-gradient(transparent, transparent 1px, #555 1px, #555 4px, transparent 4px);
|
||||||
}
|
}
|
||||||
|
@@ -15,54 +15,12 @@ on_destroy (gpointer data)
|
|||||||
window = NULL;
|
window = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkTexture *
|
|
||||||
cursor_callback (GdkCursor *cursor,
|
|
||||||
int cursor_size,
|
|
||||||
double scale,
|
|
||||||
int *width,
|
|
||||||
int *height,
|
|
||||||
int *hotspot_x,
|
|
||||||
int *hotspot_y,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
GdkPixbuf *pixbuf;
|
|
||||||
GdkTexture *texture;
|
|
||||||
GError *error = NULL;
|
|
||||||
int scaled_size;
|
|
||||||
|
|
||||||
scaled_size = ceil (cursor_size * scale);
|
|
||||||
|
|
||||||
pixbuf = gdk_pixbuf_new_from_resource_at_scale ("/cursors/images/gtk-logo.svg",
|
|
||||||
scaled_size, scaled_size,
|
|
||||||
TRUE,
|
|
||||||
&error);
|
|
||||||
if (!pixbuf)
|
|
||||||
{
|
|
||||||
g_print ("%s\n", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
texture = gdk_texture_new_for_pixbuf (pixbuf);
|
|
||||||
|
|
||||||
g_object_unref (pixbuf);
|
|
||||||
|
|
||||||
*width = cursor_size;
|
|
||||||
*height = cursor_size;
|
|
||||||
*hotspot_x = 18 * cursor_size / 32.0;
|
|
||||||
*hotspot_y = 2 * cursor_size / 32.0;
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
do_cursors (GtkWidget *do_widget)
|
do_cursors (GtkWidget *do_widget)
|
||||||
{
|
{
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
GtkBuilder *builder;
|
GtkBuilder *builder;
|
||||||
GtkWidget *logo_callback;
|
|
||||||
GdkCursor *cursor;
|
|
||||||
|
|
||||||
builder = gtk_builder_new_from_resource ("/cursors/cursors.ui");
|
builder = gtk_builder_new_from_resource ("/cursors/cursors.ui");
|
||||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||||
@@ -71,15 +29,11 @@ do_cursors (GtkWidget *do_widget)
|
|||||||
gtk_widget_get_display (do_widget));
|
gtk_widget_get_display (do_widget));
|
||||||
g_signal_connect (window, "destroy",
|
g_signal_connect (window, "destroy",
|
||||||
G_CALLBACK (on_destroy), NULL);
|
G_CALLBACK (on_destroy), NULL);
|
||||||
logo_callback = GTK_WIDGET (gtk_builder_get_object (builder, "logo_callback"));
|
|
||||||
cursor = gdk_cursor_new_from_callback (cursor_callback, NULL, NULL, NULL);
|
|
||||||
gtk_widget_set_cursor (logo_callback, cursor);
|
|
||||||
g_object_unref (cursor);
|
|
||||||
g_object_unref (builder);
|
g_object_unref (builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -24,6 +24,7 @@
|
|||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/css_accordion">
|
<gresource prefix="/css_accordion">
|
||||||
<file>css_accordion.css</file>
|
<file>css_accordion.css</file>
|
||||||
|
<file>reset.css</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/css_basics">
|
<gresource prefix="/css_basics">
|
||||||
<file>css_basics.css</file>
|
<file>css_basics.css</file>
|
||||||
@@ -43,7 +44,7 @@
|
|||||||
<file>cssview.css</file>
|
<file>cssview.css</file>
|
||||||
<file>reset.css</file>
|
<file>reset.css</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/listview_selections">
|
<gresource prefix="/dropdown">
|
||||||
<file>suggestionentry.h</file>
|
<file>suggestionentry.h</file>
|
||||||
<file>suggestionentry.c</file>
|
<file>suggestionentry.c</file>
|
||||||
<file>suggestionentry.css</file>
|
<file>suggestionentry.css</file>
|
||||||
@@ -116,7 +117,6 @@
|
|||||||
<file>w_resize_cursor.png</file>
|
<file>w_resize_cursor.png</file>
|
||||||
<file>zoom_in_cursor.png</file>
|
<file>zoom_in_cursor.png</file>
|
||||||
<file>zoom_out_cursor.png</file>
|
<file>zoom_out_cursor.png</file>
|
||||||
<file>gtk-logo.svg</file>
|
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/dnd">
|
<gresource prefix="/dnd">
|
||||||
<file>dnd.css</file>
|
<file>dnd.css</file>
|
||||||
@@ -128,7 +128,6 @@
|
|||||||
<file>fishbowl.ui</file>
|
<file>fishbowl.ui</file>
|
||||||
<file>gtkfishbowl.c</file>
|
<file>gtkfishbowl.c</file>
|
||||||
<file>gtkfishbowl.h</file>
|
<file>gtkfishbowl.h</file>
|
||||||
<file>tiger.node</file>
|
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/frames">
|
<gresource prefix="/frames">
|
||||||
<file>frames.ui</file>
|
<file>frames.ui</file>
|
||||||
@@ -146,6 +145,21 @@
|
|||||||
<file>cogs.glsl</file>
|
<file>cogs.glsl</file>
|
||||||
<file>glowingstars.glsl</file>
|
<file>glowingstars.glsl</file>
|
||||||
</gresource>
|
</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">
|
<gresource prefix="/iconscroll">
|
||||||
<file>iconscroll.ui</file>
|
<file>iconscroll.ui</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
@@ -182,9 +196,6 @@
|
|||||||
<gresource prefix="/listview_settings">
|
<gresource prefix="/listview_settings">
|
||||||
<file>listview_settings.ui</file>
|
<file>listview_settings.ui</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/listview_settings2">
|
|
||||||
<file>listview_settings2.ui</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/listview_ucd_data/">
|
<gresource prefix="/listview_ucd_data/">
|
||||||
<file>ucdnames.data</file>
|
<file>ucdnames.data</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
@@ -205,12 +216,6 @@
|
|||||||
<file>demo3widget.h</file>
|
<file>demo3widget.h</file>
|
||||||
<file>demo3widget.ui</file>
|
<file>demo3widget.ui</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/mask">
|
|
||||||
<file>demo4widget.c</file>
|
|
||||||
<file>demo4widget.h</file>
|
|
||||||
<file>hsla.h</file>
|
|
||||||
<file>hsla.c</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/paintable_svg">
|
<gresource prefix="/paintable_svg">
|
||||||
<file>svgpaintable.h</file>
|
<file>svgpaintable.h</file>
|
||||||
<file>svgpaintable.c</file>
|
<file>svgpaintable.c</file>
|
||||||
@@ -264,6 +269,7 @@
|
|||||||
<file>cursors.c</file>
|
<file>cursors.c</file>
|
||||||
<file>dialog.c</file>
|
<file>dialog.c</file>
|
||||||
<file>drawingarea.c</file>
|
<file>drawingarea.c</file>
|
||||||
|
<file>dropdown.c</file>
|
||||||
<file>dnd.c</file>
|
<file>dnd.c</file>
|
||||||
<file>editable_cells.c</file>
|
<file>editable_cells.c</file>
|
||||||
<file>entry_completion.c</file>
|
<file>entry_completion.c</file>
|
||||||
@@ -281,12 +287,12 @@
|
|||||||
<file>gears.c</file>
|
<file>gears.c</file>
|
||||||
<file>gestures.c</file>
|
<file>gestures.c</file>
|
||||||
<file>glarea.c</file>
|
<file>glarea.c</file>
|
||||||
|
<file>gltransition.c</file>
|
||||||
<file>headerbar.c</file>
|
<file>headerbar.c</file>
|
||||||
<file>hypertext.c</file>
|
<file>hypertext.c</file>
|
||||||
<file>iconscroll.c</file>
|
<file>iconscroll.c</file>
|
||||||
<file>iconview.c</file>
|
<file>iconview.c</file>
|
||||||
<file>iconview_edit.c</file>
|
<file>iconview_edit.c</file>
|
||||||
<file>image_scaling.c</file>
|
|
||||||
<file>images.c</file>
|
<file>images.c</file>
|
||||||
<file>infobar.c</file>
|
<file>infobar.c</file>
|
||||||
<file>layoutmanager.c</file>
|
<file>layoutmanager.c</file>
|
||||||
@@ -299,16 +305,14 @@
|
|||||||
<file>listview_clocks.c</file>
|
<file>listview_clocks.c</file>
|
||||||
<file>listview_filebrowser.c</file>
|
<file>listview_filebrowser.c</file>
|
||||||
<file>listview_minesweeper.c</file>
|
<file>listview_minesweeper.c</file>
|
||||||
<file>listview_selections.c</file>
|
|
||||||
<file>listview_settings.c</file>
|
<file>listview_settings.c</file>
|
||||||
<file>listview_settings2.c</file>
|
|
||||||
<file>listview_ucd.c</file>
|
<file>listview_ucd.c</file>
|
||||||
<file>listview_weather.c</file>
|
<file>listview_weather.c</file>
|
||||||
<file>listview_words.c</file>
|
<file>listview_words.c</file>
|
||||||
<file>list_store.c</file>
|
<file>list_store.c</file>
|
||||||
<file>main.c</file>
|
<file>main.c</file>
|
||||||
<file>markup.c</file>
|
<file>markup.c</file>
|
||||||
<file>mask.c</file>
|
<file>menu.c</file>
|
||||||
<file>overlay.c</file>
|
<file>overlay.c</file>
|
||||||
<file>overlay_decorative.c</file>
|
<file>overlay_decorative.c</file>
|
||||||
<file>paint.c</file>
|
<file>paint.c</file>
|
||||||
@@ -321,11 +325,6 @@
|
|||||||
<file>paintable_symbolic.c</file>
|
<file>paintable_symbolic.c</file>
|
||||||
<file>panes.c</file>
|
<file>panes.c</file>
|
||||||
<file>password_entry.c</file>
|
<file>password_entry.c</file>
|
||||||
<file>path_fill.c</file>
|
|
||||||
<file>path_maze.c</file>
|
|
||||||
<file>path_spinner.c</file>
|
|
||||||
<file>path_walk.c</file>
|
|
||||||
<file>path_text.c</file>
|
|
||||||
<file>peg_solitaire.c</file>
|
<file>peg_solitaire.c</file>
|
||||||
<file>pickers.c</file>
|
<file>pickers.c</file>
|
||||||
<file>printing.c</file>
|
<file>printing.c</file>
|
||||||
@@ -411,13 +410,6 @@
|
|||||||
<gresource prefix="/fontrendering">
|
<gresource prefix="/fontrendering">
|
||||||
<file>fontrendering.ui</file>
|
<file>fontrendering.ui</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/path_walk">
|
|
||||||
<file>path_walk.ui</file>
|
|
||||||
<file compressed="true">path_world.txt</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/path_text">
|
|
||||||
<file>path_text.ui</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/org/gtk/Demo4">
|
<gresource prefix="/org/gtk/Demo4">
|
||||||
<file>icons/16x16/actions/application-exit.png</file>
|
<file>icons/16x16/actions/application-exit.png</file>
|
||||||
<file>icons/16x16/actions/document-new.png</file>
|
<file>icons/16x16/actions/document-new.png</file>
|
||||||
@@ -438,10 +430,6 @@
|
|||||||
<file>icons/16x16/categories/applications-other.png</file>
|
<file>icons/16x16/categories/applications-other.png</file>
|
||||||
<file>icons/48x48/status/starred.png</file>
|
<file>icons/48x48/status/starred.png</file>
|
||||||
<file alias="icons/scalable/apps/org.gtk.Demo4.svg">data/scalable/apps/org.gtk.Demo4.svg</file>
|
<file alias="icons/scalable/apps/org.gtk.Demo4.svg">data/scalable/apps/org.gtk.Demo4.svg</file>
|
||||||
<file>portland-rose-thumbnail.png</file>
|
|
||||||
<file>large-image-thumbnail.png</file>
|
|
||||||
<file compressed="true">large-image.png</file>
|
|
||||||
<file compressed="true">Moby-Dick.txt</file>
|
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/org/gtk/Demo4/gtk">
|
<gresource prefix="/org/gtk/Demo4/gtk">
|
||||||
<file preprocess="xml-stripblanks">help-overlay.ui</file>
|
<file preprocess="xml-stripblanks">help-overlay.ui</file>
|
||||||
|
@@ -208,13 +208,7 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel" id="statusbar1">
|
<object class="GtkStatusbar" id="statusbar1"/>
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="margin-start">2</property>
|
|
||||||
<property name="margin-end">2</property>
|
|
||||||
<property name="margin-top">2</property>
|
|
||||||
<property name="margin-bottom">2</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
@@ -3,20 +3,16 @@
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_TEXTURE = 1,
|
PROP_PAINTABLE = 1,
|
||||||
PROP_FILTER,
|
PROP_SCALE
|
||||||
PROP_SCALE,
|
|
||||||
PROP_ANGLE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Demo3Widget
|
struct _Demo3Widget
|
||||||
{
|
{
|
||||||
GtkWidget parent_instance;
|
GtkWidget parent_instance;
|
||||||
|
|
||||||
GdkTexture *texture;
|
GdkPaintable *paintable;
|
||||||
float scale;
|
float scale;
|
||||||
float angle;
|
|
||||||
GskScalingFilter filter;
|
|
||||||
|
|
||||||
GtkWidget *menu;
|
GtkWidget *menu;
|
||||||
};
|
};
|
||||||
@@ -28,88 +24,10 @@ struct _Demo3WidgetClass
|
|||||||
|
|
||||||
G_DEFINE_TYPE (Demo3Widget, demo3_widget, GTK_TYPE_WIDGET)
|
G_DEFINE_TYPE (Demo3Widget, demo3_widget, GTK_TYPE_WIDGET)
|
||||||
|
|
||||||
static gboolean
|
|
||||||
query_tooltip (GtkWidget *widget,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
gboolean keyboard_mode,
|
|
||||||
GtkTooltip *tooltip,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
|
||||||
GtkWidget *grid;
|
|
||||||
GtkWidget *label;
|
|
||||||
char *s, *s2;
|
|
||||||
const char *filter[] = { "Linear", "Nearest", "Trilinear" };
|
|
||||||
int precision, l;
|
|
||||||
|
|
||||||
grid = gtk_grid_new ();
|
|
||||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 12);
|
|
||||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
|
|
||||||
label = gtk_label_new ("Texture");
|
|
||||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
|
||||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
|
|
||||||
s = g_strdup_printf ("%d\342\200\206\303\227\342\200\206%d",
|
|
||||||
gdk_texture_get_width (self->texture),
|
|
||||||
gdk_texture_get_height (self->texture));
|
|
||||||
label = gtk_label_new (s);
|
|
||||||
g_free (s);
|
|
||||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
|
||||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
|
|
||||||
|
|
||||||
label = gtk_label_new ("Rotation");
|
|
||||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
|
||||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
|
|
||||||
s = g_strdup_printf ("%.1f", self->angle);
|
|
||||||
if (g_str_has_suffix (s, ".0"))
|
|
||||||
s[strlen (s) - 2] = '\0';
|
|
||||||
s2 = g_strconcat (s, "\302\260", NULL);
|
|
||||||
label = gtk_label_new (s2);
|
|
||||||
g_free (s2);
|
|
||||||
g_free (s);
|
|
||||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
|
||||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 1, 1, 1);
|
|
||||||
|
|
||||||
label = gtk_label_new ("Scale");
|
|
||||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
|
||||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
|
|
||||||
|
|
||||||
precision = 1;
|
|
||||||
s = NULL;
|
|
||||||
do {
|
|
||||||
g_free (s);
|
|
||||||
s = g_strdup_printf ("%.*f", precision, self->scale);
|
|
||||||
l = strlen (s) - 1;
|
|
||||||
while (s[l] == '0')
|
|
||||||
l--;
|
|
||||||
if (s[l] == '.')
|
|
||||||
s[l] = '\0';
|
|
||||||
precision++;
|
|
||||||
} while (strcmp (s, "0") == 0);
|
|
||||||
|
|
||||||
label = gtk_label_new (s);
|
|
||||||
g_free (s);
|
|
||||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
|
||||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 2, 1, 1);
|
|
||||||
|
|
||||||
label = gtk_label_new ("Filter");
|
|
||||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
|
||||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 1, 1);
|
|
||||||
label = gtk_label_new (filter[self->filter]);
|
|
||||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
|
||||||
gtk_grid_attach (GTK_GRID (grid), label, 1, 3, 1, 1);
|
|
||||||
|
|
||||||
gtk_tooltip_set_custom (tooltip, grid);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
demo3_widget_init (Demo3Widget *self)
|
demo3_widget_init (Demo3Widget *self)
|
||||||
{
|
{
|
||||||
self->scale = 1.f;
|
self->scale = 1.f;
|
||||||
self->angle = 0.f;
|
|
||||||
self->filter = GSK_SCALING_FILTER_LINEAR;
|
|
||||||
gtk_widget_init_template (GTK_WIDGET (self));
|
gtk_widget_init_template (GTK_WIDGET (self));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +36,7 @@ demo3_widget_dispose (GObject *object)
|
|||||||
{
|
{
|
||||||
Demo3Widget *self = DEMO3_WIDGET (object);
|
Demo3Widget *self = DEMO3_WIDGET (object);
|
||||||
|
|
||||||
g_clear_object (&self->texture);
|
g_clear_object (&self->paintable);
|
||||||
|
|
||||||
gtk_widget_dispose_template (GTK_WIDGET (self), DEMO3_TYPE_WIDGET);
|
gtk_widget_dispose_template (GTK_WIDGET (self), DEMO3_TYPE_WIDGET);
|
||||||
|
|
||||||
@@ -131,35 +49,21 @@ demo3_widget_snapshot (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
Demo3Widget *self = DEMO3_WIDGET (widget);
|
||||||
int x, y, width, height;
|
int x, y, width, height;
|
||||||
double w, h, w2, h2;
|
double w, h;
|
||||||
|
|
||||||
width = gtk_widget_get_width (widget);
|
width = gtk_widget_get_width (widget);
|
||||||
height = gtk_widget_get_height (widget);
|
height = gtk_widget_get_height (widget);
|
||||||
|
|
||||||
w2 = w = self->scale * gdk_texture_get_width (self->texture);
|
w = self->scale * gdk_paintable_get_intrinsic_width (self->paintable);
|
||||||
h2 = h = self->scale * gdk_texture_get_height (self->texture);
|
h = self->scale * gdk_paintable_get_intrinsic_height (self->paintable);
|
||||||
|
|
||||||
if (G_APPROX_VALUE (self->angle, 90.f, FLT_EPSILON) ||
|
x = MAX (0, (width - ceil (w)) / 2);
|
||||||
G_APPROX_VALUE (self->angle, 270.f, FLT_EPSILON))
|
y = MAX (0, (height - ceil (h)) / 2);
|
||||||
{
|
|
||||||
double s = w2;
|
|
||||||
w2 = h2;
|
|
||||||
h2 = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
x = (width - ceil (w2)) / 2;
|
|
||||||
y = (height - ceil (h2)) / 2;
|
|
||||||
|
|
||||||
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||||
gtk_snapshot_save (snapshot);
|
gtk_snapshot_save (snapshot);
|
||||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
|
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
|
||||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (w2 / 2, h2 / 2));
|
gdk_paintable_snapshot (self->paintable, snapshot, w, h);
|
||||||
gtk_snapshot_rotate (snapshot, self->angle);
|
|
||||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- w / 2, - h / 2));
|
|
||||||
gtk_snapshot_append_scaled_texture (snapshot,
|
|
||||||
self->texture,
|
|
||||||
self->filter,
|
|
||||||
&GRAPHENE_RECT_INIT (0, 0, w, h));
|
|
||||||
gtk_snapshot_restore (snapshot);
|
gtk_snapshot_restore (snapshot);
|
||||||
gtk_snapshot_pop (snapshot);
|
gtk_snapshot_pop (snapshot);
|
||||||
}
|
}
|
||||||
@@ -174,26 +78,14 @@ demo3_widget_measure (GtkWidget *widget,
|
|||||||
int *natural_baseline)
|
int *natural_baseline)
|
||||||
{
|
{
|
||||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
Demo3Widget *self = DEMO3_WIDGET (widget);
|
||||||
int width, height;
|
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
width = gdk_texture_get_width (self->texture);
|
|
||||||
height = gdk_texture_get_height (self->texture);
|
|
||||||
|
|
||||||
if (G_APPROX_VALUE (self->angle, 90.f, FLT_EPSILON) ||
|
|
||||||
G_APPROX_VALUE (self->angle, 270.f, FLT_EPSILON))
|
|
||||||
{
|
|
||||||
int s = width;
|
|
||||||
width = height;
|
|
||||||
height = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||||
size = width;
|
size = gdk_paintable_get_intrinsic_width (self->paintable);
|
||||||
else
|
else
|
||||||
size = height;
|
size = gdk_paintable_get_intrinsic_height (self->paintable);
|
||||||
|
|
||||||
*minimum = *natural = (int) ceil (self->scale * size);
|
*minimum = *natural = self->scale * size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -211,8 +103,6 @@ demo3_widget_size_allocate (GtkWidget *widget,
|
|||||||
gtk_popover_present (GTK_POPOVER (self->menu));
|
gtk_popover_present (GTK_POPOVER (self->menu));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_actions (Demo3Widget *self);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
demo3_widget_set_property (GObject *object,
|
demo3_widget_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@@ -223,32 +113,14 @@ demo3_widget_set_property (GObject *object,
|
|||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_TEXTURE:
|
case PROP_PAINTABLE:
|
||||||
g_clear_object (&self->texture);
|
g_clear_object (&self->paintable);
|
||||||
self->texture = g_value_dup_object (value);
|
self->paintable = g_value_dup_object (value);
|
||||||
self->scale = 1.f;
|
|
||||||
self->angle = 0.f;
|
|
||||||
self->filter = GSK_SCALING_FILTER_LINEAR;
|
|
||||||
update_actions (self);
|
|
||||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||||
g_object_notify (object, "scale");
|
|
||||||
g_object_notify (object, "angle");
|
|
||||||
g_object_notify (object, "filter");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_SCALE:
|
case PROP_SCALE:
|
||||||
self->scale = g_value_get_float (value);
|
self->scale = g_value_get_float (value);
|
||||||
update_actions (self);
|
|
||||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_ANGLE:
|
|
||||||
self->angle = fmodf (g_value_get_float (value), 360.f);
|
|
||||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_FILTER:
|
|
||||||
self->filter = g_value_get_enum (value);
|
|
||||||
gtk_widget_queue_resize (GTK_WIDGET (object));
|
gtk_widget_queue_resize (GTK_WIDGET (object));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -268,22 +140,14 @@ demo3_widget_get_property (GObject *object,
|
|||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_TEXTURE:
|
case PROP_PAINTABLE:
|
||||||
g_value_set_object (value, self->texture);
|
g_value_set_object (value, self->paintable);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_SCALE:
|
case PROP_SCALE:
|
||||||
g_value_set_float (value, self->scale);
|
g_value_set_float (value, self->scale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_ANGLE:
|
|
||||||
g_value_set_float (value, self->angle);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_FILTER:
|
|
||||||
g_value_set_enum (value, self->filter);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -305,14 +169,6 @@ pressed_cb (GtkGestureClick *gesture,
|
|||||||
gtk_popover_popup (GTK_POPOVER (self->menu));
|
gtk_popover_popup (GTK_POPOVER (self->menu));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
update_actions (Demo3Widget *self)
|
|
||||||
{
|
|
||||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.in", self->scale < 1024.);
|
|
||||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.out", self->scale > 1./1024.);
|
|
||||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "zoom.reset", self->scale != 1.);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zoom_cb (GtkWidget *widget,
|
zoom_cb (GtkWidget *widget,
|
||||||
const char *action_name,
|
const char *action_name,
|
||||||
@@ -322,30 +178,19 @@ zoom_cb (GtkWidget *widget,
|
|||||||
float scale;
|
float scale;
|
||||||
|
|
||||||
if (g_str_equal (action_name, "zoom.in"))
|
if (g_str_equal (action_name, "zoom.in"))
|
||||||
scale = MIN (1024., self->scale * M_SQRT2);
|
scale = MIN (10, self->scale * M_SQRT2);
|
||||||
else if (g_str_equal (action_name, "zoom.out"))
|
else if (g_str_equal (action_name, "zoom.out"))
|
||||||
scale = MAX (1./1024., self->scale / M_SQRT2);
|
scale = MAX (0.01, self->scale / M_SQRT2);
|
||||||
else if (g_str_equal (action_name, "zoom.reset"))
|
|
||||||
scale = 1.0;
|
|
||||||
else
|
else
|
||||||
g_assert_not_reached ();
|
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);
|
g_object_set (widget, "scale", scale, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
rotate_cb (GtkWidget *widget,
|
|
||||||
const char *action_name,
|
|
||||||
GVariant *parameter)
|
|
||||||
{
|
|
||||||
Demo3Widget *self = DEMO3_WIDGET (widget);
|
|
||||||
int angle;
|
|
||||||
|
|
||||||
g_variant_get (parameter, "i", &angle);
|
|
||||||
|
|
||||||
g_object_set (widget, "angle", fmodf (self->angle + angle, 360.f), NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
demo3_widget_class_init (Demo3WidgetClass *class)
|
demo3_widget_class_init (Demo3WidgetClass *class)
|
||||||
{
|
{
|
||||||
@@ -360,55 +205,40 @@ demo3_widget_class_init (Demo3WidgetClass *class)
|
|||||||
widget_class->measure = demo3_widget_measure;
|
widget_class->measure = demo3_widget_measure;
|
||||||
widget_class->size_allocate = demo3_widget_size_allocate;
|
widget_class->size_allocate = demo3_widget_size_allocate;
|
||||||
|
|
||||||
g_object_class_install_property (object_class, PROP_TEXTURE,
|
g_object_class_install_property (object_class, PROP_PAINTABLE,
|
||||||
g_param_spec_object ("texture", NULL, NULL,
|
g_param_spec_object ("paintable", "Paintable", "Paintable",
|
||||||
GDK_TYPE_TEXTURE,
|
GDK_TYPE_PAINTABLE,
|
||||||
G_PARAM_READWRITE));
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
g_object_class_install_property (object_class, PROP_SCALE,
|
g_object_class_install_property (object_class, PROP_SCALE,
|
||||||
g_param_spec_float ("scale", NULL, NULL,
|
g_param_spec_float ("scale", "Scale", "Scale",
|
||||||
1./1024., 1024., 1.0,
|
0.0, 10.0, 1.0,
|
||||||
G_PARAM_READWRITE));
|
G_PARAM_READWRITE));
|
||||||
|
|
||||||
g_object_class_install_property (object_class, PROP_ANGLE,
|
|
||||||
g_param_spec_float ("angle", NULL, NULL,
|
|
||||||
0.0, 360.0, 0.0,
|
|
||||||
G_PARAM_READWRITE));
|
|
||||||
|
|
||||||
g_object_class_install_property (object_class, PROP_FILTER,
|
|
||||||
g_param_spec_enum ("filter", NULL, NULL,
|
|
||||||
GSK_TYPE_SCALING_FILTER, GSK_SCALING_FILTER_LINEAR,
|
|
||||||
G_PARAM_READWRITE));
|
|
||||||
|
|
||||||
/* These are the actions that we are using in the menu */
|
/* 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.in", NULL, zoom_cb);
|
||||||
gtk_widget_class_install_action (widget_class, "zoom.out", 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_install_action (widget_class, "zoom.reset", NULL, zoom_cb);
|
||||||
gtk_widget_class_install_action (widget_class, "rotate", "i", rotate_cb);
|
|
||||||
|
|
||||||
gtk_widget_class_set_template_from_resource (widget_class, "/menu/demo3widget.ui");
|
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_child (widget_class, Demo3Widget, menu);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, pressed_cb);
|
gtk_widget_class_bind_template_callback (widget_class, pressed_cb);
|
||||||
|
|
||||||
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_IMG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
demo3_widget_new (const char *resource)
|
demo3_widget_new (const char *resource)
|
||||||
{
|
{
|
||||||
Demo3Widget *self;
|
Demo3Widget *self;
|
||||||
GdkTexture *texture;
|
GdkPixbuf *pixbuf;
|
||||||
|
GdkPaintable *paintable;
|
||||||
|
|
||||||
texture = gdk_texture_new_from_resource (resource);
|
pixbuf = gdk_pixbuf_new_from_resource (resource, NULL);
|
||||||
|
paintable = GDK_PAINTABLE (gdk_texture_new_for_pixbuf (pixbuf));
|
||||||
|
|
||||||
self = g_object_new (DEMO3_TYPE_WIDGET,
|
self = g_object_new (DEMO3_TYPE_WIDGET, "paintable", paintable, NULL);
|
||||||
"texture", texture,
|
|
||||||
"has-tooltip", TRUE,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
g_signal_connect (self, "query-tooltip", G_CALLBACK (query_tooltip), NULL);
|
g_object_unref (pixbuf);
|
||||||
|
g_object_unref (paintable);
|
||||||
g_object_unref (texture);
|
|
||||||
|
|
||||||
return GTK_WIDGET (self);
|
return GTK_WIDGET (self);
|
||||||
}
|
}
|
||||||
|
@@ -12,21 +12,10 @@
|
|||||||
<attribute name="label">1∶1</attribute>
|
<attribute name="label">1∶1</attribute>
|
||||||
<attribute name="action">zoom.reset</attribute>
|
<attribute name="action">zoom.reset</attribute>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<attribute name="label">Rotate</attribute>
|
|
||||||
<attribute name="action">rotate</attribute>
|
|
||||||
<attribute name="target" type="i">90</attribute>
|
|
||||||
</item>
|
|
||||||
</menu>
|
</menu>
|
||||||
<template class="Demo3Widget">
|
<template class="Demo3Widget">
|
||||||
<accessibility>
|
|
||||||
<property name="label">Demo image</property>
|
|
||||||
</accessibility>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkPopoverMenu" id="menu">
|
<object class="GtkPopoverMenu" id="menu">
|
||||||
<accessibility>
|
|
||||||
<property name="label">Context menu</property>
|
|
||||||
</accessibility>
|
|
||||||
<property name="has-arrow">0</property>
|
<property name="has-arrow">0</property>
|
||||||
<property name="menu-model">model</property>
|
<property name="menu-model">model</property>
|
||||||
</object>
|
</object>
|
||||||
|
@@ -1,226 +0,0 @@
|
|||||||
#include <math.h>
|
|
||||||
#include "demo4widget.h"
|
|
||||||
#include "hsla.h"
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
PROP_0,
|
|
||||||
PROP_PROGRESS,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _Demo4Widget
|
|
||||||
{
|
|
||||||
GtkWidget parent_instance;
|
|
||||||
PangoLayout *layout;
|
|
||||||
GskColorStop stops[8];
|
|
||||||
gsize n_stops;
|
|
||||||
double progress;
|
|
||||||
|
|
||||||
guint tick;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _Demo4WidgetClass
|
|
||||||
{
|
|
||||||
GtkWidgetClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (Demo4Widget, demo4_widget, GTK_TYPE_WIDGET)
|
|
||||||
|
|
||||||
static void
|
|
||||||
rotate_color (GdkRGBA *rgba)
|
|
||||||
{
|
|
||||||
GdkHSLA hsla;
|
|
||||||
|
|
||||||
_gdk_hsla_init_from_rgba (&hsla, rgba);
|
|
||||||
hsla.hue -= 1;
|
|
||||||
_gdk_rgba_init_from_hsla (rgba, &hsla);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
rotate_colors (GtkWidget *widget,
|
|
||||||
GdkFrameClock *clock,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
Demo4Widget *self = DEMO4_WIDGET (widget);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < self->n_stops; i++)
|
|
||||||
rotate_color (&self->stops[i].color);
|
|
||||||
|
|
||||||
gtk_widget_queue_draw (widget);
|
|
||||||
|
|
||||||
return G_SOURCE_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo4_widget_init (Demo4Widget *self)
|
|
||||||
{
|
|
||||||
PangoFontDescription *desc;
|
|
||||||
|
|
||||||
self->progress = 0.5;
|
|
||||||
|
|
||||||
self->n_stops = 8;
|
|
||||||
self->stops[0].offset = 0;
|
|
||||||
self->stops[0].color = (GdkRGBA) { 1, 0, 0, 1 };
|
|
||||||
|
|
||||||
for (unsigned int i = 1; i < self->n_stops; i++)
|
|
||||||
{
|
|
||||||
GdkHSLA hsla;
|
|
||||||
|
|
||||||
self->stops[i].offset = i / (double)(self->n_stops - 1);
|
|
||||||
_gdk_hsla_init_from_rgba (&hsla, &self->stops[i - 1].color);
|
|
||||||
hsla.hue += 360.0 / (double)(self->n_stops - 1);
|
|
||||||
_gdk_rgba_init_from_hsla (&self->stops[i].color, &hsla);
|
|
||||||
}
|
|
||||||
|
|
||||||
self->layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), "123");
|
|
||||||
desc = pango_font_description_from_string ("Cantarell Bold 210");
|
|
||||||
pango_layout_set_font_description (self->layout, desc);
|
|
||||||
pango_font_description_free (desc);
|
|
||||||
|
|
||||||
self->tick = gtk_widget_add_tick_callback (GTK_WIDGET (self), rotate_colors, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo4_widget_dispose (GObject *object)
|
|
||||||
{
|
|
||||||
Demo4Widget *self = DEMO4_WIDGET (object);
|
|
||||||
|
|
||||||
g_clear_object (&self->layout);
|
|
||||||
gtk_widget_remove_tick_callback (GTK_WIDGET (self), self->tick);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (demo4_widget_parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo4_widget_snapshot_content (GtkWidget *widget,
|
|
||||||
GtkSnapshot *snapshot,
|
|
||||||
GskMaskMode mode)
|
|
||||||
{
|
|
||||||
Demo4Widget *self = DEMO4_WIDGET (widget);
|
|
||||||
int width, height, layout_width, layout_height;
|
|
||||||
double scale;
|
|
||||||
|
|
||||||
width = gtk_widget_get_width (widget);
|
|
||||||
height = gtk_widget_get_height (widget);
|
|
||||||
|
|
||||||
gtk_snapshot_push_mask (snapshot, mode);
|
|
||||||
pango_layout_get_pixel_size (self->layout, &layout_width, &layout_height);
|
|
||||||
scale = MIN ((double) width / layout_width, (double) height / layout_height);
|
|
||||||
gtk_snapshot_translate (snapshot,
|
|
||||||
&GRAPHENE_POINT_INIT ((width - scale * layout_width) / 2,
|
|
||||||
(height - scale * layout_height) / 2));
|
|
||||||
gtk_snapshot_scale (snapshot, scale, scale);
|
|
||||||
gtk_snapshot_append_layout (snapshot, self->layout, &(GdkRGBA) { 0, 0, 0, 1 });
|
|
||||||
gtk_snapshot_pop (snapshot);
|
|
||||||
|
|
||||||
gtk_snapshot_append_linear_gradient (snapshot,
|
|
||||||
&GRAPHENE_RECT_INIT (0, 0, width, height),
|
|
||||||
&GRAPHENE_POINT_INIT (0, 0),
|
|
||||||
&GRAPHENE_POINT_INIT (width, height),
|
|
||||||
self->stops,
|
|
||||||
self->n_stops);
|
|
||||||
gtk_snapshot_pop (snapshot);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo4_widget_snapshot (GtkWidget *widget,
|
|
||||||
GtkSnapshot *snapshot)
|
|
||||||
{
|
|
||||||
Demo4Widget *self = DEMO4_WIDGET (widget);
|
|
||||||
int width, height;
|
|
||||||
|
|
||||||
width = gtk_widget_get_width (widget);
|
|
||||||
height = gtk_widget_get_height (widget);
|
|
||||||
|
|
||||||
gtk_snapshot_push_mask (snapshot, GSK_MASK_MODE_INVERTED_LUMINANCE);
|
|
||||||
gtk_snapshot_append_linear_gradient (snapshot,
|
|
||||||
&GRAPHENE_RECT_INIT (0, 0, width, height),
|
|
||||||
&GRAPHENE_POINT_INIT (0, 0),
|
|
||||||
&GRAPHENE_POINT_INIT (width, 0),
|
|
||||||
(GskColorStop[2]) {
|
|
||||||
{ MAX (0.0, self->progress - 5.0 / width), { 1, 1, 1, 1 } },
|
|
||||||
{ MIN (1.0, self->progress + 5.0 / width), { 0, 0, 0, 1 } }
|
|
||||||
}, 2);
|
|
||||||
gtk_snapshot_pop (snapshot);
|
|
||||||
demo4_widget_snapshot_content (widget, snapshot, GSK_MASK_MODE_INVERTED_ALPHA);
|
|
||||||
gtk_snapshot_pop (snapshot);
|
|
||||||
|
|
||||||
gtk_snapshot_push_mask (snapshot, GSK_MASK_MODE_LUMINANCE);
|
|
||||||
gtk_snapshot_append_linear_gradient (snapshot,
|
|
||||||
&GRAPHENE_RECT_INIT (0, 0, width, height),
|
|
||||||
&GRAPHENE_POINT_INIT (0, 0),
|
|
||||||
&GRAPHENE_POINT_INIT (width, 0),
|
|
||||||
(GskColorStop[2]) {
|
|
||||||
{ MAX (0.0, self->progress - 5.0 / width), { 1, 1, 1, 1 } },
|
|
||||||
{ MIN (1.0, self->progress + 5.0 / width), { 0, 0, 0, 1 } }
|
|
||||||
}, 2);
|
|
||||||
gtk_snapshot_pop (snapshot);
|
|
||||||
demo4_widget_snapshot_content (widget, snapshot, GSK_MASK_MODE_ALPHA);
|
|
||||||
gtk_snapshot_pop (snapshot);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo4_widget_set_property (GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
const GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
Demo4Widget *self = DEMO4_WIDGET (object);
|
|
||||||
|
|
||||||
switch (prop_id)
|
|
||||||
{
|
|
||||||
case PROP_PROGRESS:
|
|
||||||
self->progress = g_value_get_double (value);
|
|
||||||
gtk_widget_queue_draw (GTK_WIDGET (object));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo4_widget_get_property (GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
Demo4Widget *self = DEMO4_WIDGET (object);
|
|
||||||
|
|
||||||
switch (prop_id)
|
|
||||||
{
|
|
||||||
case PROP_PROGRESS:
|
|
||||||
g_value_set_double (value, self->progress);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo4_widget_class_init (Demo4WidgetClass *class)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
|
||||||
|
|
||||||
object_class->dispose = demo4_widget_dispose;
|
|
||||||
object_class->get_property = demo4_widget_get_property;
|
|
||||||
object_class->set_property = demo4_widget_set_property;
|
|
||||||
|
|
||||||
widget_class->snapshot = demo4_widget_snapshot;
|
|
||||||
|
|
||||||
g_object_class_install_property (object_class, PROP_PROGRESS,
|
|
||||||
g_param_spec_double ("progress", NULL, NULL,
|
|
||||||
0.0, 1.0, 0.5,
|
|
||||||
G_PARAM_READWRITE));
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget *
|
|
||||||
demo4_widget_new (void)
|
|
||||||
{
|
|
||||||
return g_object_new (DEMO4_TYPE_WIDGET, NULL);
|
|
||||||
}
|
|
||||||
|
|
@@ -1,8 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
#define DEMO4_TYPE_WIDGET (demo4_widget_get_type ())
|
|
||||||
G_DECLARE_FINAL_TYPE (Demo4Widget, demo4_widget, DEMO4, WIDGET, GtkWidget)
|
|
||||||
|
|
||||||
GtkWidget * demo4_widget_new (void);
|
|
@@ -18,7 +18,8 @@
|
|||||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#ifndef __DEMO_TAGGED_ENTRY_H__
|
||||||
|
#define __DEMO_TAGGED_ENTRY_H__
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
@@ -56,3 +57,5 @@ void demo_tagged_entry_tag_set_has_close_button (DemoTaggedEntryTag *
|
|||||||
gboolean has_close_button);
|
gboolean has_close_button);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __DEMO_TAGGED_ENTRY_H__ */
|
||||||
|
@@ -34,7 +34,7 @@ transition (GtkWidget *widget,
|
|||||||
{
|
{
|
||||||
DemoWidget *self = DEMO_WIDGET (widget);
|
DemoWidget *self = DEMO_WIDGET (widget);
|
||||||
DemoLayout *demo_layout = DEMO_LAYOUT (gtk_widget_get_layout_manager (widget));
|
DemoLayout *demo_layout = DEMO_LAYOUT (gtk_widget_get_layout_manager (widget));
|
||||||
gint64 now = gdk_frame_clock_get_frame_time (frame_clock);
|
gint64 now = g_get_monotonic_time ();
|
||||||
|
|
||||||
gtk_widget_queue_allocate (widget);
|
gtk_widget_queue_allocate (widget);
|
||||||
|
|
||||||
@@ -66,13 +66,11 @@ clicked (GtkGestureClick *gesture,
|
|||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
DemoWidget *self = data;
|
DemoWidget *self = data;
|
||||||
GdkFrameClock *frame_clock;
|
|
||||||
|
|
||||||
if (self->tick_id != 0)
|
if (self->tick_id != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
|
self->start_time = g_get_monotonic_time ();
|
||||||
self->start_time = gdk_frame_clock_get_frame_time (frame_clock);
|
|
||||||
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self), transition, NULL, NULL);
|
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self), transition, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,8 +8,6 @@
|
|||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
||||||
|
|
||||||
static GtkWidget *window = NULL;
|
static GtkWidget *window = NULL;
|
||||||
static GtkWidget *entry1 = NULL;
|
static GtkWidget *entry1 = NULL;
|
||||||
static GtkWidget *entry2 = NULL;
|
static GtkWidget *entry2 = NULL;
|
||||||
@@ -29,7 +27,7 @@ message_dialog_clicked (GtkButton *button,
|
|||||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||||
ngettext ("Has been shown once", "Has been shown %d times", i), i);
|
ngettext ("Has been shown once", "Has been shown %d times", i), i);
|
||||||
g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
|
g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
|
||||||
gtk_window_present (GTK_WINDOW (dialog));
|
gtk_widget_show (dialog);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +114,7 @@ interactive_dialog_clicked (GtkButton *button,
|
|||||||
data, (GClosureNotify) g_free,
|
data, (GClosureNotify) g_free,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
gtk_window_present (GTK_WINDOW (dialog));
|
gtk_widget_show (dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
@@ -186,7 +184,7 @@ do_dialog (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (CanvasItem, canvas_item, CANVAS, ITEM, GtkWidget)
|
G_DECLARE_FINAL_TYPE (CanvasItem, canvas_item, CANVAS, ITEM, GtkWidget)
|
||||||
|
|
||||||
struct _CanvasItem {
|
struct _CanvasItem {
|
||||||
@@ -25,9 +24,6 @@ struct _CanvasItem {
|
|||||||
double delta;
|
double delta;
|
||||||
|
|
||||||
GtkWidget *editor;
|
GtkWidget *editor;
|
||||||
|
|
||||||
GtkStyleProvider *provider;
|
|
||||||
char *css_class;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _CanvasItemClass {
|
struct _CanvasItemClass {
|
||||||
@@ -38,41 +34,32 @@ G_DEFINE_TYPE (CanvasItem, canvas_item, GTK_TYPE_WIDGET)
|
|||||||
|
|
||||||
static int n_items = 0;
|
static int n_items = 0;
|
||||||
|
|
||||||
static void
|
|
||||||
unstyle_item (CanvasItem *item)
|
|
||||||
{
|
|
||||||
if (item->provider)
|
|
||||||
{
|
|
||||||
gtk_style_context_remove_provider_for_display (gtk_widget_get_display (item->label), item->provider);
|
|
||||||
g_clear_object (&item->provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item->css_class)
|
|
||||||
{
|
|
||||||
gtk_widget_remove_css_class (item->label, item->css_class);
|
|
||||||
g_clear_pointer (&item->css_class, g_free);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_color (CanvasItem *item,
|
set_color (CanvasItem *item,
|
||||||
GdkRGBA *color)
|
GdkRGBA *color)
|
||||||
{
|
{
|
||||||
char *css;
|
char *css;
|
||||||
char *str;
|
char *str;
|
||||||
|
GtkStyleContext *context;
|
||||||
GtkCssProvider *provider;
|
GtkCssProvider *provider;
|
||||||
const char *name;
|
const char *old_class;
|
||||||
|
|
||||||
unstyle_item (item);
|
|
||||||
|
|
||||||
str = gdk_rgba_to_string (color);
|
str = gdk_rgba_to_string (color);
|
||||||
name = gtk_widget_get_name (item->label);
|
css = g_strdup_printf ("* { background: %s; }", str);
|
||||||
css = g_strdup_printf ("#%s { background: %s; }", name, str);
|
|
||||||
|
context = gtk_widget_get_style_context (item->label);
|
||||||
|
provider = g_object_get_data (G_OBJECT (context), "style-provider");
|
||||||
|
if (provider)
|
||||||
|
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
|
||||||
|
|
||||||
|
old_class = (const char *)g_object_get_data (G_OBJECT (item->label), "css-class");
|
||||||
|
if (old_class)
|
||||||
|
gtk_widget_remove_css_class (item->label, old_class);
|
||||||
|
|
||||||
provider = gtk_css_provider_new ();
|
provider = gtk_css_provider_new ();
|
||||||
gtk_css_provider_load_from_string (provider, css);
|
gtk_css_provider_load_from_data (provider, css, -1);
|
||||||
gtk_style_context_add_provider_for_display (gtk_widget_get_display (item->label), GTK_STYLE_PROVIDER (provider), 700);
|
gtk_style_context_add_provider (gtk_widget_get_style_context (item->label), GTK_STYLE_PROVIDER (provider), 800);
|
||||||
item->provider = GTK_STYLE_PROVIDER (provider);
|
g_object_set_data_full (G_OBJECT (context), "style-provider", provider, g_object_unref);
|
||||||
|
|
||||||
g_free (str);
|
g_free (str);
|
||||||
g_free (css);
|
g_free (css);
|
||||||
@@ -82,10 +69,21 @@ static void
|
|||||||
set_css (CanvasItem *item,
|
set_css (CanvasItem *item,
|
||||||
const char *class)
|
const char *class)
|
||||||
{
|
{
|
||||||
unstyle_item (item);
|
GtkStyleContext *context;
|
||||||
|
GtkCssProvider *provider;
|
||||||
|
const char *old_class;
|
||||||
|
|
||||||
|
context = gtk_widget_get_style_context (item->label);
|
||||||
|
provider = g_object_get_data (G_OBJECT (context), "style-provider");
|
||||||
|
if (provider)
|
||||||
|
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
|
||||||
|
|
||||||
|
old_class = (const char *)g_object_get_data (G_OBJECT (item->label), "css-class");
|
||||||
|
if (old_class)
|
||||||
|
gtk_widget_remove_css_class (item->label, old_class);
|
||||||
|
|
||||||
|
g_object_set_data_full (G_OBJECT (item->label), "css-class", g_strdup (class), g_free);
|
||||||
gtk_widget_add_css_class (item->label, class);
|
gtk_widget_add_css_class (item->label, class);
|
||||||
item->css_class = g_strdup (class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -109,21 +107,15 @@ static void
|
|||||||
apply_transform (CanvasItem *item)
|
apply_transform (CanvasItem *item)
|
||||||
{
|
{
|
||||||
GskTransform *transform;
|
GskTransform *transform;
|
||||||
graphene_rect_t bounds;
|
|
||||||
double x, y;
|
double x, y;
|
||||||
|
|
||||||
/* Add css padding and margin */
|
x = gtk_widget_get_allocated_width (item->label) / 2.0;
|
||||||
if (!gtk_widget_compute_bounds (item->label, item->label, &bounds))
|
y = gtk_widget_get_allocated_height (item->label) / 2.0;
|
||||||
return;
|
item->r = sqrt (x*x + y*y);
|
||||||
|
|
||||||
x = bounds.size.width / 2.;
|
|
||||||
y = bounds.size.height / 2.;
|
|
||||||
|
|
||||||
item->r = sqrt (x * x + y * y);
|
|
||||||
|
|
||||||
transform = gsk_transform_translate (NULL, &(graphene_point_t) { item->r, item->r });
|
transform = gsk_transform_translate (NULL, &(graphene_point_t) { item->r, item->r });
|
||||||
transform = gsk_transform_rotate (transform, item->angle + item->delta);
|
transform = gsk_transform_rotate (transform, item->angle + item->delta);
|
||||||
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (-x, -y));
|
transform = gsk_transform_translate (transform, &(graphene_point_t) { -x, -y });
|
||||||
|
|
||||||
gtk_fixed_set_child_transform (GTK_FIXED (item->fixed), item->label, transform);
|
gtk_fixed_set_child_transform (GTK_FIXED (item->fixed), item->label, transform);
|
||||||
gsk_transform_unref (transform);
|
gsk_transform_unref (transform);
|
||||||
@@ -162,39 +154,27 @@ click_done (GtkGesture *gesture)
|
|||||||
gtk_widget_insert_after (item, canvas, last_child);
|
gtk_widget_insert_after (item, canvas, last_child);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GtkSettings treats `GTK_THEME=foo:dark` as theme name `foo`, variant `dark`,
|
|
||||||
* and our embedded CSS files let `foo-dark` work as an alias for `foo:dark`. */
|
|
||||||
static gboolean
|
|
||||||
has_dark_suffix (const char *theme)
|
|
||||||
{
|
|
||||||
return g_str_has_suffix (theme, ":dark") ||
|
|
||||||
g_str_has_suffix (theme, "-dark");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* So we can make a good guess whether the current theme is dark by checking for
|
|
||||||
* either: it is suffixed `[:-]dark`, or Settings:…prefer-dark-theme is TRUE. */
|
|
||||||
static gboolean
|
static gboolean
|
||||||
theme_is_dark (void)
|
theme_is_dark (void)
|
||||||
{
|
{
|
||||||
const char *env_theme;
|
|
||||||
GtkSettings *settings;
|
GtkSettings *settings;
|
||||||
char *theme;
|
char *theme;
|
||||||
gboolean prefer_dark;
|
gboolean prefer_dark;
|
||||||
gboolean dark;
|
gboolean dark;
|
||||||
|
|
||||||
/* Like GtkSettings, 1st see if theme is overridden by environment variable */
|
|
||||||
env_theme = g_getenv ("GTK_THEME");
|
|
||||||
if (env_theme != NULL)
|
|
||||||
return has_dark_suffix (env_theme);
|
|
||||||
|
|
||||||
/* If not, test Settings:…theme-name in the same way OR :…prefer-dark-theme */
|
|
||||||
settings = gtk_settings_get_default ();
|
settings = gtk_settings_get_default ();
|
||||||
g_object_get (settings,
|
g_object_get (settings,
|
||||||
"gtk-theme-name", &theme,
|
"gtk-theme-name", &theme,
|
||||||
"gtk-application-prefer-dark-theme", &prefer_dark,
|
"gtk-application-prefer-dark-theme", &prefer_dark,
|
||||||
NULL);
|
NULL);
|
||||||
dark = prefer_dark || has_dark_suffix (theme);
|
|
||||||
|
if ((strcmp (theme, "Adwaita") == 0 && prefer_dark) || strcmp (theme, "HighContrastInverse") == 0)
|
||||||
|
dark = TRUE;
|
||||||
|
else
|
||||||
|
dark = FALSE;
|
||||||
|
|
||||||
g_free (theme);
|
g_free (theme);
|
||||||
|
|
||||||
return dark;
|
return dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +322,7 @@ canvas_item_start_editing (CanvasItem *item)
|
|||||||
GtkWidget *canvas = gtk_widget_get_parent (GTK_WIDGET (item));
|
GtkWidget *canvas = gtk_widget_get_parent (GTK_WIDGET (item));
|
||||||
GtkWidget *entry;
|
GtkWidget *entry;
|
||||||
GtkWidget *scale;
|
GtkWidget *scale;
|
||||||
graphene_point_t p;
|
double x, y;
|
||||||
|
|
||||||
if (item->editor)
|
if (item->editor)
|
||||||
return;
|
return;
|
||||||
@@ -368,17 +348,12 @@ canvas_item_start_editing (CanvasItem *item)
|
|||||||
|
|
||||||
gtk_box_append (GTK_BOX (item->editor), scale);
|
gtk_box_append (GTK_BOX (item->editor), scale);
|
||||||
|
|
||||||
if (!gtk_widget_compute_point (GTK_WIDGET (item), canvas, &GRAPHENE_POINT_INIT (0, 0), &p))
|
gtk_widget_translate_coordinates (GTK_WIDGET (item), canvas, 0, 0, &x, &y);
|
||||||
graphene_point_init (&p, 0, 0);
|
gtk_fixed_put (GTK_FIXED (canvas), item->editor, x, y + 2 * item->r);
|
||||||
gtk_fixed_put (GTK_FIXED (canvas), item->editor, p.x, p.y + 2 * item->r);
|
|
||||||
gtk_widget_grab_focus (entry);
|
gtk_widget_grab_focus (entry);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
double x, y;
|
|
||||||
} Hotspot;
|
|
||||||
|
|
||||||
static GdkContentProvider *
|
static GdkContentProvider *
|
||||||
prepare (GtkDragSource *source,
|
prepare (GtkDragSource *source,
|
||||||
double x,
|
double x,
|
||||||
@@ -386,8 +361,6 @@ prepare (GtkDragSource *source,
|
|||||||
{
|
{
|
||||||
GtkWidget *canvas;
|
GtkWidget *canvas;
|
||||||
GtkWidget *item;
|
GtkWidget *item;
|
||||||
Hotspot *hotspot;
|
|
||||||
graphene_point_t p;
|
|
||||||
|
|
||||||
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
||||||
item = gtk_widget_pick (canvas, x, y, GTK_PICK_DEFAULT);
|
item = gtk_widget_pick (canvas, x, y, GTK_PICK_DEFAULT);
|
||||||
@@ -398,13 +371,6 @@ prepare (GtkDragSource *source,
|
|||||||
|
|
||||||
g_object_set_data (G_OBJECT (canvas), "dragged-item", item);
|
g_object_set_data (G_OBJECT (canvas), "dragged-item", item);
|
||||||
|
|
||||||
hotspot = g_new (Hotspot, 1);
|
|
||||||
if (!gtk_widget_compute_point (canvas, item, &GRAPHENE_POINT_INIT (x, y), &p))
|
|
||||||
graphene_point_init (&p, x, y);
|
|
||||||
hotspot->x = p.x;
|
|
||||||
hotspot->y = p.y;
|
|
||||||
g_object_set_data_full (G_OBJECT (canvas), "hotspot", hotspot, g_free);
|
|
||||||
|
|
||||||
return gdk_content_provider_new_typed (GTK_TYPE_WIDGET, item);
|
return gdk_content_provider_new_typed (GTK_TYPE_WIDGET, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,14 +381,12 @@ drag_begin (GtkDragSource *source,
|
|||||||
GtkWidget *canvas;
|
GtkWidget *canvas;
|
||||||
CanvasItem *item;
|
CanvasItem *item;
|
||||||
GdkPaintable *paintable;
|
GdkPaintable *paintable;
|
||||||
Hotspot *hotspot;
|
|
||||||
|
|
||||||
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
||||||
item = CANVAS_ITEM (g_object_get_data (G_OBJECT (canvas), "dragged-item"));
|
item = CANVAS_ITEM (g_object_get_data (G_OBJECT (canvas), "dragged-item"));
|
||||||
hotspot = (Hotspot *) g_object_get_data (G_OBJECT (canvas), "hotspot");
|
|
||||||
|
|
||||||
paintable = canvas_item_get_drag_icon (item);
|
paintable = canvas_item_get_drag_icon (item);
|
||||||
gtk_drag_source_set_icon (source, paintable, hotspot->x, hotspot->y);
|
gtk_drag_source_set_icon (source, paintable, item->r, item->r);
|
||||||
g_object_unref (paintable);
|
g_object_unref (paintable);
|
||||||
|
|
||||||
gtk_widget_set_opacity (GTK_WIDGET (item), 0.3);
|
gtk_widget_set_opacity (GTK_WIDGET (item), 0.3);
|
||||||
@@ -758,9 +722,8 @@ do_dnd (GtkWidget *do_widget)
|
|||||||
int i;
|
int i;
|
||||||
int x, y;
|
int x, y;
|
||||||
GtkCssProvider *provider;
|
GtkCssProvider *provider;
|
||||||
GString *css;
|
|
||||||
|
|
||||||
button = gtk_color_dialog_button_new (gtk_color_dialog_new ());
|
button = gtk_color_button_new ();
|
||||||
g_object_unref (g_object_ref_sink (button));
|
g_object_unref (g_object_ref_sink (button));
|
||||||
|
|
||||||
provider = gtk_css_provider_new ();
|
provider = gtk_css_provider_new ();
|
||||||
@@ -770,18 +733,6 @@ do_dnd (GtkWidget *do_widget)
|
|||||||
800);
|
800);
|
||||||
g_object_unref (provider);
|
g_object_unref (provider);
|
||||||
|
|
||||||
css = g_string_new ("");
|
|
||||||
for (i = 0; colors[i]; i++)
|
|
||||||
g_string_append_printf (css, ".canvasitem.%s { background: %s; }\n", colors[i], colors[i]);
|
|
||||||
|
|
||||||
provider = gtk_css_provider_new ();
|
|
||||||
gtk_css_provider_load_from_string (provider, css->str);
|
|
||||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
|
||||||
GTK_STYLE_PROVIDER (provider),
|
|
||||||
800);
|
|
||||||
g_object_unref (provider);
|
|
||||||
g_string_free (css, TRUE);
|
|
||||||
|
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new ();
|
||||||
gtk_window_set_display (GTK_WINDOW (window),
|
gtk_window_set_display (GTK_WINDOW (window),
|
||||||
gtk_widget_get_display (do_widget));
|
gtk_widget_get_display (do_widget));
|
||||||
@@ -834,7 +785,7 @@ do_dnd (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -334,17 +334,11 @@ do_drawingarea (GtkWidget *do_widget)
|
|||||||
gtk_widget_set_vexpand (frame, TRUE);
|
gtk_widget_set_vexpand (frame, TRUE);
|
||||||
gtk_box_append (GTK_BOX (vbox), frame);
|
gtk_box_append (GTK_BOX (vbox), frame);
|
||||||
|
|
||||||
da = g_object_new (GTK_TYPE_DRAWING_AREA,
|
da = gtk_drawing_area_new ();
|
||||||
"accessible-role", GTK_ACCESSIBLE_ROLE_IMG,
|
|
||||||
NULL);
|
|
||||||
gtk_frame_set_child (GTK_FRAME (frame), da);
|
|
||||||
gtk_accessible_update_relation (GTK_ACCESSIBLE (da),
|
|
||||||
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
|
|
||||||
-1);
|
|
||||||
|
|
||||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
|
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
|
||||||
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 100);
|
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 100);
|
||||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), groups_draw, NULL, NULL);
|
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), groups_draw, NULL, NULL);
|
||||||
|
gtk_frame_set_child (GTK_FRAME (frame), da);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the scribble area
|
* Create the scribble area
|
||||||
@@ -358,23 +352,17 @@ do_drawingarea (GtkWidget *do_widget)
|
|||||||
gtk_widget_set_vexpand (frame, TRUE);
|
gtk_widget_set_vexpand (frame, TRUE);
|
||||||
gtk_box_append (GTK_BOX (vbox), frame);
|
gtk_box_append (GTK_BOX (vbox), frame);
|
||||||
|
|
||||||
da = g_object_new (GTK_TYPE_DRAWING_AREA,
|
da = gtk_drawing_area_new ();
|
||||||
"accessible-role", GTK_ACCESSIBLE_ROLE_IMG,
|
|
||||||
NULL);
|
|
||||||
gtk_frame_set_child (GTK_FRAME (frame), da);
|
|
||||||
gtk_accessible_update_relation (GTK_ACCESSIBLE (da),
|
|
||||||
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
|
|
||||||
-1);
|
|
||||||
|
|
||||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
|
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
|
||||||
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 100);
|
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 100);
|
||||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), scribble_draw, NULL, NULL);
|
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), scribble_draw, NULL, NULL);
|
||||||
|
gtk_frame_set_child (GTK_FRAME (frame), da);
|
||||||
|
|
||||||
g_signal_connect (da, "resize",
|
g_signal_connect (da, "resize",
|
||||||
G_CALLBACK (scribble_resize), NULL);
|
G_CALLBACK (scribble_resize), NULL);
|
||||||
|
|
||||||
drag = gtk_gesture_drag_new ();
|
drag = gtk_gesture_drag_new ();
|
||||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), 0);
|
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), GDK_BUTTON_PRIMARY);
|
||||||
gtk_widget_add_controller (da, GTK_EVENT_CONTROLLER (drag));
|
gtk_widget_add_controller (da, GTK_EVENT_CONTROLLER (drag));
|
||||||
|
|
||||||
g_signal_connect (drag, "drag-begin", G_CALLBACK (drag_begin), da);
|
g_signal_connect (drag, "drag-begin", G_CALLBACK (drag_begin), da);
|
||||||
@@ -384,7 +372,7 @@ do_drawingarea (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_window_present (GTK_WINDOW (window));
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
/* Lists/Selections
|
/* Lists/Selections
|
||||||
* #Keywords: suggestion, completion
|
|
||||||
*
|
*
|
||||||
* The GtkDropDown widget is a modern alternative to GtkComboBox.
|
* The GtkDropDown widget is a modern alternative to GtkComboBox.
|
||||||
* It uses list models instead of tree models, and the content is
|
* It uses list models instead of tree models, and the content is
|
||||||
@@ -165,14 +164,14 @@ strings_bind_item (GtkSignalListItemFactory *factory,
|
|||||||
popup = gtk_widget_get_ancestor (title, GTK_TYPE_POPOVER);
|
popup = gtk_widget_get_ancestor (title, GTK_TYPE_POPOVER);
|
||||||
if (popup && gtk_widget_is_ancestor (popup, GTK_WIDGET (dropdown)))
|
if (popup && gtk_widget_is_ancestor (popup, GTK_WIDGET (dropdown)))
|
||||||
{
|
{
|
||||||
gtk_widget_set_visible (checkmark, TRUE);
|
gtk_widget_show (checkmark);
|
||||||
g_signal_connect (dropdown, "notify::selected-item",
|
g_signal_connect (dropdown, "notify::selected-item",
|
||||||
G_CALLBACK (selected_item_changed), item);
|
G_CALLBACK (selected_item_changed), item);
|
||||||
selected_item_changed (dropdown, NULL, item);
|
selected_item_changed (dropdown, NULL, item);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gtk_widget_set_visible (checkmark, FALSE);
|
gtk_widget_hide (checkmark);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,40 +368,8 @@ match_func (MatchObject *obj,
|
|||||||
g_free (tmp2);
|
g_free (tmp2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
setup_header (GtkSignalListItemFactory *factory,
|
|
||||||
GObject *list_item,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
GtkListHeader *self = GTK_LIST_HEADER (list_item);
|
|
||||||
GtkWidget *child;
|
|
||||||
|
|
||||||
child = gtk_label_new ("");
|
|
||||||
gtk_label_set_xalign (GTK_LABEL (child), 0);
|
|
||||||
gtk_label_set_use_markup (GTK_LABEL (child), TRUE);
|
|
||||||
gtk_widget_set_margin_top (child, 10);
|
|
||||||
gtk_widget_set_margin_bottom (child, 10);
|
|
||||||
|
|
||||||
gtk_list_header_set_child (self, child);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
bind_header (GtkSignalListItemFactory *factory,
|
|
||||||
GObject *list_item,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
GtkListHeader *self = GTK_LIST_HEADER (list_item);
|
|
||||||
GtkWidget *child = gtk_list_header_get_child (self);
|
|
||||||
GObject *item = gtk_list_header_get_item (self);
|
|
||||||
|
|
||||||
if (strstr (gtk_string_object_get_string (GTK_STRING_OBJECT (item)), "hour"))
|
|
||||||
gtk_label_set_label (GTK_LABEL (child), "<big><b>Hours</b></big>");
|
|
||||||
else
|
|
||||||
gtk_label_set_label (GTK_LABEL (child), "<big><b>Minutes</b></big>");
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
do_listview_selections (GtkWidget *do_widget)
|
do_dropdown (GtkWidget *do_widget)
|
||||||
{
|
{
|
||||||
static GtkWidget *window = NULL;
|
static GtkWidget *window = NULL;
|
||||||
GtkWidget *button, *box, *spin, *check, *hbox, *label, *entry;
|
GtkWidget *button, *box, *spin, *check, *hbox, *label, *entry;
|
||||||
@@ -410,12 +377,10 @@ do_listview_selections (GtkWidget *do_widget)
|
|||||||
GtkExpression *expression;
|
GtkExpression *expression;
|
||||||
GtkListItemFactory *factory;
|
GtkListItemFactory *factory;
|
||||||
const char * const times[] = { "1 minute", "2 minutes", "5 minutes", "20 minutes", NULL };
|
const char * const times[] = { "1 minute", "2 minutes", "5 minutes", "20 minutes", NULL };
|
||||||
const char * const minutes[] = {
|
const char * const many_times[] = {
|
||||||
"1 minute", "2 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes",
|
"1 minute", "2 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes",
|
||||||
"25 minutes", "30 minutes", "35 minutes", "40 minutes", "45 minutes", "50 minutes",
|
"25 minutes", "30 minutes", "35 minutes", "40 minutes", "45 minutes", "50 minutes",
|
||||||
"55 minutes", NULL
|
"55 minutes", "1 hour", "2 hours", "3 hours", "5 hours", "6 hours", "7 hours",
|
||||||
};
|
|
||||||
const char * const hours[] = { "1 hour", "2 hours", "3 hours", "5 hours", "6 hours", "7 hours",
|
|
||||||
"8 hours", "9 hours", "10 hours", "11 hours", "12 hours", NULL
|
"8 hours", "9 hours", "10 hours", "11 hours", "12 hours", NULL
|
||||||
};
|
};
|
||||||
const char * const device_titles[] = { "Digital Output", "Headphones", "Digital Output", "Analog Output", NULL };
|
const char * const device_titles[] = { "Digital Output", "Headphones", "Digital Output", "Analog Output", NULL };
|
||||||
@@ -430,10 +395,6 @@ do_listview_selections (GtkWidget *do_widget)
|
|||||||
|
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
GtkStringList *minutes_model, *hours_model;
|
|
||||||
GListStore *store;
|
|
||||||
GtkFlattenListModel *flat;
|
|
||||||
|
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new ();
|
||||||
gtk_window_set_display (GTK_WINDOW (window),
|
gtk_window_set_display (GTK_WINDOW (window),
|
||||||
gtk_widget_get_display (do_widget));
|
gtk_widget_get_display (do_widget));
|
||||||
@@ -461,25 +422,14 @@ do_listview_selections (GtkWidget *do_widget)
|
|||||||
gtk_box_append (GTK_BOX (box), button);
|
gtk_box_append (GTK_BOX (box), button);
|
||||||
|
|
||||||
/* A dropdown using an expression to obtain strings */
|
/* A dropdown using an expression to obtain strings */
|
||||||
minutes_model = gtk_string_list_new (minutes);
|
button = drop_down_new_from_strings (many_times, NULL, NULL);
|
||||||
hours_model = gtk_string_list_new (hours);
|
gtk_drop_down_set_enable_search (GTK_DROP_DOWN (button), TRUE);
|
||||||
store = g_list_store_new (G_TYPE_LIST_MODEL);
|
|
||||||
g_list_store_append (store, minutes_model);
|
|
||||||
g_list_store_append (store, hours_model);
|
|
||||||
g_object_unref (minutes_model);
|
|
||||||
g_object_unref (hours_model);
|
|
||||||
flat = gtk_flatten_list_model_new (G_LIST_MODEL (store));
|
|
||||||
expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
|
expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
|
||||||
0, NULL,
|
0, NULL,
|
||||||
(GCallback)get_title,
|
(GCallback)get_title,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
button = gtk_drop_down_new (G_LIST_MODEL (flat), expression);
|
gtk_drop_down_set_expression (GTK_DROP_DOWN (button), expression);
|
||||||
gtk_drop_down_set_enable_search (GTK_DROP_DOWN (button), TRUE);
|
gtk_expression_unref (expression);
|
||||||
factory = gtk_signal_list_item_factory_new ();
|
|
||||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_header), NULL);
|
|
||||||
g_signal_connect (factory, "bind", G_CALLBACK (bind_header), NULL);
|
|
||||||
gtk_drop_down_set_header_factory (GTK_DROP_DOWN (button), factory);
|
|
||||||
g_object_unref (factory);
|
|
||||||
gtk_box_append (GTK_BOX (box), button);
|
gtk_box_append (GTK_BOX (box), button);
|
||||||
|
|
||||||
button = gtk_drop_down_new (NULL, NULL);
|
button = gtk_drop_down_new (NULL, NULL);
|
||||||
@@ -613,7 +563,7 @@ do_listview_selections (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
@@ -14,8 +14,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int number;
|
int number;
|
||||||
@@ -409,7 +407,7 @@ do_editable_cells (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|
@@ -8,8 +8,6 @@
|
|||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
||||||
|
|
||||||
/* Creates a tree model containing the completions */
|
/* Creates a tree model containing the completions */
|
||||||
static GtkTreeModel *
|
static GtkTreeModel *
|
||||||
create_completion_model (void)
|
create_completion_model (void)
|
||||||
@@ -95,13 +93,6 @@ do_entry_completion (GtkWidget *do_widget)
|
|||||||
entry = gtk_entry_new ();
|
entry = gtk_entry_new ();
|
||||||
gtk_box_append (GTK_BOX (vbox), entry);
|
gtk_box_append (GTK_BOX (vbox), entry);
|
||||||
|
|
||||||
gtk_accessible_update_relation (GTK_ACCESSIBLE (entry),
|
|
||||||
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
|
|
||||||
-1);
|
|
||||||
gtk_accessible_update_property (GTK_ACCESSIBLE (entry),
|
|
||||||
GTK_ACCESSIBLE_PROPERTY_AUTOCOMPLETE, GTK_ACCESSIBLE_AUTOCOMPLETE_LIST,
|
|
||||||
-1);
|
|
||||||
|
|
||||||
/* Create the completion object */
|
/* Create the completion object */
|
||||||
completion = gtk_entry_completion_new ();
|
completion = gtk_entry_completion_new ();
|
||||||
|
|
||||||
@@ -122,7 +113,7 @@ do_entry_completion (GtkWidget *do_widget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_set_visible (window, TRUE);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_window_destroy (GTK_WINDOW (window));
|
||||||
|
|
||||||
|