Compare commits
5 Commits
tree-list-
...
font-rende
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e00d393b6a | ||
|
|
4a87115763 | ||
|
|
273d60fefa | ||
|
|
e781f986f7 | ||
|
|
40b90a16ab |
@@ -1,11 +0,0 @@
|
|||||||
# See https://wiki.apertis.org/Guidelines/Coding_conventions#Code_formatting
|
|
||||||
BasedOnStyle: GNU
|
|
||||||
AlwaysBreakAfterDefinitionReturnType: All
|
|
||||||
BreakBeforeBinaryOperators: None
|
|
||||||
BinPackParameters: false
|
|
||||||
SpaceAfterCStyleCast: true
|
|
||||||
# Our column limit is actually 80, but setting that results in clang-format
|
|
||||||
# making a lot of dubious hanging-indent choices; disable it and assume the
|
|
||||||
# developer will line wrap appropriately. clang-format will still check
|
|
||||||
# existing hanging indents.
|
|
||||||
ColumnLimit: 0
|
|
||||||
1
.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
/subprojects/*/
|
|
||||||
203
.gitlab-ci.yml
@@ -1,7 +1,5 @@
|
|||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
- analysis
|
|
||||||
- docs
|
|
||||||
- flatpak
|
- flatpak
|
||||||
- deploy
|
- deploy
|
||||||
|
|
||||||
@@ -14,111 +12,40 @@ stages:
|
|||||||
- subprojects/libepoxy/
|
- subprojects/libepoxy/
|
||||||
- subprojects/pango/
|
- subprojects/pango/
|
||||||
|
|
||||||
# Common variables
|
fedora-x86_64:
|
||||||
variables:
|
image: registry.gitlab.gnome.org/gnome/gtk/master:v1
|
||||||
COMMON_MESON_FLAGS: "--fatal-meson-warnings --werror"
|
stage: build
|
||||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true -Dvulkan=yes"
|
|
||||||
FEATURE_FLAGS: "-Dcloudproviders=true"
|
|
||||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
|
||||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v20"
|
|
||||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
|
||||||
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v19"
|
|
||||||
|
|
||||||
.only-default:
|
|
||||||
only:
|
|
||||||
- branches
|
|
||||||
except:
|
|
||||||
- tags
|
|
||||||
|
|
||||||
style-check-diff:
|
|
||||||
extends: .only-default
|
|
||||||
image: $FEDORA_IMAGE
|
|
||||||
stage: .pre
|
|
||||||
allow_failure: true
|
|
||||||
script:
|
script:
|
||||||
- .gitlab-ci/run-style-check-diff.sh
|
- bash -x ./.gitlab-ci/test-docker.sh
|
||||||
|
|
||||||
.build-fedora-default:
|
|
||||||
image: $FEDORA_IMAGE
|
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
when: on_failure
|
||||||
reports:
|
|
||||||
junit:
|
|
||||||
- "${CI_PROJECT_DIR}/_build/report-x11.xml"
|
|
||||||
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
|
|
||||||
- "${CI_PROJECT_DIR}/_build/report-broadway.xml"
|
|
||||||
name: "gtk-${CI_COMMIT_REF_NAME}"
|
name: "gtk-${CI_COMMIT_REF_NAME}"
|
||||||
paths:
|
paths:
|
||||||
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
||||||
- "${CI_PROJECT_DIR}/_build/report*.xml"
|
|
||||||
- "${CI_PROJECT_DIR}/_build/report*.html"
|
|
||||||
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.png"
|
|
||||||
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
|
|
||||||
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
|
|
||||||
cache:
|
cache:
|
||||||
key: "$CI_JOB_NAME"
|
key: "$CI_JOB_NAME"
|
||||||
paths:
|
<<: *cache-paths
|
||||||
- _ccache/
|
|
||||||
- subprojects/gdk-pixbuf/
|
|
||||||
- subprojects/glib/
|
|
||||||
- subprojects/graphene/
|
|
||||||
- subprojects/libepoxy/
|
|
||||||
- subprojects/pango/
|
|
||||||
|
|
||||||
fedora-x86_64:
|
.mingw-defaults: &mingw-defaults
|
||||||
extends: .build-fedora-default
|
|
||||||
stage: build
|
|
||||||
variables:
|
|
||||||
EXTRA_MESON_FLAGS: "--buildtype=debug --default-library=both"
|
|
||||||
script:
|
|
||||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
|
||||||
-Dprofiler=true
|
|
||||||
_build
|
|
||||||
- ninja -C _build
|
|
||||||
- .gitlab-ci/run-tests.sh _build x11
|
|
||||||
- .gitlab-ci/run-tests.sh _build wayland
|
|
||||||
- .gitlab-ci/run-tests.sh _build broadway
|
|
||||||
|
|
||||||
release-build:
|
|
||||||
extends: .build-fedora-default
|
|
||||||
stage: build
|
|
||||||
variables:
|
|
||||||
EXTRA_MESON_FLAGS: "--buildtype=release"
|
|
||||||
script:
|
|
||||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
|
||||||
_build
|
|
||||||
- ninja -C _build
|
|
||||||
- .gitlab-ci/run-tests.sh _build x11
|
|
||||||
|
|
||||||
.mingw-defaults:
|
|
||||||
stage: build
|
stage: build
|
||||||
tags:
|
tags:
|
||||||
- win32-ps
|
- win32
|
||||||
script:
|
script:
|
||||||
- C:\msys64\usr\bin\pacman --noconfirm -Syyuu
|
- C:\msys64\usr\bin\pacman --noconfirm -Syyuu
|
||||||
- C:\msys64\usr\bin\bash -lc "bash -x ./.gitlab-ci/test-msys2.sh"
|
- C:\msys64\usr\bin\bash -lc "bash -x ./.gitlab-ci/test-msys2.sh"
|
||||||
cache:
|
cache:
|
||||||
key: "$CI_JOB_NAME"
|
key: "%CI_JOB_NAME%"
|
||||||
paths:
|
<<: *cache-paths
|
||||||
- _ccache/
|
|
||||||
- subprojects/gdk-pixbuf/
|
|
||||||
- subprojects/glib/
|
|
||||||
- subprojects/graphene/
|
|
||||||
- subprojects/libepoxy/
|
|
||||||
- subprojects/pango/
|
|
||||||
|
|
||||||
msys2-mingw64:
|
msys2-mingw32:
|
||||||
extends: .mingw-defaults
|
|
||||||
variables:
|
variables:
|
||||||
MSYSTEM: "MINGW64"
|
MSYSTEM: "MINGW32"
|
||||||
CHERE_INVOKING: "yes"
|
CHERE_INVOKING: "yes"
|
||||||
|
<<: *mingw-defaults
|
||||||
|
|
||||||
.flatpak-defaults:
|
.flatpak-defaults: &flatpak-defaults
|
||||||
image: $FLATPAK_IMAGE
|
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master
|
||||||
stage: flatpak
|
stage: flatpak
|
||||||
allow_failure: true
|
|
||||||
tags:
|
|
||||||
- flatpak
|
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- "${APPID}-dev.flatpak"
|
- "${APPID}-dev.flatpak"
|
||||||
@@ -126,96 +53,28 @@ msys2-mingw64:
|
|||||||
script:
|
script:
|
||||||
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
|
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
|
||||||
|
|
||||||
# Manual jobs, for branches and MRs
|
flatpak:demo:
|
||||||
.flatpak-manual:
|
|
||||||
extends: .flatpak-defaults
|
|
||||||
when: manual
|
|
||||||
|
|
||||||
# Only build Flatpak bundles automatically on master
|
|
||||||
.flatpak-master:
|
|
||||||
extends: .flatpak-defaults
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
|
|
||||||
flatpak-manual:demo:
|
|
||||||
extends: .flatpak-manual
|
|
||||||
variables:
|
variables:
|
||||||
APPID: org.gtk.Demo4
|
APPID: org.gtk.Demo
|
||||||
|
<<: *flatpak-defaults
|
||||||
|
|
||||||
flatpak-master:demo:
|
flatpak:widget-factory:
|
||||||
extends: .flatpak-master
|
|
||||||
variables:
|
variables:
|
||||||
APPID: org.gtk.Demo4
|
APPID: org.gtk.WidgetFactory
|
||||||
|
<<: *flatpak-defaults
|
||||||
flatpak-manual:widget-factory:
|
|
||||||
extends: .flatpak-manual
|
|
||||||
variables:
|
|
||||||
APPID: org.gtk.WidgetFactory4
|
|
||||||
|
|
||||||
flatpak-master:widget-factory:
|
|
||||||
extends: .flatpak-master
|
|
||||||
variables:
|
|
||||||
APPID: org.gtk.WidgetFactory4
|
|
||||||
|
|
||||||
flatpak-manual:icon-browser:
|
|
||||||
extends: .flatpak-manual
|
|
||||||
variables:
|
|
||||||
APPID: org.gtk.IconBrowser4
|
|
||||||
|
|
||||||
flatpak-master:icon-browser:
|
|
||||||
extends: .flatpak-master
|
|
||||||
variables:
|
|
||||||
APPID: org.gtk.IconBrowser4
|
|
||||||
|
|
||||||
static-scan:
|
|
||||||
image: $FEDORA_IMAGE
|
|
||||||
stage: analysis
|
|
||||||
variables:
|
|
||||||
EXTRA_MESON_FLAGS: "--buildtype=debug"
|
|
||||||
script:
|
|
||||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} _scan_build
|
|
||||||
- ninja -C _scan_build scan-build
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- _scan_build/meson-logs
|
|
||||||
allow_failure: true
|
|
||||||
|
|
||||||
# Run tests with the address sanitizer. We need to turn off introspection,
|
|
||||||
# since it is incompatible with asan
|
|
||||||
asan-build:
|
|
||||||
image: $FEDORA_IMAGE
|
|
||||||
tags: [ asan ]
|
|
||||||
stage: analysis
|
|
||||||
variables:
|
|
||||||
script:
|
|
||||||
- CC=clang meson --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=false _build
|
|
||||||
- ninja -C _build
|
|
||||||
- .gitlab-ci/run-tests.sh _build wayland
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- _build/meson-logs
|
|
||||||
allow_failure: true
|
|
||||||
|
|
||||||
reference:
|
|
||||||
image: $DOCS_IMAGE
|
|
||||||
stage: docs
|
|
||||||
variables:
|
|
||||||
EXTRA_MESON_FLAGS: "--buildtype=release"
|
|
||||||
script:
|
|
||||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} -Dgtk_doc=true _build
|
|
||||||
- ninja -C _build gdk4-doc gsk4-doc gtk4-doc
|
|
||||||
- mkdir -p _reference/
|
|
||||||
- mv _build/docs/reference/gdk/html/ _reference/gdk/
|
|
||||||
- mv _build/docs/reference/gsk/html/ _reference/gsk/
|
|
||||||
- mv _build/docs/reference/gtk/html/ _reference/gtk/
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- _reference
|
|
||||||
|
|
||||||
pages:
|
pages:
|
||||||
stage: deploy
|
image: registry.gitlab.gnome.org/gnome/gtk/master:v1
|
||||||
|
stage: deploy
|
||||||
script:
|
script:
|
||||||
- mv _reference/ public/
|
- meson -Ddocumentation=true _build .
|
||||||
|
- ninja -C _build
|
||||||
|
- ninja -C _build gdk4-doc gsk4-doc gtk4-doc
|
||||||
|
|
||||||
|
- mkdir -p public/
|
||||||
|
- mv _build/docs/reference/gtk/html/ public/gtk/
|
||||||
|
- mv _build/docs/reference/gdk/html/ public/gdk/
|
||||||
|
- mv _build/docs/reference/gsk/html/ public/gsk/
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- public
|
- public
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
FROM fedora:31
|
FROM fedora:28
|
||||||
|
|
||||||
RUN dnf -y install \
|
RUN dnf -y install \
|
||||||
|
hicolor-icon-theme \
|
||||||
adwaita-icon-theme \
|
adwaita-icon-theme \
|
||||||
atk-devel \
|
atk-devel \
|
||||||
at-spi2-atk-devel \
|
at-spi2-atk-devel \
|
||||||
@@ -8,15 +9,9 @@ RUN dnf -y install \
|
|||||||
cairo-devel \
|
cairo-devel \
|
||||||
cairo-gobject-devel \
|
cairo-gobject-devel \
|
||||||
ccache \
|
ccache \
|
||||||
clang \
|
|
||||||
clang-analyzer \
|
|
||||||
colord-devel \
|
colord-devel \
|
||||||
cups-devel \
|
cups-devel \
|
||||||
dbus-daemon \
|
|
||||||
dbus-x11 \
|
|
||||||
dejavu-sans-mono-fonts \
|
|
||||||
desktop-file-utils \
|
desktop-file-utils \
|
||||||
diffutils \
|
|
||||||
elfutils-libelf-devel \
|
elfutils-libelf-devel \
|
||||||
fribidi-devel \
|
fribidi-devel \
|
||||||
gcc \
|
gcc \
|
||||||
@@ -26,7 +21,6 @@ RUN dnf -y install \
|
|||||||
gettext \
|
gettext \
|
||||||
git \
|
git \
|
||||||
glib2-devel \
|
glib2-devel \
|
||||||
glib2-static \
|
|
||||||
glibc-devel \
|
glibc-devel \
|
||||||
glibc-headers \
|
glibc-headers \
|
||||||
gobject-introspection-devel \
|
gobject-introspection-devel \
|
||||||
@@ -36,19 +30,15 @@ RUN dnf -y install \
|
|||||||
gstreamer1-plugins-bad-free-devel \
|
gstreamer1-plugins-bad-free-devel \
|
||||||
gstreamer1-plugins-base-devel \
|
gstreamer1-plugins-base-devel \
|
||||||
gtk-doc \
|
gtk-doc \
|
||||||
hicolor-icon-theme \
|
|
||||||
iso-codes \
|
iso-codes \
|
||||||
itstool \
|
itstool \
|
||||||
json-glib-devel \
|
json-glib-devel \
|
||||||
lcov \
|
|
||||||
libasan \
|
|
||||||
libattr-devel \
|
libattr-devel \
|
||||||
libepoxy-devel \
|
libepoxy-devel \
|
||||||
libffi-devel \
|
libffi-devel \
|
||||||
libmount-devel \
|
libmount-devel \
|
||||||
librsvg2 \
|
librsvg2 \
|
||||||
libselinux-devel \
|
libselinux-devel \
|
||||||
libubsan \
|
|
||||||
libXcomposite-devel \
|
libXcomposite-devel \
|
||||||
libXcursor-devel \
|
libXcursor-devel \
|
||||||
libXcursor-devel \
|
libXcursor-devel \
|
||||||
@@ -59,7 +49,6 @@ RUN dnf -y install \
|
|||||||
libxkbcommon-devel \
|
libxkbcommon-devel \
|
||||||
libXrandr-devel \
|
libXrandr-devel \
|
||||||
libXrender-devel \
|
libXrender-devel \
|
||||||
libXtst-devel \
|
|
||||||
libxslt \
|
libxslt \
|
||||||
mesa-dri-drivers \
|
mesa-dri-drivers \
|
||||||
mesa-libEGL-devel \
|
mesa-libEGL-devel \
|
||||||
@@ -67,24 +56,26 @@ RUN dnf -y install \
|
|||||||
ninja-build \
|
ninja-build \
|
||||||
pango-devel \
|
pango-devel \
|
||||||
pcre-devel \
|
pcre-devel \
|
||||||
pcre-static \
|
|
||||||
python3 \
|
python3 \
|
||||||
python3-jinja2 \
|
|
||||||
python3-pip \
|
python3-pip \
|
||||||
python3-pygments \
|
|
||||||
python3-wheel \
|
python3-wheel \
|
||||||
redhat-rpm-config \
|
redhat-rpm-config \
|
||||||
sassc \
|
sassc \
|
||||||
sysprof-devel \
|
|
||||||
systemtap-sdt-devel \
|
systemtap-sdt-devel \
|
||||||
vulkan-devel \
|
vulkan-devel \
|
||||||
wayland-devel \
|
wayland-devel \
|
||||||
wayland-protocols-devel \
|
wayland-protocols-devel \
|
||||||
weston \
|
|
||||||
weston-libs \
|
|
||||||
which \
|
which \
|
||||||
xorg-x11-server-Xvfb \
|
xorg-x11-server-Xvfb \
|
||||||
&& dnf clean all
|
&& dnf clean all
|
||||||
|
|
||||||
RUN pip3 install meson==0.53.1
|
RUN pip3 install meson
|
||||||
|
|
||||||
|
ARG HOST_USER_ID=5555
|
||||||
|
ENV HOST_USER_ID ${HOST_USER_ID}
|
||||||
|
RUN useradd -u $HOST_USER_ID -ms /bin/bash user
|
||||||
|
|
||||||
|
USER user
|
||||||
|
WORKDIR /home/user
|
||||||
|
|
||||||
|
ENV LANG C.UTF-8
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
## GTK CI infrastructure
|
|
||||||
|
|
||||||
GTK uses different CI images depending on platform and jobs.
|
|
||||||
|
|
||||||
The CI images are Docker containers, generated either using `docker` or
|
|
||||||
`podman`, and pushed to the GitLab [container registry][registry].
|
|
||||||
|
|
||||||
Each Docker image has a tag composed of two parts:
|
|
||||||
|
|
||||||
- `${image}`: the base image for a given platform, like "fedora" or
|
|
||||||
"debian-stable"
|
|
||||||
- `${number}`: an incremental version number, or `latest`
|
|
||||||
|
|
||||||
See the [container registry][registry] for the available images for each
|
|
||||||
branch, as well as their available versions.
|
|
||||||
|
|
||||||
### Checklist for Updating a CI image
|
|
||||||
|
|
||||||
- [ ] Update the `${image}.Dockerfile` file with the dependencies
|
|
||||||
- [ ] Run `./run-docker.sh build --base ${image} --base-version ${number}`
|
|
||||||
- [ ] Run `./run-docker.sh push --base ${image} --base-version ${number}`
|
|
||||||
once the Docker image is built; you may need to log in by using
|
|
||||||
`docker login` or `podman login`
|
|
||||||
- [ ] Update the `image` keys in the `.gitlab-ci.yml` file with the new
|
|
||||||
image tag
|
|
||||||
- [ ] Open a merge request with your changes and let it run
|
|
||||||
|
|
||||||
### Checklist for Adding a new CI image
|
|
||||||
|
|
||||||
- [ ] Write a new `${image}.Dockerfile` with the instructions to set up
|
|
||||||
a build environment
|
|
||||||
- [ ] Add the `pip3 install meson` incantation
|
|
||||||
- [ ] Run `./run-docker.sh build --base ${image} --base-version ${number}`
|
|
||||||
- [ ] Run `./run-docker.sh push --base ${image} --base-version ${number}`
|
|
||||||
- [ ] Add the new job to `.gitlab-ci.yml` referencing the image
|
|
||||||
- [ ] Open a merge request with your changes and let it run
|
|
||||||
|
|
||||||
### Checklist for Adding a new dependency to a CI image
|
|
||||||
|
|
||||||
Our images are layered, and the base (called fedora-base) contains
|
|
||||||
all the rpm payload. Therefore, adding a new dependency is a 2-step
|
|
||||||
process:
|
|
||||||
|
|
||||||
1. [ ] Build and upload fedora-base:$version+1
|
|
||||||
1. [ ] Build and upload fedora:$version+1 based on fedora-base:version+1
|
|
||||||
|
|
||||||
[registry]: https://gitlab.gnome.org/GNOME/gtk/container_registry
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
#
|
|
||||||
# === clang-format-diff.py - ClangFormat Diff Reformatter ---*- python -*-=== #
|
|
||||||
#
|
|
||||||
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
||||||
# See https://llvm.org/LICENSE.txt for license information.
|
|
||||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
||||||
#
|
|
||||||
# ===---------------------------------------------------------------------=== #
|
|
||||||
|
|
||||||
"""
|
|
||||||
This script reads input from a unified diff and reformats all the changed
|
|
||||||
lines. This is useful to reformat all the lines touched by a specific patch.
|
|
||||||
Example usage for git/svn users:
|
|
||||||
|
|
||||||
git diff -U0 --no-color HEAD^ | clang-format-diff.py -p1 -i
|
|
||||||
svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i
|
|
||||||
|
|
||||||
"""
|
|
||||||
from __future__ import absolute_import, division, print_function
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import difflib
|
|
||||||
import re
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
|
|
||||||
if sys.version_info.major >= 3:
|
|
||||||
from io import StringIO
|
|
||||||
else:
|
|
||||||
from io import BytesIO as StringIO
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description=__doc__,
|
|
||||||
formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
||||||
parser.add_argument('-i', action='store_true', default=False,
|
|
||||||
help='apply edits to files instead of displaying a '
|
|
||||||
'diff')
|
|
||||||
parser.add_argument('-p', metavar='NUM', default=0,
|
|
||||||
help='strip the smallest prefix containing P slashes')
|
|
||||||
parser.add_argument('-regex', metavar='PATTERN', default=None,
|
|
||||||
help='custom pattern selecting file paths to reformat '
|
|
||||||
'(case sensitive, overrides -iregex)')
|
|
||||||
parser.add_argument('-iregex', metavar='PATTERN',
|
|
||||||
default=r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hh|hpp|m|mm|inc'
|
|
||||||
r'|js|ts|proto|protodevel|java|cs)',
|
|
||||||
help='custom pattern selecting file paths to reformat '
|
|
||||||
'(case insensitive, overridden by -regex)')
|
|
||||||
parser.add_argument('-sort-includes', action='store_true', default=False,
|
|
||||||
help='let clang-format sort include blocks')
|
|
||||||
parser.add_argument('-v', '--verbose', action='store_true',
|
|
||||||
help='be more verbose, ineffective without -i')
|
|
||||||
parser.add_argument('-style',
|
|
||||||
help='formatting style to apply (LLVM, Google, '
|
|
||||||
'Chromium, Mozilla, WebKit)')
|
|
||||||
parser.add_argument('-binary', default='clang-format',
|
|
||||||
help='location of binary to use for clang-format')
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
# Extract changed lines for each file.
|
|
||||||
filename = None
|
|
||||||
lines_by_file = {}
|
|
||||||
for line in sys.stdin:
|
|
||||||
match = re.search(r'^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line)
|
|
||||||
if match:
|
|
||||||
filename = match.group(2)
|
|
||||||
if filename is None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if args.regex is not None:
|
|
||||||
if not re.match('^%s$' % args.regex, filename):
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE):
|
|
||||||
continue
|
|
||||||
|
|
||||||
match = re.search(r'^@@.*\+(\d+)(,(\d+))?', line)
|
|
||||||
if match:
|
|
||||||
start_line = int(match.group(1))
|
|
||||||
line_count = 1
|
|
||||||
if match.group(3):
|
|
||||||
line_count = int(match.group(3))
|
|
||||||
if line_count == 0:
|
|
||||||
continue
|
|
||||||
end_line = start_line + line_count - 1
|
|
||||||
lines_by_file.setdefault(filename, []).extend(
|
|
||||||
['-lines', str(start_line) + ':' + str(end_line)])
|
|
||||||
|
|
||||||
# Reformat files containing changes in place.
|
|
||||||
# We need to count amount of bytes generated in the output of
|
|
||||||
# clang-format-diff. If clang-format-diff doesn't generate any bytes it
|
|
||||||
# means there is nothing to format.
|
|
||||||
format_line_counter = 0
|
|
||||||
for filename, lines in lines_by_file.items():
|
|
||||||
if args.i and args.verbose:
|
|
||||||
print('Formatting {}'.format(filename))
|
|
||||||
command = [args.binary, filename]
|
|
||||||
if args.i:
|
|
||||||
command.append('-i')
|
|
||||||
if args.sort_includes:
|
|
||||||
command.append('-sort-includes')
|
|
||||||
command.extend(lines)
|
|
||||||
if args.style:
|
|
||||||
command.extend(['-style', args.style])
|
|
||||||
p = subprocess.Popen(command,
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=None,
|
|
||||||
stdin=subprocess.PIPE,
|
|
||||||
universal_newlines=True)
|
|
||||||
stdout, _ = p.communicate()
|
|
||||||
if p.returncode != 0:
|
|
||||||
sys.exit(p.returncode)
|
|
||||||
|
|
||||||
if not args.i:
|
|
||||||
with open(filename) as f:
|
|
||||||
code = f.readlines()
|
|
||||||
formatted_code = StringIO(stdout).readlines()
|
|
||||||
diff = difflib.unified_diff(code, formatted_code,
|
|
||||||
filename, filename,
|
|
||||||
'(before formatting)',
|
|
||||||
'(after formatting)')
|
|
||||||
diff_string = ''.join(diff)
|
|
||||||
if diff_string:
|
|
||||||
format_line_counter += sys.stdout.write(diff_string)
|
|
||||||
|
|
||||||
if format_line_counter > 0:
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v19
|
|
||||||
|
|
||||||
RUN dnf -y install pandoc
|
|
||||||
|
|
||||||
ARG HOST_USER_ID=5555
|
|
||||||
ENV HOST_USER_ID ${HOST_USER_ID}
|
|
||||||
RUN useradd -u $HOST_USER_ID -ms /bin/bash user
|
|
||||||
|
|
||||||
USER user
|
|
||||||
WORKDIR /home/user
|
|
||||||
|
|
||||||
ENV LANG C.UTF-8
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v20
|
|
||||||
|
|
||||||
ARG HOST_USER_ID=5555
|
|
||||||
ENV HOST_USER_ID ${HOST_USER_ID}
|
|
||||||
RUN useradd -u $HOST_USER_ID -ms /bin/bash user
|
|
||||||
|
|
||||||
USER user
|
|
||||||
WORKDIR /home/user
|
|
||||||
|
|
||||||
ENV LANG C.UTF-8
|
|
||||||
@@ -4,19 +4,20 @@ set -e
|
|||||||
|
|
||||||
appid=$1
|
appid=$1
|
||||||
|
|
||||||
builddir=flatpak_app
|
builddir=app
|
||||||
repodir=repo
|
repodir=repo
|
||||||
|
|
||||||
flatpak-builder \
|
flatpak-builder \
|
||||||
--user --disable-rofiles-fuse \
|
|
||||||
--stop-at=gtk \
|
--stop-at=gtk \
|
||||||
${builddir} \
|
${builddir} \
|
||||||
build-aux/flatpak/${appid}.json
|
build-aux/flatpak/${appid}.json
|
||||||
|
|
||||||
flatpak build ${builddir} meson \
|
flatpak-builder \
|
||||||
--prefix=/app \
|
--run ${builddir} build-aux/flatpak/${appid}.json \
|
||||||
--libdir=/app/lib \
|
meson \
|
||||||
--buildtype=release \
|
--prefix /app \
|
||||||
|
--libdir /app/lib \
|
||||||
|
--buildtype debug \
|
||||||
-Dx11-backend=true \
|
-Dx11-backend=true \
|
||||||
-Dwayland-backend=true \
|
-Dwayland-backend=true \
|
||||||
-Dprint-backends=file \
|
-Dprint-backends=file \
|
||||||
@@ -24,12 +25,13 @@ flatpak build ${builddir} meson \
|
|||||||
-Dbuild-examples=false \
|
-Dbuild-examples=false \
|
||||||
-Dintrospection=false \
|
-Dintrospection=false \
|
||||||
-Ddemos=true \
|
-Ddemos=true \
|
||||||
_flatpak_build
|
_build .
|
||||||
|
|
||||||
flatpak build ${builddir} ninja -C _flatpak_build install
|
flatpak-builder \
|
||||||
|
--run ${builddir} build-aux/flatpak/${appid}.json \
|
||||||
|
ninja -C _build install
|
||||||
|
|
||||||
flatpak-builder \
|
flatpak-builder \
|
||||||
--user --disable-rofiles-fuse \
|
|
||||||
--finish-only \
|
--finish-only \
|
||||||
--repo=${repodir} \
|
--repo=${repodir} \
|
||||||
${builddir} \
|
${builddir} \
|
||||||
@@ -38,5 +40,5 @@ flatpak-builder \
|
|||||||
flatpak build-bundle \
|
flatpak build-bundle \
|
||||||
${repodir} \
|
${repodir} \
|
||||||
${appid}-dev.flatpak \
|
${appid}-dev.flatpak \
|
||||||
--runtime-repo=https://nightly.gnome.org/gnome-nightly.flatpakrepo \
|
--runtime-repo=https://flathub.org/repo/flathub.flatpakrepo \
|
||||||
${appid}
|
${appid}
|
||||||
|
|||||||
@@ -1,371 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# Turns a Mason testlog.json file into an HTML report
|
|
||||||
#
|
|
||||||
# Copyright 2019 GNOME Foundation
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
#
|
|
||||||
# Original author: Emmanuele Bassi
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import datetime
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
from jinja2 import Template
|
|
||||||
|
|
||||||
REPORT_TEMPLATE = '''
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>{{ report.project_name }} Test Report</title>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<style type="text/css">
|
|
||||||
body {
|
|
||||||
background: white;
|
|
||||||
color: #333;
|
|
||||||
font-family: 'Cantarell', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: #333333;
|
|
||||||
font-size: 1.9em;
|
|
||||||
font-weight: normal;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
border-bottom: 1px solid #333333;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
position: fixed;
|
|
||||||
padding-bottom: 12px;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
background: rgba(255, 255, 255, 0.85);
|
|
||||||
box-shadow: 0 0 1px rgba(0, 0, 0, 0.15);
|
|
||||||
z-index: 500;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
color: rgba(0, 0, 0, 0.3);
|
|
||||||
transform: translateY(0px);
|
|
||||||
transition: .2s background-color, color;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: block;
|
|
||||||
visibility: visible;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
article {
|
|
||||||
padding-top: 200px;
|
|
||||||
margin: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.report-meta {
|
|
||||||
width: auto;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
padding: .5em 2em;
|
|
||||||
color: #3c3c3c;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.result {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.pass {
|
|
||||||
color: rgb(51, 209, 122);
|
|
||||||
}
|
|
||||||
|
|
||||||
span.skip {
|
|
||||||
color: rgb(255, 163, 72);
|
|
||||||
}
|
|
||||||
|
|
||||||
span.fail {
|
|
||||||
color: rgb(224, 27, 36);
|
|
||||||
}
|
|
||||||
|
|
||||||
span.xfail {
|
|
||||||
color: rgb(163, 71, 186);
|
|
||||||
}
|
|
||||||
|
|
||||||
div.result {
|
|
||||||
border-top: 1px solid #c0c0c0;
|
|
||||||
padding-top: 1em;
|
|
||||||
padding-bottom: 1em;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.result h4 {
|
|
||||||
border-bottom: 1px solid #c0c0c0;
|
|
||||||
margin-bottom: 0.7em;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
color: #fafafa;
|
|
||||||
background-color: black;
|
|
||||||
border-radius: 6px;
|
|
||||||
box-shadow: 0px 5px 8px 0px rgba(0, 0, 0, 0.25);
|
|
||||||
font-family: monospace;
|
|
||||||
line-height: 1.2em;
|
|
||||||
border: none;
|
|
||||||
padding: 10px 1em;
|
|
||||||
font-size: 0.9em;
|
|
||||||
overflow: auto;
|
|
||||||
white-space: pre;
|
|
||||||
word-break: normal;
|
|
||||||
word-wrap: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.passed li {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.passed li:after {
|
|
||||||
content: ",";
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.passed li:last-child:after {
|
|
||||||
content: "";
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.images {
|
|
||||||
padding-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.images li {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<header>
|
|
||||||
<h1>{{ report.project_name }}/{{ report.backend }}/{{ report.branch_name }} :: Test Reports</h1>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<article>
|
|
||||||
<section>
|
|
||||||
<div class="report-meta">
|
|
||||||
<p><strong>Backend:</strong> {{ report.backend }}</p>
|
|
||||||
<p><strong>Branch:</strong> {{ report.branch_name }}</p>
|
|
||||||
<p><strong>Date:</strong> <time datetime="{{ report.date.isoformat() }}">{{ report.locale_date }}</time></p>
|
|
||||||
{% if report.job_id %}<p><strong>Job ID:</strong> {{ report.job_id }}</p>{% endif %}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<div class="summary">
|
|
||||||
<h3><a name="summary">Summary</a></h3>
|
|
||||||
<ul>
|
|
||||||
<li><strong>Total units:</strong> {{ report.total_units }}</li>
|
|
||||||
<li><strong>Failed:</strong> {{ report.total_failures }}</li>
|
|
||||||
<li><strong>Passed:</strong> {{ report.total_successes }}</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{% for suite_result in report.results_list %}
|
|
||||||
<section>
|
|
||||||
<div class="result">
|
|
||||||
<h3><a name="results">Suite: {{ suite_result.suite_name }}</a></h3>
|
|
||||||
<ul>
|
|
||||||
<li><strong>Units:</strong> {{ suite_result.n_units }}</li>
|
|
||||||
<li><strong>Failed:</strong> <a href="#{{ suite_result.suite_name }}-failed">{{ suite_result.n_failures }}</a></li>
|
|
||||||
<li><strong>Passed:</strong> <a href="#{{ suite_result.suite_name }}-passed">{{ suite_result.n_successes }}</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="failures">
|
|
||||||
<h4><a name="{{ suite_result.suite_name }}-failed">Failures</a></h4>
|
|
||||||
<ul class="failed">
|
|
||||||
{% for failure in suite_result.failures if failure.result in [ 'ERROR', 'FAIL', 'UNEXPECTEDPASS' ] %}
|
|
||||||
<li><a name="{{ failure.name }}">{{ failure.name }}</a> - result: <span class="result fail">{{ failure.result }}</span><br/>
|
|
||||||
{% if failure.stdout %}
|
|
||||||
Output: <pre>{{ failure.stdout }}</pre>
|
|
||||||
{% endif %}
|
|
||||||
{% if failure.image_data is defined %}
|
|
||||||
<ul class="images">
|
|
||||||
<li><img alt="ref" src="{{ failure.image_data.ref }}" /></li>
|
|
||||||
<li><img alt="out" src="{{ failure.image_data.out }}" /></li>
|
|
||||||
<li><img alt="diff" src="{{ failure.image_data.diff }}" /></li>
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
</li>
|
|
||||||
{% else %}
|
|
||||||
<li>None</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h4><a name="{{ suite_result.suite_name }}-timed-out">Timed out</a></h4>
|
|
||||||
<ul class="failed">
|
|
||||||
{% for failure in suite_result.failures if failure.result == 'TIMEOUT' %}
|
|
||||||
<li><a name="{{ failure.name }}">{{ failure.name }}</a> - result: <span class="result fail">{{ failure.result }}</span><br/>
|
|
||||||
{% if failure.stdout %}
|
|
||||||
Output: <pre>{{ failure.stdout }}</pre>
|
|
||||||
{% endif %}
|
|
||||||
</li>
|
|
||||||
{% else %}
|
|
||||||
<li>None</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="successes">
|
|
||||||
<h4><a name="{{ suite_result.suite_name }}-expected-fail">Expected failures</a></h4>
|
|
||||||
<ul>
|
|
||||||
{% for success in suite_result.successes if success.result == 'EXPECTEDFAIL' %}
|
|
||||||
<li><a name="{{ success.name }}">{{ success.name }}</a> - result: <span class="result xfail">{{ success.result }}</span><br/>
|
|
||||||
{% if success.stdout %}
|
|
||||||
Output: <pre>{{ success.stdout }}</pre>
|
|
||||||
{% endif %}
|
|
||||||
{% if success.image_data is defined %}
|
|
||||||
<ul class="images">
|
|
||||||
<li><img alt="ref" src="{{ success.image_data.ref }}" /></li>
|
|
||||||
<li><img alt="out" src="{{ success.image_data.out }}" /></li>
|
|
||||||
<li><img alt="diff" src="{{ success.image_data.diff }}" /></li>
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
</li>
|
|
||||||
{% else %}
|
|
||||||
<li>None</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h4><a name="{{ suite_result.suite_name }}-skipped">Skipped</a></h4>
|
|
||||||
<ul>
|
|
||||||
{% for success in suite_result.successes if success.result == 'SKIP' %}
|
|
||||||
<li>{{ success.name }} - result: <span class="result skip">{{ success.result }}</li>
|
|
||||||
{% else %}
|
|
||||||
<li>None</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h4><a name="{{ suite_result.suite_name }}-passed">Passed</a></h4>
|
|
||||||
<ul class="passed">
|
|
||||||
{% for success in suite_result.successes if success.result == 'OK' %}
|
|
||||||
<li>{{ success.name }} - result: <span class="result pass">{{ success.result }}</li>
|
|
||||||
{% else %}
|
|
||||||
<li>None</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
</article>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
'''
|
|
||||||
|
|
||||||
aparser = argparse.ArgumentParser(description='Turns a Meson test log into an HTML report')
|
|
||||||
aparser.add_argument('--project-name', metavar='NAME',
|
|
||||||
help='The project name',
|
|
||||||
default='Unknown')
|
|
||||||
aparser.add_argument('--backend', metavar='NAME',
|
|
||||||
help='The used backend',
|
|
||||||
default='unknown')
|
|
||||||
aparser.add_argument('--job-id', metavar='ID',
|
|
||||||
help='The job ID for the report',
|
|
||||||
default=None)
|
|
||||||
aparser.add_argument('--branch', metavar='NAME',
|
|
||||||
help='Branch of the project being tested',
|
|
||||||
default='master')
|
|
||||||
aparser.add_argument('--output', metavar='FILE',
|
|
||||||
help='The output HTML file, stdout by default',
|
|
||||||
type=argparse.FileType('w', encoding='UTF-8'),
|
|
||||||
default=sys.stdout)
|
|
||||||
aparser.add_argument('--reftest-suite', metavar='NAME',
|
|
||||||
help='The name of the reftests suite',
|
|
||||||
default='reftest')
|
|
||||||
aparser.add_argument('--reftest-output-dir', metavar='DIR',
|
|
||||||
help='The output directory for reftests data',
|
|
||||||
default=None)
|
|
||||||
aparser.add_argument('infile', metavar='FILE',
|
|
||||||
help='The input testlog.json, stdin by default',
|
|
||||||
type=argparse.FileType('r', encoding='UTF-8'),
|
|
||||||
default=sys.stdin)
|
|
||||||
|
|
||||||
args = aparser.parse_args()
|
|
||||||
|
|
||||||
outfile = args.output
|
|
||||||
|
|
||||||
suites = {}
|
|
||||||
for line in args.infile:
|
|
||||||
data = json.loads(line)
|
|
||||||
(full_suite, unit_name) = data['name'].split(' / ')
|
|
||||||
(project_name, suite_name) = full_suite.split(':')
|
|
||||||
|
|
||||||
unit = {
|
|
||||||
'project-name': project_name,
|
|
||||||
'suite': suite_name,
|
|
||||||
'name': unit_name,
|
|
||||||
'duration': data['duration'],
|
|
||||||
'returncode': data['returncode'],
|
|
||||||
'result': data['result'],
|
|
||||||
'stdout': data['stdout'],
|
|
||||||
}
|
|
||||||
|
|
||||||
if args.reftest_output_dir is not None and suite_name == args.reftest_suite:
|
|
||||||
filename = unit_name.split(' ')[1]
|
|
||||||
basename = os.path.splitext(filename)[0]
|
|
||||||
|
|
||||||
image_data = {
|
|
||||||
'ref': os.path.join(args.reftest_output_dir, '{}.ref.png'.format(basename)),
|
|
||||||
'out': os.path.join(args.reftest_output_dir, '{}.out.png'.format(basename)),
|
|
||||||
'diff': os.path.join(args.reftest_output_dir, '{}.diff.png'.format(basename)),
|
|
||||||
}
|
|
||||||
|
|
||||||
unit['image_data'] = image_data
|
|
||||||
|
|
||||||
units = suites.setdefault(full_suite, [])
|
|
||||||
units.append(unit)
|
|
||||||
|
|
||||||
report = {}
|
|
||||||
report['date'] = datetime.datetime.utcnow()
|
|
||||||
report['locale_date'] = report['date'].strftime("%c")
|
|
||||||
report['project_name'] = args.project_name
|
|
||||||
report['backend'] = args.backend
|
|
||||||
report['job_id'] = args.job_id
|
|
||||||
report['branch_name'] = args.branch
|
|
||||||
report['total_successes'] = 0
|
|
||||||
report['total_failures'] = 0
|
|
||||||
report['total_units'] = 0
|
|
||||||
report['results_list'] = []
|
|
||||||
|
|
||||||
for name, units in suites.items():
|
|
||||||
(project_name, suite_name) = name.split(':')
|
|
||||||
print('Processing {} suite {}:'.format(project_name, suite_name))
|
|
||||||
|
|
||||||
def if_failed(unit):
|
|
||||||
if unit['result'] in ['FAIL', 'UNEXPECTEDPASS', 'TIMEOUT', 'ERROR',]:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def if_succeded(unit):
|
|
||||||
if unit['result'] in ['OK', 'EXPECTEDFAIL', 'SKIP']:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
successes = list(filter(if_succeded, units))
|
|
||||||
failures = list(filter(if_failed, units))
|
|
||||||
|
|
||||||
n_units = len(units)
|
|
||||||
n_successes = len(successes)
|
|
||||||
n_failures = len(failures)
|
|
||||||
|
|
||||||
report['total_units'] += n_units
|
|
||||||
report['total_successes'] += n_successes
|
|
||||||
report['total_failures'] += n_failures
|
|
||||||
print(' - {}: {} total, {} pass, {} fail'.format(suite_name, n_units, n_successes, n_failures))
|
|
||||||
|
|
||||||
suite_report = {
|
|
||||||
'suite_name': suite_name,
|
|
||||||
'n_units': n_units,
|
|
||||||
'successes': successes,
|
|
||||||
'n_successes': n_successes,
|
|
||||||
'failures': failures,
|
|
||||||
'n_failures': n_failures,
|
|
||||||
}
|
|
||||||
report['results_list'].append(suite_report)
|
|
||||||
|
|
||||||
template = Template(REPORT_TEMPLATE)
|
|
||||||
outfile.write(template.render({'report': report}))
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# Turns a Meson testlog.json file into a JUnit XML report
|
|
||||||
#
|
|
||||||
# Copyright 2019 GNOME Foundation
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
||||||
#
|
|
||||||
# Original author: Emmanuele Bassi
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import datetime
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import xml.etree.ElementTree as ET
|
|
||||||
|
|
||||||
aparser = argparse.ArgumentParser(description='Turns a Meson test log into a JUnit report')
|
|
||||||
aparser.add_argument('--project-name', metavar='NAME',
|
|
||||||
help='The project name',
|
|
||||||
default='unknown')
|
|
||||||
aparser.add_argument('--backend', metavar='NAME',
|
|
||||||
help='The used backend',
|
|
||||||
default='unknown')
|
|
||||||
aparser.add_argument('--job-id', metavar='ID',
|
|
||||||
help='The job ID for the report',
|
|
||||||
default='Unknown')
|
|
||||||
aparser.add_argument('--branch', metavar='NAME',
|
|
||||||
help='Branch of the project being tested',
|
|
||||||
default='master')
|
|
||||||
aparser.add_argument('--output', metavar='FILE',
|
|
||||||
help='The output file, stdout by default',
|
|
||||||
type=argparse.FileType('w', encoding='UTF-8'),
|
|
||||||
default=sys.stdout)
|
|
||||||
aparser.add_argument('infile', metavar='FILE',
|
|
||||||
help='The input testlog.json, stdin by default',
|
|
||||||
type=argparse.FileType('r', encoding='UTF-8'),
|
|
||||||
default=sys.stdin)
|
|
||||||
|
|
||||||
args = aparser.parse_args()
|
|
||||||
|
|
||||||
outfile = args.output
|
|
||||||
|
|
||||||
testsuites = ET.Element('testsuites')
|
|
||||||
testsuites.set('id', '{}/{}'.format(args.job_id, args.branch))
|
|
||||||
testsuites.set('package', args.project_name)
|
|
||||||
testsuites.set('timestamp', datetime.datetime.utcnow().isoformat(timespec='minutes'))
|
|
||||||
|
|
||||||
suites = {}
|
|
||||||
for line in args.infile:
|
|
||||||
data = json.loads(line)
|
|
||||||
(full_suite, unit_name) = data['name'].split(' / ')
|
|
||||||
(project_name, suite_name) = full_suite.split(':')
|
|
||||||
|
|
||||||
duration = data['duration']
|
|
||||||
return_code = data['returncode']
|
|
||||||
result = data['result']
|
|
||||||
log = data['stdout']
|
|
||||||
|
|
||||||
unit = {
|
|
||||||
'suite': suite_name,
|
|
||||||
'name': unit_name,
|
|
||||||
'duration': duration,
|
|
||||||
'returncode': return_code,
|
|
||||||
'result': result,
|
|
||||||
'stdout': log,
|
|
||||||
}
|
|
||||||
|
|
||||||
units = suites.setdefault(suite_name, [])
|
|
||||||
units.append(unit)
|
|
||||||
|
|
||||||
for name, units in suites.items():
|
|
||||||
print('Processing suite {} (units: {})'.format(name, len(units)))
|
|
||||||
|
|
||||||
def if_failed(unit):
|
|
||||||
if unit['result'] in ['ERROR', 'FAIL', 'UNEXPECTEDPASS', 'TIMEOUT']:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def if_succeded(unit):
|
|
||||||
if unit['result'] in ['OK', 'EXPECTEDFAIL', 'SKIP']:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
successes = list(filter(if_succeded, units))
|
|
||||||
failures = list(filter(if_failed, units))
|
|
||||||
print(' - {}: {} pass, {} fail'.format(name, len(successes), len(failures)))
|
|
||||||
|
|
||||||
testsuite = ET.SubElement(testsuites, 'testsuite')
|
|
||||||
testsuite.set('name', '{}/{}'.format(args.project_name, name))
|
|
||||||
testsuite.set('tests', str(len(units)))
|
|
||||||
testsuite.set('errors', str(len(failures)))
|
|
||||||
testsuite.set('failures', str(len(failures)))
|
|
||||||
|
|
||||||
for unit in successes:
|
|
||||||
testcase = ET.SubElement(testsuite, 'testcase')
|
|
||||||
testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
|
|
||||||
testcase.set('name', '{}/{}'.format(args.backend, unit['name']))
|
|
||||||
testcase.set('time', str(unit['duration']))
|
|
||||||
|
|
||||||
for unit in failures:
|
|
||||||
testcase = ET.SubElement(testsuite, 'testcase')
|
|
||||||
testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
|
|
||||||
testcase.set('name', '{}/{}'.format(args.backend, unit['name']))
|
|
||||||
testcase.set('time', str(unit['duration']))
|
|
||||||
|
|
||||||
failure = ET.SubElement(testcase, 'failure')
|
|
||||||
failure.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
|
|
||||||
testcase.set('name', '{}/{}'.format(args.backend, unit['name']))
|
|
||||||
failure.set('type', 'error')
|
|
||||||
failure.text = unit['stdout']
|
|
||||||
|
|
||||||
output = ET.tostring(testsuites, encoding='unicode')
|
|
||||||
outfile.write(output)
|
|
||||||
@@ -1,135 +1,11 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
read_arg() {
|
|
||||||
# $1 = arg name
|
|
||||||
# $2 = arg value
|
|
||||||
# $3 = arg parameter
|
|
||||||
local rematch='^[^=]*=(.*)$'
|
|
||||||
if [[ $2 =~ $rematch ]]; then
|
|
||||||
read "$1" <<< "${BASH_REMATCH[1]}"
|
|
||||||
else
|
|
||||||
read "$1" <<< "$3"
|
|
||||||
# There is no way to shift our callers args, so
|
|
||||||
# return 1 to indicate they should do it instead.
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
build=0
|
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v1"
|
||||||
run=0
|
|
||||||
push=0
|
|
||||||
list=0
|
|
||||||
print_help=0
|
|
||||||
no_login=0
|
|
||||||
|
|
||||||
while (($# > 0)); do
|
sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \
|
||||||
case "${1%%=*}" in
|
--file "Dockerfile" .
|
||||||
build) build=1;;
|
sudo docker run --rm --security-opt label=disable \
|
||||||
run) run=1;;
|
--volume "$(pwd)/..:/home/user/app" --workdir "/home/user/app" \
|
||||||
push) push=1;;
|
--tty --interactive "${TAG}" bash
|
||||||
list) list=1;;
|
|
||||||
help) print_help=1;;
|
|
||||||
--base|-b) read_arg base "$@" || shift;;
|
|
||||||
--base-version) read_arg base_version "$@" || shift;;
|
|
||||||
--no-login) no_login=1;;
|
|
||||||
*) echo -e "\e[1;31mERROR\e[0m: Unknown option '$1'"; exit 1;;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ $print_help == 1 ]; then
|
|
||||||
echo "$0 - Build and run Docker images"
|
|
||||||
echo ""
|
|
||||||
echo "Usage: $0 <command> [options] [basename]"
|
|
||||||
echo ""
|
|
||||||
echo "Available commands"
|
|
||||||
echo ""
|
|
||||||
echo " build --base=<BASENAME> - Build Docker image <BASENAME>.Dockerfile"
|
|
||||||
echo " run --base=<BASENAME> - Run Docker image <BASENAME>"
|
|
||||||
echo " push --base=<BASENAME> - Push Docker image <BASENAME> to the registry"
|
|
||||||
echo " list - List available images"
|
|
||||||
echo " help - This help message"
|
|
||||||
echo ""
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
|
|
||||||
if [ $list == 1 ]; then
|
|
||||||
echo "Available Docker images:"
|
|
||||||
for f in *.Dockerfile; do
|
|
||||||
filename=$( basename -- "$f" )
|
|
||||||
basename="${filename%.*}"
|
|
||||||
|
|
||||||
echo -e " \e[1;39m$basename\e[0m"
|
|
||||||
done
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# All commands after this require --base to be set
|
|
||||||
if [ -z $base ]; then
|
|
||||||
echo "Usage: $0 <command>"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "$base.Dockerfile" ]; then
|
|
||||||
echo -e "\e[1;31mERROR\e[0m: Dockerfile for '$base' not found"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z $base_version ]; then
|
|
||||||
base_version="latest"
|
|
||||||
elif [ $base_version != "latest" ]; then
|
|
||||||
base_version="v$base_version"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -x "$(command -v docker)" ] || [ docker --help |& grep -q podman ]; then
|
|
||||||
# Docker is actually implemented by podman, and its OCI output
|
|
||||||
# is incompatible with some of the dockerd instances on GitLab
|
|
||||||
# CI runners.
|
|
||||||
echo "Using: Podman"
|
|
||||||
format="--format docker"
|
|
||||||
CMD="podman"
|
|
||||||
else
|
|
||||||
echo "Using: Docker"
|
|
||||||
format=""
|
|
||||||
CMD="sudo docker"
|
|
||||||
fi
|
|
||||||
|
|
||||||
REGISTRY="registry.gitlab.gnome.org"
|
|
||||||
TAG="${REGISTRY}/gnome/gtk/${base}:${base_version}"
|
|
||||||
|
|
||||||
if [ $build == 1 ]; then
|
|
||||||
echo -e "\e[1;32mBUILDING\e[0m: ${base} as ${TAG}"
|
|
||||||
${CMD} build \
|
|
||||||
${format} \
|
|
||||||
--build-arg HOST_USER_ID="$UID" \
|
|
||||||
--tag "${TAG}" \
|
|
||||||
--file "${base}.Dockerfile" .
|
|
||||||
exit $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $push == 1 ]; then
|
|
||||||
echo -e "\e[1;32mPUSHING\e[0m: ${base} as ${TAG}"
|
|
||||||
|
|
||||||
if [ $no_login == 0 ]; then
|
|
||||||
${CMD} login ${REGISTRY}
|
|
||||||
fi
|
|
||||||
|
|
||||||
${CMD} push ${TAG}
|
|
||||||
exit $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $run == 1 ]; then
|
|
||||||
echo -e "\e[1;32mRUNNING\e[0m: ${base} as ${TAG}"
|
|
||||||
${CMD} run \
|
|
||||||
--rm \
|
|
||||||
--volume "$(pwd)/..:/home/user/app" \
|
|
||||||
--workdir "/home/user/app" \
|
|
||||||
--tty \
|
|
||||||
--interactive "${TAG}" \
|
|
||||||
bash
|
|
||||||
exit $?
|
|
||||||
fi
|
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# We need to add a new remote for the upstream master, since this script could
|
|
||||||
# be running in a personal fork of the repository which has out of date branches.
|
|
||||||
if [ "${CI_PROJECT_NAMESPACE}" != "GNOME" ]; then
|
|
||||||
echo "Retrieving the current upstream repository from ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}..."
|
|
||||||
git remote add upstream https://gitlab.gnome.org/GNOME/gtk.git
|
|
||||||
git fetch upstream
|
|
||||||
ORIGIN="upstream"
|
|
||||||
else
|
|
||||||
echo "Reusing the existing repository on ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}"
|
|
||||||
ORIGIN="origin"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Work out the newest common ancestor between the detached HEAD that this CI job
|
|
||||||
# has checked out, and the upstream target branch (which will typically be
|
|
||||||
# `upstream/master` or `upstream/gtk-3-24`).
|
|
||||||
#
|
|
||||||
# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` is only defined if we’re running in
|
|
||||||
# a merge request pipeline; fall back to `${CI_DEFAULT_BRANCH}` otherwise.
|
|
||||||
newest_common_ancestor_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${ORIGIN}/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}") <(git rev-list --first-parent HEAD) | head -1)
|
|
||||||
git diff -U0 --no-color "${newest_common_ancestor_sha}" | .gitlab-ci/clang-format-diff.py -binary "clang-format" -p1
|
|
||||||
exit_status=$?
|
|
||||||
|
|
||||||
# The style check is not infallible. The clang-format configuration cannot
|
|
||||||
# perfectly describe GTK’s coding style: in particular, it cannot align
|
|
||||||
# function arguments. The documented coding style for GTK takes priority over
|
|
||||||
# clang-format suggestions. Hopefully we can eventually improve clang-format to
|
|
||||||
# be configurable enough for our coding style. That’s why this CI check is OK
|
|
||||||
# to fail: the idea is that people can look through the output and ignore it if
|
|
||||||
# it’s wrong. (That situation can also happen if someone touches pre-existing
|
|
||||||
# badly formatted code and it doesn’t make sense to tidy up the wider coding
|
|
||||||
# style with the changes they’re making.)
|
|
||||||
echo ""
|
|
||||||
echo "Note that clang-format output is advisory and cannot always match the"
|
|
||||||
echo "GTK coding style, documented at:"
|
|
||||||
echo " https://gitlab.gnome.org/GNOME/gtk/blob/master/docs/CODING-STYLE"
|
|
||||||
echo "Warnings from this tool can be ignored in favour of the documented "
|
|
||||||
echo "coding style, or in favour of matching the style of existing"
|
|
||||||
echo "surrounding code."
|
|
||||||
|
|
||||||
exit ${exit_status}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set +x
|
|
||||||
set +e
|
|
||||||
|
|
||||||
srcdir=$( pwd )
|
|
||||||
builddir=$1
|
|
||||||
backend=$2
|
|
||||||
|
|
||||||
# Ignore memory leaks lower in dependencies
|
|
||||||
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp
|
|
||||||
|
|
||||||
case "${backend}" in
|
|
||||||
x11)
|
|
||||||
xvfb-run -a -s "-screen 0 1024x768x24" \
|
|
||||||
meson test -C ${builddir} \
|
|
||||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
|
||||||
--print-errorlogs \
|
|
||||||
--setup=${backend} \
|
|
||||||
--suite=gtk \
|
|
||||||
--no-suite=gtk:a11y \
|
|
||||||
--no-suite=gsk-compare-broadway
|
|
||||||
|
|
||||||
# Store the exit code for the CI run, but always
|
|
||||||
# generate the reports
|
|
||||||
exit_code=$?
|
|
||||||
;;
|
|
||||||
|
|
||||||
wayland)
|
|
||||||
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} \
|
|
||||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
|
||||||
--print-errorlogs \
|
|
||||||
--setup=${backend} \
|
|
||||||
--suite=gtk \
|
|
||||||
--no-suite=gtk:a11y \
|
|
||||||
--no-suite=gsk-compare-broadway
|
|
||||||
|
|
||||||
exit_code=$?
|
|
||||||
kill ${compositor}
|
|
||||||
;;
|
|
||||||
|
|
||||||
broadway)
|
|
||||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
|
||||||
|
|
||||||
${builddir}/gdk/broadway/gtk4-broadwayd :5 &
|
|
||||||
server=$!
|
|
||||||
export BROADWAY_DISPLAY=:5
|
|
||||||
|
|
||||||
meson test -C ${builddir} \
|
|
||||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
|
||||||
--print-errorlogs \
|
|
||||||
--setup=${backend} \
|
|
||||||
--suite=gtk \
|
|
||||||
--no-suite=gtk:a11y \
|
|
||||||
--no-suite=gsk-compare-opengl
|
|
||||||
|
|
||||||
# don't let Broadway failures fail the run, for now
|
|
||||||
exit_code=0
|
|
||||||
kill ${server}
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
cd ${builddir}
|
|
||||||
|
|
||||||
$srcdir/.gitlab-ci/meson-junit-report.py \
|
|
||||||
--project-name=gtk \
|
|
||||||
--backend=${backend} \
|
|
||||||
--job-id="${CI_JOB_NAME}" \
|
|
||||||
--output=report-${backend}.xml \
|
|
||||||
meson-logs/testlog-${backend}.json
|
|
||||||
$srcdir/.gitlab-ci/meson-html-report.py \
|
|
||||||
--project-name=gtk \
|
|
||||||
--backend=${backend} \
|
|
||||||
--job-id="${CI_JOB_NAME}" \
|
|
||||||
--reftest-output-dir="testsuite/reftests/output/${backend}" \
|
|
||||||
--output=report-${backend}.html \
|
|
||||||
meson-logs/testlog-${backend}.json
|
|
||||||
|
|
||||||
exit $exit_code
|
|
||||||
@@ -16,9 +16,6 @@ meson \
|
|||||||
-Dwayland-backend=true \
|
-Dwayland-backend=true \
|
||||||
-Dbroadway-backend=true \
|
-Dbroadway-backend=true \
|
||||||
-Dvulkan=yes \
|
-Dvulkan=yes \
|
||||||
-Dprofiler=true \
|
|
||||||
--werror \
|
|
||||||
${EXTRA_MESON_FLAGS:-} \
|
|
||||||
_build $srcdir
|
_build $srcdir
|
||||||
unset CCACHE_DISABLE
|
unset CCACHE_DISABLE
|
||||||
|
|
||||||
@@ -27,30 +24,9 @@ cd _build
|
|||||||
ninja
|
ninja
|
||||||
ccache --show-stats
|
ccache --show-stats
|
||||||
|
|
||||||
set +e
|
|
||||||
|
|
||||||
xvfb-run -a -s "-screen 0 1024x768x24" \
|
xvfb-run -a -s "-screen 0 1024x768x24" \
|
||||||
meson test \
|
meson test \
|
||||||
--timeout-multiplier 2 \
|
|
||||||
--print-errorlogs \
|
--print-errorlogs \
|
||||||
--suite=gtk \
|
--suite=gtk+ \
|
||||||
--no-suite=gtk:a11y
|
--no-suite=gtk+:gsk \
|
||||||
|
--no-suite=gtk+:a11y
|
||||||
# Save the exit code
|
|
||||||
exit_code=$?
|
|
||||||
|
|
||||||
# We always want to run the report generators
|
|
||||||
$srcdir/.gitlab-ci/meson-junit-report.py \
|
|
||||||
--project-name=gtk \
|
|
||||||
--job-id="${CI_JOB_NAME}" \
|
|
||||||
--output=report.xml \
|
|
||||||
meson-logs/testlog.json
|
|
||||||
|
|
||||||
$srcdir/.gitlab-ci/meson-html-report.py \
|
|
||||||
--project-name=GTK \
|
|
||||||
--job-id="${CI_JOB_NAME}" \
|
|
||||||
--reftest-output-dir="testsuite/reftests/output" \
|
|
||||||
--output=report.html \
|
|
||||||
meson-logs/testlog.json
|
|
||||||
|
|
||||||
exit $exit_code
|
|
||||||
|
|||||||
@@ -33,13 +33,6 @@ pacman --noconfirm -S --needed \
|
|||||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad \
|
mingw-w64-$MSYS2_ARCH-gst-plugins-bad \
|
||||||
mingw-w64-$MSYS2_ARCH-shared-mime-info
|
mingw-w64-$MSYS2_ARCH-shared-mime-info
|
||||||
|
|
||||||
# https://gitlab.gnome.org/GNOME/gtk/issues/2243
|
|
||||||
wget "https://gitlab.gnome.org/creiter/gitlab-ci-win32-runner-v2/raw/master/pango/mingw-w64-$MSYS2_ARCH-pango-git-1.44.7.90.ge48ae523-1-any.pkg.tar.zst"
|
|
||||||
pacman --noconfirm -U "mingw-w64-$MSYS2_ARCH-pango-git-1.44.7.90.ge48ae523-1-any.pkg.tar.zst"
|
|
||||||
|
|
||||||
# https://github.com/msys2/MINGW-packages/pull/6465
|
|
||||||
pacman --noconfirm -S --needed mingw-w64-$MSYS2_ARCH-brotli
|
|
||||||
|
|
||||||
mkdir -p _ccache
|
mkdir -p _ccache
|
||||||
export CCACHE_BASEDIR="$(pwd)"
|
export CCACHE_BASEDIR="$(pwd)"
|
||||||
export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
|
export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
|
||||||
@@ -48,15 +41,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
|
||||||
# FIXME: introspection disabled for now because of
|
|
||||||
# https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/340
|
|
||||||
meson \
|
meson \
|
||||||
-Dx11-backend=false \
|
-Denable-x11-backend=false \
|
||||||
-Dwayland-backend=false \
|
-Denable-wayland-backend=false \
|
||||||
-Dwin32-backend=true \
|
-Denable-win32-backend=true \
|
||||||
-Dvulkan=no \
|
-Dvulkan=no \
|
||||||
-Dintrospection=false \
|
|
||||||
--werror \
|
|
||||||
_build
|
_build
|
||||||
unset CCACHE_DISABLE
|
unset CCACHE_DISABLE
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@
|
|||||||
<!--
|
<!--
|
||||||
You should try and reproduce with the demos applications available
|
You should try and reproduce with the demos applications available
|
||||||
under the `demos` directory, or the test programs in the `tests` directory.
|
under the `demos` directory, or the test programs in the `tests` directory.
|
||||||
Alternatively, please attach a *small and self-contained* example
|
Alternatively, please attach a *small and self-contained* example that
|
||||||
*written in C* that exhibits the issue.
|
exhibits the issue.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## Current behavior
|
## Current behavior
|
||||||
@@ -23,10 +23,10 @@
|
|||||||
|
|
||||||
## Version information
|
## Version information
|
||||||
<!--
|
<!--
|
||||||
- Which version of GTK you are using
|
- Which version of GTK+ you are using
|
||||||
- What operating system and version
|
- What operating system and version
|
||||||
- For Linux, which distribution
|
- 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
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## Additional information
|
## Additional information
|
||||||
|
|||||||
@@ -13,10 +13,10 @@
|
|||||||
|
|
||||||
## Version information
|
## Version information
|
||||||
<!--
|
<!--
|
||||||
- Which version of GTK you are using
|
- Which version of GTK+ you are using
|
||||||
- What operating system and version
|
- What operating system and version
|
||||||
- for Linux, which distribution
|
- 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
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## Warnings
|
## Warnings
|
||||||
|
|||||||
240
CONTRIBUTING.md
@@ -1,139 +1,31 @@
|
|||||||
# Contribution guidelines
|
If you want to hack on the GTK+ project, you'll need to have the development
|
||||||
|
tools appropriate for your operating system, including:
|
||||||
Thank you for considering contributing to the GTK project!
|
|
||||||
|
|
||||||
These guidelines are meant for new contributors, regardless of their level
|
|
||||||
of proficiency; following them allows the maintainers of the GTK project to
|
|
||||||
more effectively evaluate your contribution, and provide prompt feedback to
|
|
||||||
you. Additionally, by following these guidelines you clearly communicate
|
|
||||||
that you respect the time and effort that the people developing GTK put into
|
|
||||||
managing the project.
|
|
||||||
|
|
||||||
GTK is a complex free software GUI toolkit, and it would not exist without
|
|
||||||
contributions from the free and open source software community. There are
|
|
||||||
many things that we value:
|
|
||||||
|
|
||||||
- bug reporting and fixing
|
|
||||||
- documentation and examples
|
|
||||||
- tests
|
|
||||||
- new features
|
|
||||||
|
|
||||||
Please, do not use the issue tracker for support questions. If you have
|
|
||||||
questions on how to use GTK effectively, you can use:
|
|
||||||
|
|
||||||
- the `#gtk` IRC channel on irc.gnome.org
|
|
||||||
- the [gtk tag on the GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
|
|
||||||
|
|
||||||
You can also look at the GTK tag on [Stack
|
|
||||||
Overflow](https://stackoverflow.com/questions/tagged/gtk).
|
|
||||||
|
|
||||||
The issue tracker is meant to be used for actionable issues only.
|
|
||||||
|
|
||||||
## How to report bugs
|
|
||||||
|
|
||||||
### Security issues
|
|
||||||
|
|
||||||
You should not open a new issue for security related questions.
|
|
||||||
|
|
||||||
When in doubt, send an email to the [security](mailto:security@gnome.org)
|
|
||||||
mailing list.
|
|
||||||
|
|
||||||
### Bug reports
|
|
||||||
|
|
||||||
If you're reporting a bug make sure to list:
|
|
||||||
|
|
||||||
0. which version of GTK are you using?
|
|
||||||
0. which operating system are you using?
|
|
||||||
0. the necessary steps to reproduce the issue
|
|
||||||
0. the expected outcome
|
|
||||||
0. a description of the behavior; screenshots are also welcome
|
|
||||||
0. a small, self-contained example exhibiting the behavior; if this
|
|
||||||
is not available, try reproducing the issue using the GTK examples
|
|
||||||
or interactive tests
|
|
||||||
|
|
||||||
If the issue includes a crash, you should also include:
|
|
||||||
|
|
||||||
0. the eventual warnings printed on the terminal
|
|
||||||
0. a backtrace, obtained with tools such as GDB or LLDB
|
|
||||||
|
|
||||||
For small issues, such as:
|
|
||||||
|
|
||||||
- spelling/grammar fixes in the documentation
|
|
||||||
- typo correction
|
|
||||||
- comment clean ups
|
|
||||||
- changes to metadata files (CI, `.gitignore`)
|
|
||||||
- build system changes
|
|
||||||
- source tree clean ups and reorganizations
|
|
||||||
|
|
||||||
You should directly open a merge request instead of filing a new issue.
|
|
||||||
|
|
||||||
### Features and enhancements
|
|
||||||
|
|
||||||
Feature discussion can be open ended and require high bandwidth channels; if
|
|
||||||
you are proposing a new feature on the issue tracker, make sure to make
|
|
||||||
an actionable proposal, and list:
|
|
||||||
|
|
||||||
0. what you're trying to achieve
|
|
||||||
0. prior art, in other toolkits or applications
|
|
||||||
0. design and theming changes
|
|
||||||
|
|
||||||
If you're proposing the integration of new features it helps to have
|
|
||||||
multiple applications using shared or similar code, especially if they have
|
|
||||||
iterated over it various times.
|
|
||||||
|
|
||||||
Each feature should also come fully documented, and with tests.
|
|
||||||
|
|
||||||
## Your first contribution
|
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
|
|
||||||
If you want to contribute to the GTK project, you will need to have the
|
|
||||||
development tools appropriate for your operating system, including:
|
|
||||||
|
|
||||||
- Python 3.x
|
- Python 3.x
|
||||||
- Meson
|
- Meson
|
||||||
- Ninja
|
- Ninja
|
||||||
- Gettext (19.7 or newer)
|
- Gettext (19.7 or newer)
|
||||||
- a [C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
|
- a C99 compatible compiler
|
||||||
|
|
||||||
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 here:
|
||||||
|
|
||||||
The GTK project uses GitLab for code hosting and for tracking issues. More
|
* https://developer.gnome.org
|
||||||
information about using GitLab can be found [on the GNOME
|
|
||||||
wiki](https://wiki.gnome.org/GitLab).
|
|
||||||
|
|
||||||
### Dependencies
|
Information about using GitLab with GNOME can be found here:
|
||||||
|
|
||||||
In order to get GTK from Git installed on your system, you need to have the
|
* https://wiki.gnome.org/GitLab
|
||||||
required versions of all the software dependencies required by GTK; typically,
|
|
||||||
this means a recent version of GLib, Cairo, Pango, and ATK, as well as the
|
|
||||||
platform-specific dependencies for the windowing system you are using (Wayland,
|
|
||||||
X11, Windows, or macOS).
|
|
||||||
|
|
||||||
The core dependencies for GTK are:
|
In order to get Git GTK+ installed on your system, you need to have the
|
||||||
|
required versions of all the GTK+ dependencies; typically, this means a
|
||||||
- [GLib, GObject, and GIO](https://gitlab.gnome.org/GNOME/glib)
|
recent version of GLib, Cairo, Pango, and ATK, as well as the platform
|
||||||
- [Cairo](http://cairographics.org)
|
specific dependencies for the windowing system you are using (Wayland, X11,
|
||||||
- [Pango](https://gitlab.gnome.org/GNOME/pango)
|
Windows, or macOS).
|
||||||
- [GdkPixbuf](https://gitlab.gnome.org/GNOME/gdk-pixbuf)
|
|
||||||
- [Epoxy](https://github.com/anholt/libepoxy)
|
|
||||||
- [ATK](https://gitlab.gnome.org/GNOME/atk)
|
|
||||||
- [Graphene](https://github.com/ebassi/graphene)
|
|
||||||
|
|
||||||
GTK will attempt to download and build some of these dependencies if it
|
|
||||||
cannot find them on your system.
|
|
||||||
|
|
||||||
Additionally, you may want to look at projects that create a development
|
|
||||||
environment for you, like [jhbuild](https://wiki.gnome.org/HowDoI/Jhbuild)
|
|
||||||
and [gvsbuild](https://github.com/wingtk/gvsbuild).
|
|
||||||
|
|
||||||
### Getting started
|
|
||||||
|
|
||||||
You should start by forking the GTK repository from the GitLab web UI, and
|
You should start by forking the GTK repository from the GitLab web UI, and
|
||||||
cloning from your fork:
|
cloning from your fork:
|
||||||
|
|
||||||
```sh
|
```ssh
|
||||||
$ git clone https://gitlab.gnome.org/yourusername/gtk.git
|
$ git clone https://gitlab.gnome.org/yourusername/gtk.git
|
||||||
$ cd gtk
|
$ cd gtk
|
||||||
```
|
```
|
||||||
@@ -146,7 +38,7 @@ $ git clone git@gitlab.gnome.org:GNOME/gtk.git
|
|||||||
$ cd gtk
|
$ 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
|
||||||
@@ -155,6 +47,11 @@ $ cd _builddir
|
|||||||
$ ninja
|
$ ninja
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Note**: For information about submitting patches and pushing changes
|
||||||
|
to Git, see the `README.md` and `README.commits` files. In particular,
|
||||||
|
don't, under any circumstances, push anything to Git before reading and
|
||||||
|
understanding `README.commmits`.
|
||||||
|
|
||||||
Typically, you should work on your own branch:
|
Typically, you should work on your own branch:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -163,99 +60,6 @@ $ 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. The [CODE-OWNERS](./docs-CODE-OWNERS)
|
||||||
|
document contains the list of core contributors to GTK and the areas for
|
||||||
### Code reviews
|
which they are responsible.
|
||||||
|
|
||||||
Each contribution is reviewed by the core developers of the GTK project.
|
|
||||||
|
|
||||||
The [CODEOWNERS](./docs/CODEOWNERS) document contains the list of core
|
|
||||||
contributors to GTK and the areas for which they are responsible; you
|
|
||||||
should ensure to receive their review and signoff on your changes.
|
|
||||||
|
|
||||||
### Commit messages
|
|
||||||
|
|
||||||
The expected format for git commit messages is as follows:
|
|
||||||
|
|
||||||
```plain
|
|
||||||
Short explanation of the commit
|
|
||||||
|
|
||||||
Longer explanation explaining exactly what's changed, whether any
|
|
||||||
external or private interfaces changed, what bugs were fixed (with bug
|
|
||||||
tracker reference if applicable) and so forth. Be concise but not too
|
|
||||||
brief.
|
|
||||||
|
|
||||||
Closes #1234
|
|
||||||
```
|
|
||||||
|
|
||||||
- Always add a brief description of the commit to the _first_ line of
|
|
||||||
the commit and terminate by two newlines (it will work without the
|
|
||||||
second newline, but that is not nice for the interfaces).
|
|
||||||
|
|
||||||
- First line (the brief description) must only be one sentence and
|
|
||||||
should start with a capital letter unless it starts with a lowercase
|
|
||||||
symbol or identifier. Don't use a trailing period either. Don't exceed
|
|
||||||
72 characters.
|
|
||||||
|
|
||||||
- The main description (the body) is normal prose and should use normal
|
|
||||||
punctuation and capital letters where appropriate. Consider the commit
|
|
||||||
message as an email sent to the developers (or yourself, six months
|
|
||||||
down the line) detailing **why** you changed something. There's no need
|
|
||||||
to specify the **how**: the changes can be inlined.
|
|
||||||
|
|
||||||
- When committing code on behalf of others use the `--author` option, e.g.
|
|
||||||
`git commit -a --author "Joe Coder <joe@coder.org>"` and `--signoff`.
|
|
||||||
|
|
||||||
- If your commit is addressing an issue, use the
|
|
||||||
[GitLab syntax](https://docs.gitlab.com/ce/user/project/issues/automatic_issue_closing.html)
|
|
||||||
to automatically close the issue when merging the commit with the upstream
|
|
||||||
repository:
|
|
||||||
|
|
||||||
```plain
|
|
||||||
Closes #1234
|
|
||||||
Fixes #1234
|
|
||||||
Closes: https://gitlab.gnome.org/GNOME/gtk/issues/1234
|
|
||||||
```
|
|
||||||
|
|
||||||
- If you have a merge request with multiple commits and none of them
|
|
||||||
completely fixes an issue, you should add a reference to the issue in
|
|
||||||
the commit message, e.g. `Bug: #1234`, and use the automatic issue
|
|
||||||
closing syntax in the description of the merge request.
|
|
||||||
|
|
||||||
### Commit access to the GTK repository
|
|
||||||
|
|
||||||
GTK is part of the GNOME infrastructure. At the current time, any
|
|
||||||
person with write access to the GNOME repository can merge changes to
|
|
||||||
GTK. This is a good thing, in that it encourages many people to work
|
|
||||||
on GTK, and progress can be made quickly. However, GTK is a fairly
|
|
||||||
large and complicated project on which many other things depend, so to
|
|
||||||
avoid unnecessary breakage, and to take advantage of the knowledge
|
|
||||||
about GTK that has been built up over the years, we'd like to ask
|
|
||||||
people committing to GTK to follow a few rules:
|
|
||||||
|
|
||||||
0. Ask first. If your changes are major, or could possibly break existing
|
|
||||||
code, you should always ask. If your change is minor and you've been
|
|
||||||
working on GTK for a while it probably isn't necessary to ask. But when
|
|
||||||
in doubt, ask. Even if your change is correct, somebody may know a
|
|
||||||
better way to do things. If you are making changes to GTK, you should
|
|
||||||
be subscribed to the [gtk-devel](https://mail.gnome.org/mailman/listinfo/gtk-devel-list)
|
|
||||||
mailing list; this is a good place to ask about intended changes.
|
|
||||||
The `#gtk` IRC channel on irc.gnome.org is also a good place to find GTK
|
|
||||||
developers to discuss changes, but if you live outside of the EU/US time
|
|
||||||
zones, an email to the gtk-devel mailing list is the most certain and
|
|
||||||
preferred method.
|
|
||||||
|
|
||||||
0. Ask _first_.
|
|
||||||
|
|
||||||
0. Always write a meaningful commit message. Changes without a sufficient
|
|
||||||
commit message will be reverted.
|
|
||||||
|
|
||||||
0. Never push to the `master` branch, or any stable branches, directly; you
|
|
||||||
should always go through a merge request, to ensure that the code is
|
|
||||||
tested on the CI infrastructure at the very least. A merge request is
|
|
||||||
also the proper place to get a comprehensive code review from the core
|
|
||||||
developers of GTK.
|
|
||||||
|
|
||||||
If you have been contributing to GTK for a while and you don't have commit
|
|
||||||
access to the repository, you may ask to obtain it following the [GNOME account
|
|
||||||
process](https://wiki.gnome.org/AccountsTeam/NewAccounts).
|
|
||||||
|
|||||||
611
NEWS
@@ -1,612 +1,3 @@
|
|||||||
Overview of Changes in GTK 3.99.0
|
|
||||||
=================================
|
|
||||||
|
|
||||||
* Add GtkEditableLabel, a label that can be edited
|
|
||||||
|
|
||||||
* Add GtkBookmarkList, a list model for bookmarks
|
|
||||||
|
|
||||||
* Add GtkStringList, a list model for strings
|
|
||||||
|
|
||||||
* Add GtkBitset, and use it for representing selections
|
|
||||||
|
|
||||||
* GtkTreeView:
|
|
||||||
- Make cell editing work again
|
|
||||||
|
|
||||||
* GtkSpinButton:
|
|
||||||
- Make autosizing work again
|
|
||||||
|
|
||||||
* Printing:
|
|
||||||
- Use GtkDropDown in the print dialog
|
|
||||||
|
|
||||||
* GtkApplication
|
|
||||||
- Support opening files on OS X
|
|
||||||
|
|
||||||
* GtkFileChooser:
|
|
||||||
- Fix libcloudproviders support
|
|
||||||
- Turn GtkFileFilter into a GtkFilter
|
|
||||||
- Simplify the api
|
|
||||||
|
|
||||||
* GtkGridView, GtkListView:
|
|
||||||
- Improve scrolling behavior
|
|
||||||
- Autoscroll and autoexpand during DND
|
|
||||||
|
|
||||||
* GtkScrolledWindow:
|
|
||||||
- Make autoscrolling work again
|
|
||||||
|
|
||||||
* GtkFilterListModel:
|
|
||||||
- Add incremental filtering
|
|
||||||
|
|
||||||
* GtkSortListModel:
|
|
||||||
- Use timsort
|
|
||||||
- Add various tweaks that massively speed up sorting
|
|
||||||
- Add incremental sorting
|
|
||||||
|
|
||||||
* GtkWidget:
|
|
||||||
- Massively speed up action handling
|
|
||||||
|
|
||||||
* GtkEntry:
|
|
||||||
- Make entry completion work again
|
|
||||||
- Drop action support from GtkEntryCompletion
|
|
||||||
|
|
||||||
* Inspector:
|
|
||||||
- Improve list model support
|
|
||||||
- Add direct navigation between objects
|
|
||||||
|
|
||||||
* GDK:
|
|
||||||
- Compress scroll events
|
|
||||||
- Keep a scroll history
|
|
||||||
- Clean up GdkDevice api
|
|
||||||
- Improve frame clock accuracy
|
|
||||||
- Add a new macOS backend
|
|
||||||
|
|
||||||
* GSK:
|
|
||||||
- Use GL_ARB_framebuffer_object
|
|
||||||
|
|
||||||
* gtk-demo:
|
|
||||||
- Add incremental refill to the color grid
|
|
||||||
- Improve performance of the color grid
|
|
||||||
- Add an incrementally filtering word list
|
|
||||||
- Improve the sidebar
|
|
||||||
|
|
||||||
* Install print-editor as another demo
|
|
||||||
|
|
||||||
* Translation updates
|
|
||||||
Basque
|
|
||||||
Catalan
|
|
||||||
Chinese
|
|
||||||
Japanese
|
|
||||||
Kazakh
|
|
||||||
Lithuanian
|
|
||||||
Polish
|
|
||||||
Romanian
|
|
||||||
Spanish
|
|
||||||
Turkish
|
|
||||||
Ukrainian
|
|
||||||
|
|
||||||
|
|
||||||
Overview of Changes in GTK 3.98.5
|
|
||||||
=================================
|
|
||||||
|
|
||||||
* Introduce new list widgets and supporting infrastructure.
|
|
||||||
The main APIs are:
|
|
||||||
- GtkListView
|
|
||||||
- GtkGridView
|
|
||||||
- GtkColumnView and GtkColumnViewColumn
|
|
||||||
- GtkDropDown
|
|
||||||
- GtkListItemFactory and implementations
|
|
||||||
- GtkExpression
|
|
||||||
- GtkFilter and subclasses, and GtkFilterListModel
|
|
||||||
- GtkSorter and subclasses, and GtkSortListModel
|
|
||||||
- GtkSelectionModel and subclasses
|
|
||||||
- GtkTreeListModel, GtkTreeExpander and GtkTreeListRowSorter
|
|
||||||
|
|
||||||
* GtkFileChooser:
|
|
||||||
- Add a tracker3-based search engine implementation
|
|
||||||
- Rate-limit updates from the trash monitor
|
|
||||||
|
|
||||||
* GtkWindow:
|
|
||||||
- Redo the css node setup. There is now a single 'window' node
|
|
||||||
- Fix rounded corners on tiled windows
|
|
||||||
|
|
||||||
* GtkApplication:
|
|
||||||
- Drop app menu support. Menubar support is still there
|
|
||||||
|
|
||||||
* GtkFixed:
|
|
||||||
- Change coordinate APIs to take doubles
|
|
||||||
|
|
||||||
* GtkOverlay:
|
|
||||||
- Make GtkOverlayLayout public
|
|
||||||
|
|
||||||
* GtkTooltips:
|
|
||||||
- Fix line wrapping of tooltips
|
|
||||||
|
|
||||||
* Shortcuts:
|
|
||||||
- Fix mnemonic cycling
|
|
||||||
- Fix using '0' as a mnemonic
|
|
||||||
|
|
||||||
* Menus:
|
|
||||||
- Differentiate keypad keys in accelerators
|
|
||||||
|
|
||||||
* GtkIMContext:
|
|
||||||
- Add gtk_im_context_filter_key to allow event reinjection
|
|
||||||
|
|
||||||
* Themes:
|
|
||||||
- Adwaita: Limit the scope of backdrop
|
|
||||||
|
|
||||||
* Accessibility:
|
|
||||||
- Clean up and reorganize the code to prepare for the
|
|
||||||
dropping of ATK
|
|
||||||
|
|
||||||
* GDK:
|
|
||||||
- Drop unused enum and struct definitions from headers
|
|
||||||
- Make keymap translation API public again. Still needed
|
|
||||||
- Frameclock: Always use compositor refresh rate info
|
|
||||||
- Frameclock: Use quadratic correction for frame time jitter
|
|
||||||
- Frameclock: Ensure monotonicity
|
|
||||||
- Frameclock: Track resason for paint
|
|
||||||
- X11: Improve sync when the Nvidia driver is used
|
|
||||||
|
|
||||||
* GSK:
|
|
||||||
- GL renderer: Fix blurred outset shadows
|
|
||||||
- GL renderer: handle nested transform nodes properly
|
|
||||||
- GL renderer: Optimize clip handling
|
|
||||||
|
|
||||||
* gtk-demo:
|
|
||||||
- Improve the Drag-and-Drop demo with proper drag icons
|
|
||||||
- Don't show the main window if --run is given
|
|
||||||
- Add demos for list widgets and GtkDropDrown
|
|
||||||
|
|
||||||
* Documentation:
|
|
||||||
- Convert freestanding sections to markdown
|
|
||||||
- Drop the glossary
|
|
||||||
- Expand and improve the migration guide
|
|
||||||
|
|
||||||
* Build:
|
|
||||||
- We require pandoc now, for building the documentation
|
|
||||||
- Require Pango 1.45
|
|
||||||
|
|
||||||
* Translation updates:
|
|
||||||
Polish
|
|
||||||
Romanian
|
|
||||||
Slovenian
|
|
||||||
Turkish
|
|
||||||
Ukrainian
|
|
||||||
|
|
||||||
|
|
||||||
Overview of Changes in GTK 3.98.4
|
|
||||||
=================================
|
|
||||||
|
|
||||||
* Themes
|
|
||||||
- Refine menu styling
|
|
||||||
- Tweak visible focus behavior
|
|
||||||
- HighConstrast: Add public colors
|
|
||||||
- HighContrast: Fix scale borders
|
|
||||||
|
|
||||||
* CSS:
|
|
||||||
- Drop the nonstandard -gtk-icon-theme property
|
|
||||||
- Add a system_setting_changed vfunc to propagate global changes
|
|
||||||
|
|
||||||
* Untangle titlebars from windows:
|
|
||||||
- Add a GtkWindowControls widget
|
|
||||||
- Add a GtkWindowHandle widget
|
|
||||||
- Add actions for window menu items
|
|
||||||
- Remove app menu fallback from GtkHeaderBar
|
|
||||||
- Remove title and subtitle properties from GtkHeaderBar,
|
|
||||||
rename custom-title to title-widget
|
|
||||||
|
|
||||||
* GtkWidget
|
|
||||||
- Add a focusable property
|
|
||||||
|
|
||||||
* GtkPopover:
|
|
||||||
- Fix (re-)positioning issues
|
|
||||||
|
|
||||||
* GtkStack:
|
|
||||||
- Drop the homogeneous property
|
|
||||||
- Add a use-underline property to stack pages
|
|
||||||
|
|
||||||
* GtkScale:
|
|
||||||
- Make area around the trough clickable
|
|
||||||
|
|
||||||
* GtkScrolledWindow:
|
|
||||||
- Fix kinetic scrolling
|
|
||||||
|
|
||||||
* GtkTreeView:
|
|
||||||
- Break reference cycles in unroot
|
|
||||||
|
|
||||||
* Drop GtkBin and GtkContainer. All existing GtkBin subclasses
|
|
||||||
have grown a child property with setter and getter. All
|
|
||||||
existing GtkContainer subclasses have grown widget-specific
|
|
||||||
remove (and in some cases, add) functions. <child> in ui
|
|
||||||
files continues to work as before
|
|
||||||
|
|
||||||
* Replace gtk_widget_destroy by gtk_window_destroy
|
|
||||||
|
|
||||||
* Drop the ::size-allocate signal. Use a GtkWidgetPaintable
|
|
||||||
if you need to be informed about changes to a widgets
|
|
||||||
content or size
|
|
||||||
|
|
||||||
* Remove gtk_dialog_run
|
|
||||||
|
|
||||||
* GDK:
|
|
||||||
- Wayland: Provide a builtin cursor of last resort
|
|
||||||
- Change the monitor api to use a GListModel
|
|
||||||
|
|
||||||
* GSK:
|
|
||||||
- Don't include renderer-specific headers automatically
|
|
||||||
- GL: Fix nested rounded clips
|
|
||||||
|
|
||||||
* Introspection:
|
|
||||||
- Assorted annotation fixes
|
|
||||||
|
|
||||||
* Inspector:
|
|
||||||
- Preview media resources
|
|
||||||
- Show media backend information
|
|
||||||
|
|
||||||
* gtk4-widget-factory:
|
|
||||||
- Add GtkVideo
|
|
||||||
- Add text styles
|
|
||||||
- Add a print dialog
|
|
||||||
- Add a password entry
|
|
||||||
- Improve toolbar styling
|
|
||||||
- Revamp transition effects
|
|
||||||
|
|
||||||
* gtk4-demo:
|
|
||||||
- Replace some demos
|
|
||||||
|
|
||||||
* Translation updates:
|
|
||||||
Chinese (Taiwan)
|
|
||||||
Esperanto
|
|
||||||
Japanese
|
|
||||||
Romanian
|
|
||||||
Spanish
|
|
||||||
Ukrainian
|
|
||||||
|
|
||||||
|
|
||||||
Overview of Changes in GTK 3.98.3
|
|
||||||
=================================
|
|
||||||
|
|
||||||
* GtkEntry:
|
|
||||||
- Support setting attributes in ui files
|
|
||||||
|
|
||||||
* GtkScaleButton:
|
|
||||||
- Don't derive from GtkButton
|
|
||||||
|
|
||||||
* GtkAboutDialog:
|
|
||||||
- Support more common licenses
|
|
||||||
|
|
||||||
* GtkEmojiChooser:
|
|
||||||
- Improve keyboard navigation
|
|
||||||
|
|
||||||
* GtkLabel:
|
|
||||||
- Remove pattern API
|
|
||||||
|
|
||||||
* GtkAspectFrame:
|
|
||||||
- Modernize and simplify
|
|
||||||
|
|
||||||
* Chooser buttons:
|
|
||||||
- Make dialogs modal by default
|
|
||||||
|
|
||||||
* Various widgets:
|
|
||||||
- Replace shadow-type and relief properties by
|
|
||||||
a simpler has-frame
|
|
||||||
|
|
||||||
* CSS:
|
|
||||||
- Use :focus-visible instead of :focus(visible)
|
|
||||||
- Add support for :focus-within
|
|
||||||
|
|
||||||
* Focus handling
|
|
||||||
- Fix crossing event generation
|
|
||||||
- Fix focus handling in various widgets
|
|
||||||
- Change :can-focus to be recursive
|
|
||||||
- Fix GtkWindow:is-active setting
|
|
||||||
|
|
||||||
* Scrolling
|
|
||||||
- gtk_container_set_focus_[hv]adjustment has been removed
|
|
||||||
- gtk_viewport_set_scroll_to_focus has been added
|
|
||||||
|
|
||||||
* Accessibility:
|
|
||||||
- Add a cursor-aspect-ratio setting
|
|
||||||
- Set focus-related states properly
|
|
||||||
|
|
||||||
* Themes:
|
|
||||||
- Use blue focus outlines more
|
|
||||||
- Numerous minor improvements
|
|
||||||
|
|
||||||
* Wayland:
|
|
||||||
- Fix .Compose file loading
|
|
||||||
- Support popup repositioning
|
|
||||||
- Fix problems with autohide popovers
|
|
||||||
|
|
||||||
* GDK:
|
|
||||||
- Remove GdkKeymap from public API, replaced by
|
|
||||||
GdkDevice properties
|
|
||||||
- Add full keyboard translation state to key events
|
|
||||||
- Simplify modifier support, drop GdkModifierIntent
|
|
||||||
- Move key event matching to GDK
|
|
||||||
- Add GdkSurface::enter/leave-monitor signals
|
|
||||||
- Turn GskEvent into a derivable type, and make
|
|
||||||
it introspectable
|
|
||||||
|
|
||||||
* GSK:
|
|
||||||
- Turn GskRenderNode into a derivable type, and make
|
|
||||||
it introspectable
|
|
||||||
- Fall back to cairo if compiling shaders fails
|
|
||||||
|
|
||||||
* Translation updates:
|
|
||||||
- Japanese
|
|
||||||
- Lithuanian
|
|
||||||
- Turkish
|
|
||||||
|
|
||||||
|
|
||||||
Overview of Changes in GTK 3.98.2
|
|
||||||
=================================
|
|
||||||
|
|
||||||
* Introduce GtkShortcutController, and replace key bindings,
|
|
||||||
mnemonics and accelerators by GtkShortcut
|
|
||||||
|
|
||||||
* Derive the HighContrast theme from Adwaita
|
|
||||||
|
|
||||||
* GtkMenuButton: Add a use-underline property
|
|
||||||
|
|
||||||
* GtkTreeView: Fix cell editing
|
|
||||||
|
|
||||||
* Add gdk_toplevel_inhibit_system_shortcuts
|
|
||||||
|
|
||||||
* gtk-demo: Fix issues in multiple demos
|
|
||||||
|
|
||||||
* Translation updates:
|
|
||||||
Polish
|
|
||||||
|
|
||||||
|
|
||||||
Overview of Changes in GTK 3.98.1
|
|
||||||
=================================
|
|
||||||
|
|
||||||
* GtkFileChooser:
|
|
||||||
- Remove filename/uri api
|
|
||||||
- Drop extra-widget
|
|
||||||
- Remove overwrite confirmation
|
|
||||||
- Remove show-hidden property
|
|
||||||
- Remove local-only property
|
|
||||||
- Remove GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
|
|
||||||
- The portal file chooser supports selecting folders
|
|
||||||
|
|
||||||
* GtkSpinner:
|
|
||||||
- Rename active property to spinning
|
|
||||||
|
|
||||||
* GtkRevealer:
|
|
||||||
- Fix size allocation at small scales
|
|
||||||
|
|
||||||
* GtkPopover:
|
|
||||||
- Drop :relative-to, it is always the :parent now
|
|
||||||
|
|
||||||
* GtkWindow:
|
|
||||||
- Drop window-type, it is always a regular toplevel
|
|
||||||
|
|
||||||
* GtkWidget:
|
|
||||||
- Drop expand property
|
|
||||||
- Drop margin property
|
|
||||||
- Drop gtk_grab_add, gtk_device_grab_add
|
|
||||||
|
|
||||||
* GtkTextView:
|
|
||||||
- Support overlines in GtkTextTag
|
|
||||||
- Support visible spaces in GtkTextTag
|
|
||||||
- Support hyphenation control in GtkTextTag
|
|
||||||
|
|
||||||
* Split GtkEventControllerFocus from GtkEventControllerKey
|
|
||||||
|
|
||||||
* DND:
|
|
||||||
- Fix local DND to avoid serialization
|
|
||||||
- Add new content provider constructors
|
|
||||||
- Split GtkDropTargetAsync and GtkDropTarget
|
|
||||||
- Group DND events into event sequences
|
|
||||||
- Propagate DND events like motion events
|
|
||||||
- Introduce GtkDropControllerMotion
|
|
||||||
- Remove GtkSelectionData
|
|
||||||
|
|
||||||
* Performance:
|
|
||||||
- Clean up profiler marks
|
|
||||||
- Share GL programs between renderers
|
|
||||||
|
|
||||||
* GDK:
|
|
||||||
- Drop gdk_surface_new_temp
|
|
||||||
- Make GdkEvent an immutable boxed type, not an object
|
|
||||||
- Remove GdkAtom and property- and selection-related apis
|
|
||||||
- Introduce GdkPopup and GdkToplevel interfaces
|
|
||||||
- Implement them in backend-specific surface subtypes
|
|
||||||
- Rename gdk_surface_input_shape_combine_region to
|
|
||||||
gdk_surface_set_input_region
|
|
||||||
- Drop X11-only concepts such as sticky or keep-below
|
|
||||||
|
|
||||||
* OS X: Fix OpenGL extension detection
|
|
||||||
|
|
||||||
* Broadway: implement scaling
|
|
||||||
|
|
||||||
* Translation updates:
|
|
||||||
Dutch
|
|
||||||
Japanese
|
|
||||||
Persian
|
|
||||||
|
|
||||||
|
|
||||||
Overview of Changes in GTK 3.98.0
|
|
||||||
=================================
|
|
||||||
|
|
||||||
While this release gets significantly closer to what we aim for in GTK 4,
|
|
||||||
there are still a few big items outstanding that we are currently working
|
|
||||||
on:
|
|
||||||
|
|
||||||
- Event controllers for keyboard shortcuts
|
|
||||||
- Movable popovers
|
|
||||||
- Row-recycling list and grid views
|
|
||||||
- Revamped accessibility infrastructure
|
|
||||||
- Animation API
|
|
||||||
|
|
||||||
We will do further 3.98.x snapshots as these land.
|
|
||||||
|
|
||||||
*****************
|
|
||||||
|
|
||||||
* The DND refactoring has been completed. The GTK API for DND has been turned
|
|
||||||
into event controllers: GtkDragSource and GtkDropTarget. Support for file
|
|
||||||
transfers via file transfer portal has been added for both DND and the clipboard.
|
|
||||||
|
|
||||||
* Child surfaces have been removed. GDK only supports toplevel and popup surfaces
|
|
||||||
now. The client-side window implementation has been removed too. On the GTK side,
|
|
||||||
the GtkNative interface has been introduced for widgets that have their own
|
|
||||||
surface. This cleanup is not 100% complete yet.
|
|
||||||
|
|
||||||
* Global positions and related apis such as gdk_surface_move are no longer available.
|
|
||||||
|
|
||||||
* A constraint-based layout manager has been added.
|
|
||||||
|
|
||||||
* Many classes have been made explicitly non-subclassable, and the widget hierarchy
|
|
||||||
has been simplified, by making widgets derive directly from GtkWidget instead of
|
|
||||||
a container.
|
|
||||||
|
|
||||||
* Menu-related changes:
|
|
||||||
- GtkMenu, GtkMenuBar and related classes have been removed. They are being replaced
|
|
||||||
by GMenu and popover-based variants. Popover menus can now do traditional, nested
|
|
||||||
menus, and model buttons show accelerators.
|
|
||||||
- Context menus are no longer created with ::populate-popup signals, but use menu
|
|
||||||
models and actions.
|
|
||||||
- Widget actions can be created in class_init, with gtk_widget_class_install_action.
|
|
||||||
- GtkToolbar has been removed as well.
|
|
||||||
|
|
||||||
* Text-related changed:
|
|
||||||
- Text cursor blinking has been made smooth.
|
|
||||||
- GtkTextView is caching rendernodes for the visible text range now, improving the
|
|
||||||
scrolling performance of text.
|
|
||||||
- Add a simple undo stack for text edits has been added.
|
|
||||||
|
|
||||||
* The native Win32 filechooser backend supports choices.
|
|
||||||
|
|
||||||
* GtkTreeView renders tree and grid lines with textures.
|
|
||||||
|
|
||||||
* GtkEmojiChooser has been made public.
|
|
||||||
|
|
||||||
* GtkGestureMultiPress has been renamed to GtkGestureClick.
|
|
||||||
|
|
||||||
* GtkWidget has api to handle style classes: gtk_widget_add_style_class.
|
|
||||||
This is the first step towards moving away from GtkStyleContext.
|
|
||||||
|
|
||||||
* X11-specific changes:
|
|
||||||
- XI2 is now mandatory
|
|
||||||
- The xim input method has been removed
|
|
||||||
|
|
||||||
* Wayland-specific changes:
|
|
||||||
- The loading of cursor themes has been improved to load cursors on demand,
|
|
||||||
and no longer relies on libwayland-cursor.
|
|
||||||
|
|
||||||
* The GL renderer is now sharing icon and glyph caches for all surfaces,
|
|
||||||
and has better support for blurring and shadow rendering.
|
|
||||||
|
|
||||||
* Performance-related changes:
|
|
||||||
- GTK provides profiling information for Sysprof when launched with GTK_TRACE=1.
|
|
||||||
- Css computation has been optimized
|
|
||||||
- Css lookups are using a Bloom filter
|
|
||||||
- Icon loading IO has been moved to a thread
|
|
||||||
|
|
||||||
|
|
||||||
Overview of Changes in GTK+ 3.96.0
|
|
||||||
==================================
|
|
||||||
|
|
||||||
* DND has been refactored. There are now separate GdkDrag and GdkDrop
|
|
||||||
objects. This work is still incomplete
|
|
||||||
|
|
||||||
* The GDK_SURFACE_SUBSURFACE surface type has been removed.
|
|
||||||
|
|
||||||
* Use of child surfaces has been greatly reduced. This work is still
|
|
||||||
incomplete
|
|
||||||
|
|
||||||
* The use of global coordinates in GDK apis has been reduced. This
|
|
||||||
work is still incomplete
|
|
||||||
|
|
||||||
* Events have been simplified and are used just for input
|
|
||||||
- expose events have been replaced by a GdkSurface::render signal
|
|
||||||
- configure events have been replaced by a GdkSurface::size-changed signal
|
|
||||||
- map events have been replaced by a GdkSurface::mapped property
|
|
||||||
- gdk_event_handler_set has been replaced by a GdkSurface::event signal
|
|
||||||
- key events no longer contain a string
|
|
||||||
- events on unmapped widgets are ignored
|
|
||||||
|
|
||||||
* Warping the pointer is no longer supported
|
|
||||||
|
|
||||||
* The Wayland backend now uses the Settings portal for GtkSettings
|
|
||||||
|
|
||||||
* The Wayland input module uses the text-input-unstable-v3 protocol
|
|
||||||
|
|
||||||
* The Broadway backend has been rewritten to work well with GSK
|
|
||||||
|
|
||||||
* The color chooser has a color picker
|
|
||||||
|
|
||||||
* GtkApplication tracks screensaver state and has a ::query-end signal
|
|
||||||
|
|
||||||
* The file chooser portal backend supports file filters
|
|
||||||
|
|
||||||
* A number of list models have been introduced, for internal use
|
|
||||||
and as public api:
|
|
||||||
- GtkMapListModel
|
|
||||||
- GtkSliceListModel
|
|
||||||
- GtkSortListModel
|
|
||||||
- GtkSelectionModel
|
|
||||||
- GtkSingleSelection
|
|
||||||
|
|
||||||
* Support for tabular menus and combo boxes has been dropped
|
|
||||||
|
|
||||||
* Key themes are no longer supported
|
|
||||||
|
|
||||||
* GtkInvisible has been dropped
|
|
||||||
|
|
||||||
* A GtkRoot interface has been added that is currently implemented
|
|
||||||
just by GtkWindow. This work is incomplete
|
|
||||||
|
|
||||||
* GtkWidgets can transform their children using projective linear
|
|
||||||
transformations. This functionality is available in CSS and
|
|
||||||
as GskTransform argument to gtk_widget_allocate. GtkFixed is
|
|
||||||
a container that exposes this functionality. For examples of this,
|
|
||||||
see the swing transition of GtkRevealer, the rotate transitions
|
|
||||||
of GtkStack or the Fixed Layout example in gtk-demo.
|
|
||||||
|
|
||||||
* GtkEntry functionality has been moved into a new GtkText widget,
|
|
||||||
the GtkEditable interface has been expanded, and new a new
|
|
||||||
GtkPasswordEntry widget has been introduced.
|
|
||||||
|
|
||||||
* Focus handling has been rewritten, and focus-change event
|
|
||||||
generation has been unified with crossing events.
|
|
||||||
|
|
||||||
* All demos and settings schemas have been renamed to avoid collisions
|
|
||||||
with GTK3.
|
|
||||||
|
|
||||||
* GtkWidget can now use a GtkLayoutManager for size allocation.
|
|
||||||
Layout managers can optionally use layout children holding layout
|
|
||||||
properties. A number of layout managers are available:
|
|
||||||
- GtkBinLayout
|
|
||||||
- GtkBoxLayout
|
|
||||||
- GtkGridLayout
|
|
||||||
- GtkFixedLayout
|
|
||||||
- GtkCustomLayout
|
|
||||||
More layout manager implementations will appear in the future.
|
|
||||||
|
|
||||||
* GtkAssistant, GtkStack and GtkNotebook now have publicly
|
|
||||||
accessible page objects for their children. The page objects
|
|
||||||
are also exposed via a list model.
|
|
||||||
|
|
||||||
* GtkContainer no longer supports child properties. All existing
|
|
||||||
child properties have been removed, converted to regular properties,
|
|
||||||
moved to layout properties or moved to child meta objects.
|
|
||||||
|
|
||||||
* GtkListBox has gained a ::show-separators property that gets
|
|
||||||
translated into a CSS style class.
|
|
||||||
|
|
||||||
* A number of X11-specific GtkWindow and GdkSurface apis have been
|
|
||||||
removed or changed to backend APIs.
|
|
||||||
|
|
||||||
* GtkBuilder can specify object-valued properties inline.
|
|
||||||
|
|
||||||
* The gtk4-builder-tool simplify command has gained a --3to4 option
|
|
||||||
to convert GTK3 ui files to GTK4.
|
|
||||||
|
|
||||||
* The inspector can show child meta objects and layout properties.
|
|
||||||
|
|
||||||
|
|
||||||
Overview of Changes in GTK+ 3.94.0
|
Overview of Changes in GTK+ 3.94.0
|
||||||
==================================
|
==================================
|
||||||
|
|
||||||
@@ -867,7 +258,7 @@ Overview of Changes in GTK+ 3.92.1, 重庆市
|
|||||||
The bulk of the preparation for this release was done during
|
The bulk of the preparation for this release was done during
|
||||||
and after the fantastic GNOME.Asia Summit 2017 in Chongqing, China.
|
and after the fantastic GNOME.Asia Summit 2017 in Chongqing, China.
|
||||||
|
|
||||||
* Drop autotools support. Meson 0.42.1 is now required
|
* Drop autotools support. Meson 0.42.1 is now required
|
||||||
|
|
||||||
* Implement most of CSS3 font-variant
|
* Implement most of CSS3 font-variant
|
||||||
|
|
||||||
|
|||||||
72
README.commits
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
GTK+ is part of the GNOME git repository. At the current time, any
|
||||||
|
person with write access to the GNOME repository, can make changes to
|
||||||
|
GTK+. This is a good thing, in that it encourages many people to work
|
||||||
|
on GTK+, and progress can be made quickly. However, GTK+ is a fairly
|
||||||
|
large and complicated package that many other things depend on, so to
|
||||||
|
avoid unnecessary breakage, and to take advantage of the knowledge
|
||||||
|
about GTK+ that has been built up over the years, we'd like to ask
|
||||||
|
people committing to GTK+ to follow a few rules:
|
||||||
|
|
||||||
|
0) Ask first. If your changes are major, or could possibly break existing
|
||||||
|
code, you should always ask. If your change is minor and you've
|
||||||
|
been working on GTK+ for a while it probably isn't necessary
|
||||||
|
to ask. But when in doubt, ask. Even if your change is correct,
|
||||||
|
somebody may know a better way to do things.
|
||||||
|
|
||||||
|
If you are making changes to GTK+, you should be subscribed
|
||||||
|
to gtk-devel-list@gnome.org. (Subscription address:
|
||||||
|
gtk-devel-list-request@gnome.org.) This is a good place to ask
|
||||||
|
about intended changes.
|
||||||
|
|
||||||
|
#gtk+ on GIMPNet (irc.gimp.org, irc.us.gimp.org, irc.eu.gimp.org, ...)
|
||||||
|
is also a good place to find GTK+ developers to discuss changes with,
|
||||||
|
however, email to gtk-devel-list is the most certain and preferred
|
||||||
|
method.
|
||||||
|
|
||||||
|
1) Ask _first_.
|
||||||
|
|
||||||
|
2) With git, we no longer maintain a ChangeLog file, but you are expected
|
||||||
|
to produce a meaningful commit message. Changes without a sufficient
|
||||||
|
commit message will be reverted. See below for the expected format
|
||||||
|
of commit messages.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
* When developing larger features or complicated bug fixes, it is
|
||||||
|
advisable to work in a branch in your own cloned GTK+ repository.
|
||||||
|
You may even consider making your repository publically available
|
||||||
|
so that others can easily test and review your changes.
|
||||||
|
|
||||||
|
* The expected format for git commit messages is as follows:
|
||||||
|
|
||||||
|
=== begin example commit ===
|
||||||
|
Short explanation of the commit
|
||||||
|
|
||||||
|
Longer explanation explaining exactly what's changed, whether any
|
||||||
|
external or private interfaces changed, what bugs were fixed (with bug
|
||||||
|
tracker reference if applicable) and so forth. Be concise but not too brief.
|
||||||
|
=== end example commit ===
|
||||||
|
|
||||||
|
- Always add a brief description of the commit to the _first_ line of
|
||||||
|
the commit and terminate by two newlines (it will work without the
|
||||||
|
second newline, but that is not nice for the interfaces).
|
||||||
|
|
||||||
|
- First line (the brief description) must only be one sentence and
|
||||||
|
should start with a capital letter unless it starts with a lowercase
|
||||||
|
symbol or identifier. Don't use a trailing period either. Don't exceed
|
||||||
|
72 characters.
|
||||||
|
|
||||||
|
- The main description (the body) is normal prose and should use normal
|
||||||
|
punctuation and capital letters where appropriate. Normally, for patches
|
||||||
|
sent to a mailing list it's copied from there.
|
||||||
|
|
||||||
|
- When committing code on behalf of others use the --author option, e.g.
|
||||||
|
git commit -a --author "Joe Coder <joe@coder.org>" and --signoff.
|
||||||
|
|
||||||
|
|
||||||
|
Owen Taylor
|
||||||
|
13 Aug 1998
|
||||||
|
17 Apr 2001
|
||||||
|
|
||||||
|
Matthias Clasen
|
||||||
|
31 Mar 2009
|
||||||
43
README.md
@@ -1,17 +1,17 @@
|
|||||||
GTK — The GTK toolkit
|
GTK+ — The GTK toolkit
|
||||||
=====================
|
======================
|
||||||
|
|
||||||
[](https://gitlab.gnome.org/GNOME/gtk/pipelines)
|
[](https://gitlab.gnome.org/GNOME/gtk/pipelines)
|
||||||
|
|
||||||
General information
|
General information
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
GTK is a multi-platform toolkit for creating graphical user interfaces.
|
GTK+ is a multi-platform toolkit for creating graphical user interfaces.
|
||||||
Offering a complete set of widgets, GTK is suitable for projects ranging
|
Offering a complete set of widgets, GTK+ is suitable for projects ranging
|
||||||
from small one-off projects to complete application suites.
|
from small one-off projects to complete application suites.
|
||||||
|
|
||||||
GTK is free software and part of the GNU Project. However, the
|
GTK+ is free software and part of the GNU Project. However, the
|
||||||
licensing terms for GTK, the GNU LGPL, allow it to be used by all
|
licensing terms for GTK+, the GNU LGPL, allow it to be used by all
|
||||||
developers, including those developing proprietary software, without any
|
developers, including those developing proprietary software, without any
|
||||||
license fees or royalties.
|
license fees or royalties.
|
||||||
|
|
||||||
@@ -27,19 +27,14 @@ The official developers blog
|
|||||||
|
|
||||||
- https://blog.gtk.org
|
- https://blog.gtk.org
|
||||||
|
|
||||||
Discussion forum
|
Information about mailing lists can be found at
|
||||||
|
|
||||||
- https://discourse.gnome.org/c/platform/core/
|
- http://www.gtk.org/mailing-lists.php
|
||||||
|
|
||||||
Nightly documentation can be found at
|
|
||||||
- Gtk: https://gnome.pages.gitlab.gnome.org/gtk/gtk/
|
|
||||||
- Gdk: https://gnome.pages.gitlab.gnome.org/gtk/gdk/
|
|
||||||
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk/
|
|
||||||
|
|
||||||
Building and installing
|
Building and installing
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
In order to build GTK you will need:
|
In order to build GTK+ you will need:
|
||||||
|
|
||||||
- [a C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
|
- [a C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
|
||||||
- [Python 3](https://www.python.org/)
|
- [Python 3](https://www.python.org/)
|
||||||
@@ -79,7 +74,7 @@ If you are building the Wayland backend, you will also need:
|
|||||||
- Wayland-cursor
|
- Wayland-cursor
|
||||||
- Wayland-EGL
|
- 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
|
||||||
@@ -94,7 +89,7 @@ You can run the test suite using:
|
|||||||
$ meson test
|
$ meson test
|
||||||
```
|
```
|
||||||
|
|
||||||
And, finally, you can install GTK using:
|
And, finally, you can install GTK+ using:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ sudo ninja install
|
$ sudo ninja install
|
||||||
@@ -118,10 +113,10 @@ In the bug report please include:
|
|||||||
|
|
||||||
* Information about your system. For instance:
|
* Information about your system. For instance:
|
||||||
|
|
||||||
- which version of GTK you are using
|
- which version of GTK+ you are using
|
||||||
- what operating system and version
|
- what operating system and 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
|
||||||
|
|
||||||
And anything else you think is relevant.
|
And anything else you think is relevant.
|
||||||
|
|
||||||
@@ -140,16 +135,10 @@ In the bug report please include:
|
|||||||
* Further information such as stack traces may be useful, but
|
* Further information such as stack traces may be useful, but
|
||||||
is not necessary.
|
is not necessary.
|
||||||
|
|
||||||
Contributing to GTK
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Please, follow the [contribution guide](./CONTRIBUTING.md) to know how to
|
|
||||||
start contributing to GTK.
|
|
||||||
|
|
||||||
Release notes
|
Release notes
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
The release notes for GTK are part of the migration guide in the API
|
The release notes for GTK+ are part of the migration guide in the API
|
||||||
reference. See:
|
reference. See:
|
||||||
|
|
||||||
- [3.x release notes](https://developer.gnome.org/gtk3/unstable/gtk-migrating-2-to-3.html)
|
- [3.x release notes](https://developer.gnome.org/gtk3/unstable/gtk-migrating-2-to-3.html)
|
||||||
@@ -158,8 +147,8 @@ reference. See:
|
|||||||
Licensing terms
|
Licensing terms
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
GTK is released under the terms of the GNU Lesser General Public License,
|
GTK+ is released under the terms of the GNU Lesser General Public License,
|
||||||
version 2.1 or, at your option, any later version, as published by the Free
|
version 2.1 or, at your option, any later version, as published by the Free
|
||||||
Software Foundation.
|
Software Foundation.
|
||||||
|
|
||||||
Please, see the [`COPYING`](./COPYING) file for further information.
|
Please, see the `COPYING` file for further information.
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
{
|
{
|
||||||
"app-id": "org.gtk.Demo4",
|
"app-id": "org.gtk.Demo",
|
||||||
"runtime": "org.gnome.Platform",
|
"runtime": "org.gnome.Platform",
|
||||||
"runtime-version": "master",
|
"runtime-version": "master",
|
||||||
"sdk": "org.gnome.Sdk",
|
"sdk": "org.gnome.Sdk",
|
||||||
"command": "gtk4-demo",
|
"command": "gtk4-demo",
|
||||||
"tags": ["devel", "development", "nightly"],
|
"tags": ["devel", "development", "nightly"],
|
||||||
|
"rename-desktop-file": "gtk4-demo.desktop",
|
||||||
|
"rename-icon": "gtk4-demo",
|
||||||
"desktop-file-name-prefix": "(Development) ",
|
"desktop-file-name-prefix": "(Development) ",
|
||||||
"finish-args": [
|
"finish-args": [
|
||||||
"--device=dri",
|
"--device=dri",
|
||||||
"--share=ipc",
|
"--share=ipc",
|
||||||
"--socket=fallback-x11",
|
"--socket=x11",
|
||||||
"--socket=wayland",
|
"--socket=wayland",
|
||||||
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*"
|
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*",
|
||||||
|
"--talk-name=ca.desrt.conf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf"
|
||||||
],
|
],
|
||||||
"cleanup": [
|
"cleanup": [
|
||||||
"/include",
|
"/include",
|
||||||
@@ -54,36 +57,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name" : "libsass",
|
|
||||||
"buildsystem" : "meson",
|
|
||||||
"builddir" : true,
|
|
||||||
"config-opts": [
|
|
||||||
"--libdir=/app/lib"
|
|
||||||
],
|
|
||||||
"sources" : [
|
|
||||||
{
|
|
||||||
"type" : "git",
|
|
||||||
"url" : "https://github.com/lazka/libsass.git",
|
|
||||||
"branch" : "meson"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name" : "sassc",
|
|
||||||
"buildsystem" : "meson",
|
|
||||||
"builddir" : true,
|
|
||||||
"config-opts": [
|
|
||||||
"--libdir=/app/lib"
|
|
||||||
],
|
|
||||||
"sources" : [
|
|
||||||
{
|
|
||||||
"type" : "git",
|
|
||||||
"url" : "https://github.com/lazka/sassc.git",
|
|
||||||
"branch" : "meson"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "gtk",
|
"name": "gtk",
|
||||||
"buildsystem": "meson",
|
"buildsystem": "meson",
|
||||||
@@ -1,17 +1,20 @@
|
|||||||
{
|
{
|
||||||
"app-id": "org.gtk.IconBrowser4",
|
"app-id": "org.gtk.WidgetFactory",
|
||||||
"runtime": "org.gnome.Platform",
|
"runtime": "org.gnome.Platform",
|
||||||
"runtime-version": "master",
|
"runtime-version": "master",
|
||||||
"sdk": "org.gnome.Sdk",
|
"sdk": "org.gnome.Sdk",
|
||||||
"command": "gtk4-icon-browser",
|
"command": "gtk4-widget-factory",
|
||||||
"tags": ["devel", "development", "nightly"],
|
"tags": ["devel", "development", "nightly"],
|
||||||
|
"rename-desktop-file": "gtk4-widget-factory.desktop",
|
||||||
|
"rename-icon": "gtk4-widget-factory",
|
||||||
"desktop-file-name-prefix": "(Development) ",
|
"desktop-file-name-prefix": "(Development) ",
|
||||||
"finish-args": [
|
"finish-args": [
|
||||||
"--device=dri",
|
"--device=dri",
|
||||||
"--share=ipc",
|
"--share=ipc",
|
||||||
"--socket=fallback-x11",
|
"--socket=x11",
|
||||||
"--socket=wayland",
|
"--socket=wayland",
|
||||||
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*"
|
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*",
|
||||||
|
"--talk-name=ca.desrt.conf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf"
|
||||||
],
|
],
|
||||||
"cleanup": [
|
"cleanup": [
|
||||||
"/include",
|
"/include",
|
||||||
@@ -54,36 +57,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name" : "libsass",
|
|
||||||
"buildsystem" : "meson",
|
|
||||||
"builddir" : true,
|
|
||||||
"config-opts": [
|
|
||||||
"--libdir=/app/lib"
|
|
||||||
],
|
|
||||||
"sources" : [
|
|
||||||
{
|
|
||||||
"type" : "git",
|
|
||||||
"url" : "https://github.com/lazka/libsass.git",
|
|
||||||
"branch" : "meson"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name" : "sassc",
|
|
||||||
"buildsystem" : "meson",
|
|
||||||
"builddir" : true,
|
|
||||||
"config-opts": [
|
|
||||||
"--libdir=/app/lib"
|
|
||||||
],
|
|
||||||
"sources" : [
|
|
||||||
{
|
|
||||||
"type" : "git",
|
|
||||||
"url" : "https://github.com/lazka/sassc.git",
|
|
||||||
"branch" : "meson"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "gtk",
|
"name": "gtk",
|
||||||
"buildsystem": "meson",
|
"buildsystem": "meson",
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
{
|
|
||||||
"app-id" : "org.gtk.WidgetFactory4",
|
|
||||||
"runtime" : "org.gnome.Platform",
|
|
||||||
"runtime-version" : "master",
|
|
||||||
"sdk" : "org.gnome.Sdk",
|
|
||||||
"command" : "gtk4-widget-factory",
|
|
||||||
"tags" : [
|
|
||||||
"devel",
|
|
||||||
"development",
|
|
||||||
"nightly"
|
|
||||||
],
|
|
||||||
"desktop-file-name-prefix" : "(Development) ",
|
|
||||||
"finish-args" : [
|
|
||||||
"--device=dri",
|
|
||||||
"--share=ipc",
|
|
||||||
"--socket=fallback-x11",
|
|
||||||
"--socket=wayland",
|
|
||||||
"--talk-name=org.gtk.vfs",
|
|
||||||
"--talk-name=org.gtk.vfs.*"
|
|
||||||
],
|
|
||||||
"cleanup" : [
|
|
||||||
"/include",
|
|
||||||
"/lib/pkgconfig",
|
|
||||||
"/share/pkgconfig",
|
|
||||||
"/share/aclocal",
|
|
||||||
"/man",
|
|
||||||
"/share/man",
|
|
||||||
"/share/gtk-doc",
|
|
||||||
"*.la",
|
|
||||||
".a",
|
|
||||||
"/lib/girepository-1.0",
|
|
||||||
"/share/gir-1.0",
|
|
||||||
"/share/doc"
|
|
||||||
],
|
|
||||||
"modules" : [
|
|
||||||
{
|
|
||||||
"name" : "wayland",
|
|
||||||
"buildsystem" : "autotools",
|
|
||||||
"builddir" : true,
|
|
||||||
"config-opts" : [
|
|
||||||
"--disable-documentation"
|
|
||||||
],
|
|
||||||
"sources" : [
|
|
||||||
{
|
|
||||||
"type" : "git",
|
|
||||||
"url" : "https://github.com/wayland-project/wayland.git"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name" : "graphene",
|
|
||||||
"buildsystem" : "meson",
|
|
||||||
"builddir" : true,
|
|
||||||
"config-opts" : [
|
|
||||||
"--libdir=/app/lib",
|
|
||||||
"-Dtests=false",
|
|
||||||
"-Dbenchmarks=false"
|
|
||||||
],
|
|
||||||
"sources" : [
|
|
||||||
{
|
|
||||||
"type" : "git",
|
|
||||||
"url" : "https://github.com/ebassi/graphene.git"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name" : "libsass",
|
|
||||||
"buildsystem" : "meson",
|
|
||||||
"builddir" : true,
|
|
||||||
"config-opts" : [
|
|
||||||
"--libdir=/app/lib"
|
|
||||||
],
|
|
||||||
"sources" : [
|
|
||||||
{
|
|
||||||
"type" : "git",
|
|
||||||
"url" : "https://github.com/lazka/libsass.git",
|
|
||||||
"branch" : "meson"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name" : "sassc",
|
|
||||||
"buildsystem" : "meson",
|
|
||||||
"builddir" : true,
|
|
||||||
"config-opts" : [
|
|
||||||
"--libdir=/app/lib"
|
|
||||||
],
|
|
||||||
"sources" : [
|
|
||||||
{
|
|
||||||
"type" : "git",
|
|
||||||
"url" : "https://github.com/lazka/sassc.git",
|
|
||||||
"branch" : "meson"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name" : "gtk",
|
|
||||||
"buildsystem" : "meson",
|
|
||||||
"builddir" : true,
|
|
||||||
"config-opts" : [
|
|
||||||
"--libdir=/app/lib"
|
|
||||||
],
|
|
||||||
"sources" : [
|
|
||||||
{
|
|
||||||
"type" : "git",
|
|
||||||
"url" : "https://gitlab.gnome.org/GNOME/gtk.git"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"build-options" : {
|
|
||||||
"env" : {
|
|
||||||
"DBUS_SESSION_BUS_ADDRESS" : "''"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
#!/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_moduledir = os.path.join(gtk_libdir, 'gtk-' + gtk_api_version, gtk_abi_version)
|
|
||||||
gtk_printmodule_dir = os.path.join(gtk_moduledir, 'printbackends')
|
|
||||||
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
|
|
||||||
|
|
||||||
print('Compiling GSettings schemas...')
|
|
||||||
glib_compile_schemas = subprocess.check_output(['pkg-config',
|
|
||||||
'--variable=glib_compile_schemas',
|
|
||||||
'gio-2.0']).strip()
|
|
||||||
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...')
|
|
||||||
subprocess.call(['gtk4-update-icon-cache', '-q', '-t' ,'-f',
|
|
||||||
os.path.join(gtk_datadir, 'icons', 'hicolor')])
|
|
||||||
|
|
||||||
print('Updating module cache for print backends...')
|
|
||||||
os.makedirs(gtk_printmodule_dir, exist_ok=True)
|
|
||||||
gio_querymodules = subprocess.check_output(['pkg-config',
|
|
||||||
'--variable=gio_querymodules',
|
|
||||||
'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 input methods...')
|
|
||||||
os.makedirs(gtk_immodule_dir, exist_ok=True)
|
|
||||||
subprocess.call([gio_querymodules, gtk_immodule_dir])
|
|
||||||
26
build-aux/meson/post-install.sh
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
gtk_api_version=$1
|
||||||
|
gtk_abi_version=$2
|
||||||
|
gtk_libdir=$3
|
||||||
|
gtk_datadir=$4
|
||||||
|
|
||||||
|
# Package managers set this so we don't need to run
|
||||||
|
if [ -z "$DESTDIR" ]; then
|
||||||
|
echo Compiling GSettings schemas...
|
||||||
|
glib-compile-schemas ${gtk_datadir}/glib-2.0/schemas
|
||||||
|
|
||||||
|
echo Updating desktop database...
|
||||||
|
update-desktop-database -q ${gtk_datadir}/applications
|
||||||
|
|
||||||
|
echo Updating icon cache...
|
||||||
|
gtk-update-icon-cache -q -t -f ${gtk_datadir}/icons/hicolor
|
||||||
|
|
||||||
|
echo Updating module cache for print backends...
|
||||||
|
mkdir -p ${gtk_libdir}/gtk-4.0/4.0.0/printbackends
|
||||||
|
gio-querymodules ${gtk_libdir}/gtk-4.0/4.0.0/printbackends
|
||||||
|
|
||||||
|
echo Updating module cache for input methods...
|
||||||
|
mkdir -p ${gtk_libdir}/gtk-4.0/4.0.0/immodules
|
||||||
|
gio-querymodules ${gtk_libdir}/gtk-4.0/4.0.0/immodules
|
||||||
|
fi
|
||||||
@@ -24,9 +24,20 @@
|
|||||||
/* Define to 1 if you have the <crt_externs.h> header file. */
|
/* Define to 1 if you have the <crt_externs.h> header file. */
|
||||||
#mesondefine HAVE_CRT_EXTERNS_H
|
#mesondefine HAVE_CRT_EXTERNS_H
|
||||||
|
|
||||||
|
/* Define to 1 if CUPS 1.6 API is available */
|
||||||
|
#mesondefine HAVE_CUPS_API_1_6
|
||||||
|
|
||||||
/* Define to 1 if you have the `dcgettext' function. */
|
/* Define to 1 if you have the `dcgettext' function. */
|
||||||
#mesondefine HAVE_DCGETTEXT
|
#mesondefine HAVE_DCGETTEXT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
|
||||||
|
*/
|
||||||
|
#mesondefine HAVE_DECL_ISINF
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't.
|
||||||
|
*/
|
||||||
|
#mesondefine HAVE_DECL_ISNAN
|
||||||
|
|
||||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
#mesondefine HAVE_DLFCN_H
|
#mesondefine HAVE_DLFCN_H
|
||||||
|
|
||||||
@@ -48,6 +59,12 @@
|
|||||||
/* Define if GStreamer support is available */
|
/* Define if GStreamer support is available */
|
||||||
#mesondefine HAVE_GSTREAMER
|
#mesondefine HAVE_GSTREAMER
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `httpGetAuthString' function. */
|
||||||
|
#mesondefine HAVE_HTTPGETAUTHSTRING
|
||||||
|
|
||||||
|
/* Define if cups http_t authstring field is accessible */
|
||||||
|
#mesondefine HAVE_HTTP_AUTHSTRING
|
||||||
|
|
||||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
#mesondefine HAVE_INTTYPES_H
|
#mesondefine HAVE_INTTYPES_H
|
||||||
|
|
||||||
@@ -72,6 +89,9 @@
|
|||||||
/* Define to 1 if you have a working `mmap' system call. */
|
/* Define to 1 if you have a working `mmap' system call. */
|
||||||
#mesondefine HAVE_MMAP
|
#mesondefine HAVE_MMAP
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `nearbyint' function. */
|
||||||
|
#mesondefine HAVE_NEARBYINT
|
||||||
|
|
||||||
/* Define to 1 if you have the `posix_fallocate' function. */
|
/* Define to 1 if you have the `posix_fallocate' function. */
|
||||||
#mesondefine HAVE_POSIX_FALLOCATE
|
#mesondefine HAVE_POSIX_FALLOCATE
|
||||||
|
|
||||||
@@ -81,9 +101,21 @@
|
|||||||
/* Have the Xrandr 1.5 extension library */
|
/* Have the Xrandr 1.5 extension library */
|
||||||
#mesondefine HAVE_RANDR15
|
#mesondefine HAVE_RANDR15
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `rint' function. */
|
||||||
|
#mesondefine HAVE_RINT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `round' function. */
|
||||||
|
#mesondefine HAVE_ROUND
|
||||||
|
|
||||||
/* Define to 1 if you have the `sincos' function. */
|
/* Define to 1 if you have the `sincos' function. */
|
||||||
#mesondefine HAVE_SINCOS
|
#mesondefine HAVE_SINCOS
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `log2` function */
|
||||||
|
#mesondefine HAVE_LOG2
|
||||||
|
|
||||||
|
/* Define to 1 if you ahve the `exp2` function */
|
||||||
|
#mesondefine HAVE_EXP2
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdint.h> header file. */
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
#mesondefine HAVE_STDINT_H
|
#mesondefine HAVE_STDINT_H
|
||||||
|
|
||||||
@@ -102,9 +134,6 @@
|
|||||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||||
#mesondefine HAVE_SYS_PARAM_H
|
#mesondefine HAVE_SYS_PARAM_H
|
||||||
|
|
||||||
/* Have the sysprof-capture library */
|
|
||||||
#mesondefine HAVE_SYSPROF_CAPTURE
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
#mesondefine HAVE_SYS_STAT_H
|
#mesondefine HAVE_SYS_STAT_H
|
||||||
|
|
||||||
@@ -162,6 +191,9 @@
|
|||||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||||
#mesondefine LT_OBJDIR
|
#mesondefine LT_OBJDIR
|
||||||
|
|
||||||
|
/* Define if <X11/extensions/XIproto.h> needed for xReply */
|
||||||
|
#mesondefine NEED_XIPROTO_H_FOR_XREPLY
|
||||||
|
|
||||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||||
#mesondefine NO_MINUS_C_MINUS_O
|
#mesondefine NO_MINUS_C_MINUS_O
|
||||||
|
|
||||||
@@ -212,6 +244,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Define to 1 if XInput 2.0 is available */
|
||||||
|
#mesondefine XINPUT_2
|
||||||
|
|
||||||
/* Define to 1 if XInput 2.2 is available */
|
/* Define to 1 if XInput 2.2 is available */
|
||||||
#mesondefine XINPUT_2_2
|
#mesondefine XINPUT_2_2
|
||||||
|
|
||||||
@@ -265,13 +300,18 @@
|
|||||||
|
|
||||||
#mesondefine GTK_PRINT_BACKENDS
|
#mesondefine GTK_PRINT_BACKENDS
|
||||||
|
|
||||||
#mesondefine HAVE_CAIRO_SCRIPT_INTERPRETER
|
|
||||||
|
|
||||||
#mesondefine HAVE_HARFBUZZ
|
#mesondefine HAVE_HARFBUZZ
|
||||||
|
|
||||||
#mesondefine HAVE_PANGOFT
|
#mesondefine HAVE_PANGOFT
|
||||||
|
|
||||||
#mesondefine ISO_CODES_PREFIX
|
#mesondefine ISO_CODES_PREFIX
|
||||||
|
|
||||||
/* Define if tracker3 is available */
|
#mesondefine MALLOC_IS_ALIGNED16
|
||||||
#mesondefine HAVE_TRACKER3
|
|
||||||
|
#mesondefine HAVE_POSIX_MEMALIGN
|
||||||
|
|
||||||
|
#mesondefine HAVE_MEMALIGN
|
||||||
|
|
||||||
|
#mesondefine HAVE_ALIGNED_ALLOC
|
||||||
|
|
||||||
|
#mesondefine HAVE__ALIGNED_MALLOC
|
||||||
|
|||||||
@@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_APPLICATION_TYPE (constraint_editor_application_get_type ())
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (ConstraintEditorApplication, constraint_editor_application, CONSTRAINT, EDITOR_APPLICATION, GtkApplication)
|
|
||||||
|
|
||||||
ConstraintEditorApplication *constraint_editor_application_new (void);
|
|
||||||
@@ -1,654 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
item = g_list_model_get_item (list, i);
|
|
||||||
constraint = GTK_CONSTRAINT (item);
|
|
||||||
|
|
||||||
target = gtk_constraint_get_target (constraint);
|
|
||||||
source = gtk_constraint_get_source (constraint);
|
|
||||||
clone = gtk_constraint_new (find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), target),
|
|
||||||
gtk_constraint_get_target_attribute (constraint),
|
|
||||||
gtk_constraint_get_relation (constraint),
|
|
||||||
find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), source),
|
|
||||||
gtk_constraint_get_target_attribute (constraint),
|
|
||||||
gtk_constraint_get_multiplier (constraint),
|
|
||||||
gtk_constraint_get_constant (constraint),
|
|
||||||
gtk_constraint_get_strength (constraint));
|
|
||||||
|
|
||||||
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, -1,
|
|
||||||
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_finalize (GObject *object)
|
|
||||||
{
|
|
||||||
//ConstraintEditorWindow *self = (ConstraintEditorWindow *)object;
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (constraint_editor_window_parent_class)->finalize (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->finalize = constraint_editor_window_finalize;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<interface>
|
|
||||||
<template class="ConstraintEditorWindow" parent="GtkApplicationWindow">
|
|
||||||
<style>
|
|
||||||
<class name="devel"/>
|
|
||||||
</style>
|
|
||||||
<property name="title" translatable="yes">GTK Constraint Editor</property>
|
|
||||||
<property name="default-width">1024</property>
|
|
||||||
<property name="default-height">768</property>
|
|
||||||
<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>
|
|
||||||
@@ -1,656 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 (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 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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_nick (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)
|
|
||||||
{
|
|
||||||
if (gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target)) != NULL &&
|
|
||||||
gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source)) != NULL)
|
|
||||||
gtk_widget_set_sensitive (editor->button, TRUE);
|
|
||||||
else
|
|
||||||
gtk_widget_set_sensitive (editor->button, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
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_pointer (&self->grid, gtk_widget_unparent);
|
|
||||||
g_clear_object (&self->model);
|
|
||||||
g_clear_object (&self->constraint);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
constraintview {
|
|
||||||
background: black;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
constraintview .child {
|
|
||||||
background: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
constraintview .guide {
|
|
||||||
background: blue;
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?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>
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
<?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="left-attach">0</property>
|
|
||||||
<property name="top-attach">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="left-attach">1</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkComboBoxText" id="target_attr">
|
|
||||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">2</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label">Relation</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">2</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkComboBoxText" id="relation">
|
|
||||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">2</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label">Source</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">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="left-attach">1</property>
|
|
||||||
<property name="top-attach">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"/>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">2</property>
|
|
||||||
<property name="top-attach">3</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label">Multiplier</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">4</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkEntry" id="multiplier">
|
|
||||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">4</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label">Constant</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">5</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkEntry" id="constant">
|
|
||||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">5</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label">Strength</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">6</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkComboBoxText" id="strength">
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">6</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="preview">
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">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="left-attach">2</property>
|
|
||||||
<property name="top-attach">8</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</template>
|
|
||||||
</interface>
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
@@ -1,345 +0,0 @@
|
|||||||
/* 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_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_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;
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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);
|
|
||||||
@@ -1,355 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_pointer (&self->grid, gtk_widget_unparent);
|
|
||||||
g_clear_object (&self->guide);
|
|
||||||
|
|
||||||
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,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 GUIDE_EDITOR_TYPE (guide_editor_get_type ())
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (GuideEditor, guide_editor, GUIDE, EDITOR, GtkWidget)
|
|
||||||
|
|
||||||
GuideEditor * guide_editor_new (GtkConstraintGuide *guide);
|
|
||||||
|
|
||||||
void guide_editor_serialize_guide (GString *str,
|
|
||||||
int indent,
|
|
||||||
GtkConstraintGuide *guide);
|
|
||||||
@@ -1,191 +0,0 @@
|
|||||||
<?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="left-attach">0</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkEntry" id="name">
|
|
||||||
<property name="max-width-chars">20</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
<property name="column-span">2</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label">Min Size</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">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="left-attach">1</property>
|
|
||||||
<property name="top-attach">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="left-attach">2</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label">Nat Size</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">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="left-attach">1</property>
|
|
||||||
<property name="top-attach">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="left-attach">2</property>
|
|
||||||
<property name="top-attach">2</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label">Max Size</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">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="left-attach">1</property>
|
|
||||||
<property name="top-attach">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="left-attach">2</property>
|
|
||||||
<property name="top-attach">3</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label">Strength</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">4</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkComboBoxText" id="strength">
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">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="left-attach">2</property>
|
|
||||||
<property name="top-attach">5</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</template>
|
|
||||||
</interface>
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 <mclasen@redhat.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <constraint-editor-application.h>
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int argc, char *argv[])
|
|
||||||
{
|
|
||||||
return g_application_run (G_APPLICATION (constraint_editor_application_new ()), argc, argv);
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
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',
|
|
||||||
constraint_editor_sources, constraint_editor_resources,
|
|
||||||
c_args: common_cflags,
|
|
||||||
dependencies: libgtk_dep,
|
|
||||||
include_directories: confinc,
|
|
||||||
gui_app: true,
|
|
||||||
link_args: extra_demo_ldflags,
|
|
||||||
install: false)
|
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
typedef GtkApplication DemoApplication;
|
typedef GtkApplication DemoApplication;
|
||||||
typedef GtkApplicationClass DemoApplicationClass;
|
typedef GtkApplicationClass DemoApplicationClass;
|
||||||
|
|
||||||
static GType demo_application_get_type (void);
|
|
||||||
G_DEFINE_TYPE (DemoApplication, demo_application, GTK_TYPE_APPLICATION)
|
G_DEFINE_TYPE (DemoApplication, demo_application, GTK_TYPE_APPLICATION)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -15,7 +14,7 @@ typedef struct {
|
|||||||
GtkWidget *message;
|
GtkWidget *message;
|
||||||
GtkWidget *infobar;
|
GtkWidget *infobar;
|
||||||
GtkWidget *status;
|
GtkWidget *status;
|
||||||
GtkWidget *menubutton;
|
GtkWidget *menutool;
|
||||||
GMenuModel *toolmenu;
|
GMenuModel *toolmenu;
|
||||||
GtkTextBuffer *buffer;
|
GtkTextBuffer *buffer;
|
||||||
|
|
||||||
@@ -26,7 +25,6 @@ typedef struct {
|
|||||||
} DemoApplicationWindow;
|
} DemoApplicationWindow;
|
||||||
typedef GtkApplicationWindowClass DemoApplicationWindowClass;
|
typedef GtkApplicationWindowClass DemoApplicationWindowClass;
|
||||||
|
|
||||||
static GType demo_application_window_get_type (void);
|
|
||||||
G_DEFINE_TYPE (DemoApplicationWindow, demo_application_window, GTK_TYPE_APPLICATION_WINDOW)
|
G_DEFINE_TYPE (DemoApplicationWindow, demo_application_window, GTK_TYPE_APPLICATION_WINDOW)
|
||||||
|
|
||||||
static void create_window (GApplication *app, const char *contents);
|
static void create_window (GApplication *app, const char *contents);
|
||||||
@@ -34,7 +32,7 @@ static void create_window (GApplication *app, const char *contents);
|
|||||||
static void
|
static void
|
||||||
show_action_dialog (GSimpleAction *action)
|
show_action_dialog (GSimpleAction *action)
|
||||||
{
|
{
|
||||||
const char *name;
|
const gchar *name;
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
|
|
||||||
name = g_action_get_name (G_ACTION (action));
|
name = g_action_get_name (G_ACTION (action));
|
||||||
@@ -47,7 +45,7 @@ show_action_dialog (GSimpleAction *action)
|
|||||||
name);
|
name);
|
||||||
|
|
||||||
g_signal_connect (dialog, "response",
|
g_signal_connect (dialog, "response",
|
||||||
G_CALLBACK (gtk_window_destroy), NULL);
|
G_CALLBACK (gtk_widget_destroy), NULL);
|
||||||
|
|
||||||
gtk_widget_show (dialog);
|
gtk_widget_show (dialog);
|
||||||
}
|
}
|
||||||
@@ -58,9 +56,9 @@ show_action_infobar (GSimpleAction *action,
|
|||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
DemoApplicationWindow *window = data;
|
DemoApplicationWindow *window = data;
|
||||||
char *text;
|
gchar *text;
|
||||||
const char *name;
|
const gchar *name;
|
||||||
const char *value;
|
const gchar *value;
|
||||||
|
|
||||||
name = g_action_get_name (G_ACTION (action));
|
name = g_action_get_name (G_ACTION (action));
|
||||||
value = g_variant_get_string (parameter, NULL);
|
value = g_variant_get_string (parameter, NULL);
|
||||||
@@ -92,7 +90,7 @@ activate_new (GSimpleAction *action,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
open_response_cb (GtkNativeDialog *dialog,
|
open_response_cb (GtkNativeDialog *dialog,
|
||||||
int response_id,
|
gint response_id,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GtkFileChooserNative *native = user_data;
|
GtkFileChooserNative *native = user_data;
|
||||||
@@ -120,7 +118,7 @@ open_response_cb (GtkNativeDialog *dialog,
|
|||||||
"Error loading file: \"%s\"",
|
"Error loading file: \"%s\"",
|
||||||
error->message);
|
error->message);
|
||||||
g_signal_connect (message_dialog, "response",
|
g_signal_connect (message_dialog, "response",
|
||||||
G_CALLBACK (gtk_window_destroy), NULL);
|
G_CALLBACK (gtk_widget_destroy), NULL);
|
||||||
gtk_widget_show (message_dialog);
|
gtk_widget_show (message_dialog);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
}
|
}
|
||||||
@@ -185,7 +183,7 @@ activate_about (GSimpleAction *action,
|
|||||||
{
|
{
|
||||||
GtkWidget *window = user_data;
|
GtkWidget *window = user_data;
|
||||||
|
|
||||||
const char *authors[] = {
|
const gchar *authors[] = {
|
||||||
"Peter Mattis",
|
"Peter Mattis",
|
||||||
"Spencer Kimball",
|
"Spencer Kimball",
|
||||||
"Josh MacDonald",
|
"Josh MacDonald",
|
||||||
@@ -193,7 +191,7 @@ activate_about (GSimpleAction *action,
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *documentors[] = {
|
const gchar *documentors[] = {
|
||||||
"Owen Taylor",
|
"Owen Taylor",
|
||||||
"Tony Gale",
|
"Tony Gale",
|
||||||
"Matthias Clasen <mclasen@redhat.com>",
|
"Matthias Clasen <mclasen@redhat.com>",
|
||||||
@@ -202,20 +200,20 @@ activate_about (GSimpleAction *action,
|
|||||||
};
|
};
|
||||||
|
|
||||||
gtk_show_about_dialog (GTK_WINDOW (window),
|
gtk_show_about_dialog (GTK_WINDOW (window),
|
||||||
"program-name", "GTK Code Demos",
|
"program-name", "GTK+ Code Demos",
|
||||||
"version", g_strdup_printf ("%s,\nRunning against GTK %d.%d.%d",
|
"version", g_strdup_printf ("%s,\nRunning against GTK+ %d.%d.%d",
|
||||||
PACKAGE_VERSION,
|
PACKAGE_VERSION,
|
||||||
gtk_get_major_version (),
|
gtk_get_major_version (),
|
||||||
gtk_get_minor_version (),
|
gtk_get_minor_version (),
|
||||||
gtk_get_micro_version ()),
|
gtk_get_micro_version ()),
|
||||||
"copyright", "(C) 1997-2013 The GTK Team",
|
"copyright", "(C) 1997-2013 The GTK+ Team",
|
||||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||||
"website", "http://www.gtk.org",
|
"website", "http://www.gtk.org",
|
||||||
"comments", "Program to demonstrate GTK functions.",
|
"comments", "Program to demonstrate GTK+ functions.",
|
||||||
"authors", authors,
|
"authors", authors,
|
||||||
"documenters", documentors,
|
"documenters", documentors,
|
||||||
"logo-icon-name", "org.gtk.Demo4",
|
"logo-icon-name", "gtk4-demo",
|
||||||
"title", "About GTK Code Demos",
|
"title", "About GTK+ Code Demos",
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +232,7 @@ activate_quit (GSimpleAction *action,
|
|||||||
win = list->data;
|
win = list->data;
|
||||||
next = list->next;
|
next = list->next;
|
||||||
|
|
||||||
gtk_window_destroy (GTK_WINDOW (win));
|
gtk_widget_destroy (GTK_WIDGET (win));
|
||||||
|
|
||||||
list = next;
|
list = next;
|
||||||
}
|
}
|
||||||
@@ -244,9 +242,9 @@ static void
|
|||||||
update_statusbar (GtkTextBuffer *buffer,
|
update_statusbar (GtkTextBuffer *buffer,
|
||||||
DemoApplicationWindow *window)
|
DemoApplicationWindow *window)
|
||||||
{
|
{
|
||||||
char *msg;
|
gchar *msg;
|
||||||
int row, col;
|
gint row, col;
|
||||||
int count;
|
gint count;
|
||||||
GtkTextIter iter;
|
GtkTextIter iter;
|
||||||
|
|
||||||
/* clear any previous message, underflow is allowed */
|
/* clear any previous message, underflow is allowed */
|
||||||
@@ -328,14 +326,19 @@ static void
|
|||||||
startup (GApplication *app)
|
startup (GApplication *app)
|
||||||
{
|
{
|
||||||
GtkBuilder *builder;
|
GtkBuilder *builder;
|
||||||
|
GMenuModel *appmenu;
|
||||||
|
GMenuModel *menubar;
|
||||||
|
|
||||||
G_APPLICATION_CLASS (demo_application_parent_class)->startup (app);
|
G_APPLICATION_CLASS (demo_application_parent_class)->startup (app);
|
||||||
|
|
||||||
builder = gtk_builder_new ();
|
builder = gtk_builder_new ();
|
||||||
gtk_builder_add_from_resource (builder, "/application_demo/menus.ui", NULL);
|
gtk_builder_add_from_resource (builder, "/application_demo/menus.ui", NULL);
|
||||||
|
|
||||||
gtk_application_set_menubar (GTK_APPLICATION (app),
|
appmenu = (GMenuModel *)gtk_builder_get_object (builder, "appmenu");
|
||||||
G_MENU_MODEL (gtk_builder_get_object (builder, "menubar")));
|
menubar = (GMenuModel *)gtk_builder_get_object (builder, "menubar");
|
||||||
|
|
||||||
|
gtk_application_set_app_menu (GTK_APPLICATION (app), appmenu);
|
||||||
|
gtk_application_set_menubar (GTK_APPLICATION (app), menubar);
|
||||||
|
|
||||||
g_object_unref (builder);
|
g_object_unref (builder);
|
||||||
}
|
}
|
||||||
@@ -348,7 +351,6 @@ create_window (GApplication *app,
|
|||||||
|
|
||||||
window = (DemoApplicationWindow *)g_object_new (demo_application_window_get_type (),
|
window = (DemoApplicationWindow *)g_object_new (demo_application_window_get_type (),
|
||||||
"application", app,
|
"application", app,
|
||||||
"show-menubar", TRUE,
|
|
||||||
NULL);
|
NULL);
|
||||||
if (content)
|
if (content)
|
||||||
gtk_text_buffer_set_text (window->buffer, content, -1);
|
gtk_text_buffer_set_text (window->buffer, content, -1);
|
||||||
@@ -368,7 +370,7 @@ demo_application_init (DemoApplication *app)
|
|||||||
GSettings *settings;
|
GSettings *settings;
|
||||||
GAction *action;
|
GAction *action;
|
||||||
|
|
||||||
settings = g_settings_new ("org.gtk.Demo4");
|
settings = g_settings_new ("org.gtk.Demo");
|
||||||
|
|
||||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||||
app_entries, G_N_ELEMENTS (app_entries),
|
app_entries, G_N_ELEMENTS (app_entries),
|
||||||
@@ -395,7 +397,7 @@ demo_application_window_store_state (DemoApplicationWindow *win)
|
|||||||
{
|
{
|
||||||
GSettings *settings;
|
GSettings *settings;
|
||||||
|
|
||||||
settings = g_settings_new ("org.gtk.Demo4");
|
settings = g_settings_new ("org.gtk.Demo");
|
||||||
g_settings_set (settings, "window-size", "(ii)", win->width, win->height);
|
g_settings_set (settings, "window-size", "(ii)", win->width, win->height);
|
||||||
g_settings_set_boolean (settings, "maximized", win->maximized);
|
g_settings_set_boolean (settings, "maximized", win->maximized);
|
||||||
g_settings_set_boolean (settings, "fullscreen", win->fullscreen);
|
g_settings_set_boolean (settings, "fullscreen", win->fullscreen);
|
||||||
@@ -407,7 +409,7 @@ demo_application_window_load_state (DemoApplicationWindow *win)
|
|||||||
{
|
{
|
||||||
GSettings *settings;
|
GSettings *settings;
|
||||||
|
|
||||||
settings = g_settings_new ("org.gtk.Demo4");
|
settings = g_settings_new ("org.gtk.Demo");
|
||||||
g_settings_get (settings, "window-size", "(ii)", &win->width, &win->height);
|
g_settings_get (settings, "window-size", "(ii)", &win->width, &win->height);
|
||||||
win->maximized = g_settings_get_boolean (settings, "maximized");
|
win->maximized = g_settings_get_boolean (settings, "maximized");
|
||||||
win->fullscreen = g_settings_get_boolean (settings, "fullscreen");
|
win->fullscreen = g_settings_get_boolean (settings, "fullscreen");
|
||||||
@@ -417,7 +419,7 @@ demo_application_window_load_state (DemoApplicationWindow *win)
|
|||||||
static void
|
static void
|
||||||
demo_application_window_init (DemoApplicationWindow *window)
|
demo_application_window_init (DemoApplicationWindow *window)
|
||||||
{
|
{
|
||||||
GtkWidget *popover;
|
GtkWidget *menu;
|
||||||
|
|
||||||
window->width = -1;
|
window->width = -1;
|
||||||
window->height = -1;
|
window->height = -1;
|
||||||
@@ -426,8 +428,8 @@ demo_application_window_init (DemoApplicationWindow *window)
|
|||||||
|
|
||||||
gtk_widget_init_template (GTK_WIDGET (window));
|
gtk_widget_init_template (GTK_WIDGET (window));
|
||||||
|
|
||||||
popover = gtk_popover_menu_new_from_model (window->toolmenu);
|
menu = gtk_menu_new_from_model (window->toolmenu);
|
||||||
gtk_menu_button_set_popover (GTK_MENU_BUTTON (window->menubutton), popover);
|
gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (window->menutool), menu);
|
||||||
|
|
||||||
g_action_map_add_action_entries (G_ACTION_MAP (window),
|
g_action_map_add_action_entries (G_ACTION_MAP (window),
|
||||||
win_entries, G_N_ELEMENTS (win_entries),
|
win_entries, G_N_ELEMENTS (win_entries),
|
||||||
@@ -453,16 +455,13 @@ demo_application_window_constructed (GObject *object)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
demo_application_window_size_allocate (GtkWidget *widget,
|
demo_application_window_size_allocate (GtkWidget *widget,
|
||||||
int width,
|
const GtkAllocation *allocation,
|
||||||
int height,
|
int baseline)
|
||||||
int baseline)
|
|
||||||
{
|
{
|
||||||
DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
|
DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (demo_application_window_parent_class)->size_allocate (widget,
|
GTK_WIDGET_CLASS (demo_application_window_parent_class)->size_allocate (widget, allocation,
|
||||||
width,
|
|
||||||
height,
|
|
||||||
baseline);
|
baseline);
|
||||||
|
|
||||||
if (!window->maximized && !window->fullscreen)
|
if (!window->maximized && !window->fullscreen)
|
||||||
@@ -475,7 +474,7 @@ surface_state_changed (GtkWidget *widget)
|
|||||||
DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
|
DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
|
||||||
GdkSurfaceState new_state;
|
GdkSurfaceState new_state;
|
||||||
|
|
||||||
new_state = gdk_toplevel_get_state (GDK_TOPLEVEL (gtk_native_get_surface (GTK_NATIVE (widget))));
|
new_state = gdk_surface_get_state (gtk_widget_get_surface (widget));
|
||||||
window->maximized = (new_state & GDK_SURFACE_STATE_MAXIMIZED) != 0;
|
window->maximized = (new_state & GDK_SURFACE_STATE_MAXIMIZED) != 0;
|
||||||
window->fullscreen = (new_state & GDK_SURFACE_STATE_FULLSCREEN) != 0;
|
window->fullscreen = (new_state & GDK_SURFACE_STATE_FULLSCREEN) != 0;
|
||||||
}
|
}
|
||||||
@@ -485,27 +484,27 @@ demo_application_window_realize (GtkWidget *widget)
|
|||||||
{
|
{
|
||||||
GTK_WIDGET_CLASS (demo_application_window_parent_class)->realize (widget);
|
GTK_WIDGET_CLASS (demo_application_window_parent_class)->realize (widget);
|
||||||
|
|
||||||
g_signal_connect_swapped (gtk_native_get_surface (GTK_NATIVE (widget)), "notify::state",
|
g_signal_connect_swapped (gtk_widget_get_surface (widget), "notify::state",
|
||||||
G_CALLBACK (surface_state_changed), widget);
|
G_CALLBACK (surface_state_changed), widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
demo_application_window_unrealize (GtkWidget *widget)
|
demo_application_window_unrealize (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
g_signal_handlers_disconnect_by_func (gtk_native_get_surface (GTK_NATIVE (widget)),
|
g_signal_handlers_disconnect_by_func (gtk_widget_get_surface (widget),
|
||||||
surface_state_changed, widget);
|
surface_state_changed, widget);
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (demo_application_window_parent_class)->unrealize (widget);
|
GTK_WIDGET_CLASS (demo_application_window_parent_class)->unrealize (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
demo_application_window_dispose (GObject *object)
|
demo_application_window_destroy (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
DemoApplicationWindow *window = (DemoApplicationWindow *)object;
|
DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
|
||||||
|
|
||||||
demo_application_window_store_state (window);
|
demo_application_window_store_state (window);
|
||||||
|
|
||||||
G_OBJECT_CLASS (demo_application_window_parent_class)->dispose (object);
|
GTK_WIDGET_CLASS (demo_application_window_parent_class)->destroy (widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -515,18 +514,18 @@ demo_application_window_class_init (DemoApplicationWindowClass *class)
|
|||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||||
|
|
||||||
object_class->constructed = demo_application_window_constructed;
|
object_class->constructed = demo_application_window_constructed;
|
||||||
object_class->dispose = demo_application_window_dispose;
|
|
||||||
|
|
||||||
widget_class->size_allocate = demo_application_window_size_allocate;
|
widget_class->size_allocate = demo_application_window_size_allocate;
|
||||||
widget_class->realize = demo_application_window_realize;
|
widget_class->realize = demo_application_window_realize;
|
||||||
widget_class->unrealize = demo_application_window_unrealize;
|
widget_class->unrealize = demo_application_window_unrealize;
|
||||||
|
widget_class->destroy = demo_application_window_destroy;
|
||||||
|
|
||||||
gtk_widget_class_set_template_from_resource (widget_class, "/application_demo/application.ui");
|
gtk_widget_class_set_template_from_resource (widget_class, "/application_demo/application.ui");
|
||||||
gtk_widget_class_bind_template_child (widget_class, DemoApplicationWindow, message);
|
gtk_widget_class_bind_template_child (widget_class, DemoApplicationWindow, message);
|
||||||
gtk_widget_class_bind_template_child (widget_class, DemoApplicationWindow, infobar);
|
gtk_widget_class_bind_template_child (widget_class, DemoApplicationWindow, infobar);
|
||||||
gtk_widget_class_bind_template_child (widget_class, DemoApplicationWindow, status);
|
gtk_widget_class_bind_template_child (widget_class, DemoApplicationWindow, status);
|
||||||
gtk_widget_class_bind_template_child (widget_class, DemoApplicationWindow, buffer);
|
gtk_widget_class_bind_template_child (widget_class, DemoApplicationWindow, buffer);
|
||||||
gtk_widget_class_bind_template_child (widget_class, DemoApplicationWindow, menubutton);
|
gtk_widget_class_bind_template_child (widget_class, DemoApplicationWindow, menutool);
|
||||||
gtk_widget_class_bind_template_child (widget_class, DemoApplicationWindow, toolmenu);
|
gtk_widget_class_bind_template_child (widget_class, DemoApplicationWindow, toolmenu);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, clicked_cb);
|
gtk_widget_class_bind_template_callback (widget_class, clicked_cb);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, update_statusbar);
|
gtk_widget_class_bind_template_callback (widget_class, update_statusbar);
|
||||||
@@ -539,7 +538,7 @@ main (int argc, char *argv[])
|
|||||||
GtkApplication *app;
|
GtkApplication *app;
|
||||||
|
|
||||||
app = GTK_APPLICATION (g_object_new (demo_application_get_type (),
|
app = GTK_APPLICATION (g_object_new (demo_application_get_type (),
|
||||||
"application-id", "org.gtk.Demo4.App",
|
"application-id", "org.gtk.Demo2",
|
||||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||||
NULL));
|
NULL));
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0"?>
|
||||||
<interface>
|
<interface>
|
||||||
<template class="DemoApplicationWindow" parent="GtkApplicationWindow">
|
<template class="DemoApplicationWindow" parent="GtkApplicationWindow">
|
||||||
<property name="title" translatable="yes">Application Class</property>
|
<property name="title" translatable="yes">Application Class</property>
|
||||||
@@ -8,60 +8,72 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkGrid">
|
<object class="GtkGrid">
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkToolbar">
|
||||||
<property name="hexpand">1</property>
|
<property name="hexpand">1</property>
|
||||||
|
<style>
|
||||||
|
<class name="primary-toolbar"/>
|
||||||
|
</style>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkMenuButton" id="menubutton">
|
<object class="GtkMenuToolButton" id="menutool">
|
||||||
<property name="icon-name">document-open</property>
|
<property name="icon-name">document-open</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton">
|
<object class="GtkToolButton">
|
||||||
<property name="icon-name">application-exit</property>
|
<property name="icon-name">application-exit</property>
|
||||||
<property name="action-name">app.quit</property>
|
<property name="action-name">app.quit</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparator"/>
|
<object class="GtkSeparatorToolItem">
|
||||||
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton">
|
<object class="GtkToolButton">
|
||||||
<property name="icon-name">applications-other</property>
|
<property name="icon-name">applications-other</property>
|
||||||
<property name="action-name">win.logo</property>
|
<property name="action-name">win.logo</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">0</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkInfoBar" id="infobar">
|
<object class="GtkInfoBar" id="infobar">
|
||||||
<property name="visible">0</property>
|
<property name="visible">0</property>
|
||||||
<property name="hexpand">1</property>
|
<property name="hexpand">1</property>
|
||||||
<child>
|
<child internal-child="content_area">
|
||||||
<object class="GtkLabel" id="message">
|
<object class="GtkBox" id="content_area">
|
||||||
<property name="hexpand">1</property>
|
<child>
|
||||||
|
<object class="GtkLabel" id="message">
|
||||||
|
<property name="hexpand">1</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child type="action">
|
<child internal-child="action_area">
|
||||||
<object class="GtkButton">
|
<object class="GtkBox">
|
||||||
<property name="valign">center</property>
|
<child>
|
||||||
<property name="label" translatable="yes">_OK</property>
|
<object class="GtkButton">
|
||||||
<property name="use-underline">1</property>
|
<property name="valign">center</property>
|
||||||
<signal name="clicked" handler="clicked_cb"/>
|
<property name="label" translatable="yes">_OK</property>
|
||||||
|
<property name="use-underline">1</property>
|
||||||
|
<signal name="clicked" handler="clicked_cb"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">1</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="has-frame">1</property>
|
<property name="shadow-type">in</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTextView">
|
<object class="GtkTextView">
|
||||||
<property name="hexpand">1</property>
|
<property name="hexpand">1</property>
|
||||||
@@ -69,20 +81,20 @@
|
|||||||
<property name="buffer">buffer</property>
|
<property name="buffer">buffer</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">2</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">2</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkStatusbar" id="status">
|
<object class="GtkStatusbar" id="status">
|
||||||
<property name="hexpand">1</property>
|
<property name="hexpand">1</property>
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">3</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">3</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ static GtkWidget *placeholder;
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
on_name_appeared (GDBusConnection *connection,
|
on_name_appeared (GDBusConnection *connection,
|
||||||
const char *name,
|
const gchar *name,
|
||||||
const char *name_owner,
|
const gchar *name_owner,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
name_seen = TRUE;
|
name_seen = TRUE;
|
||||||
@@ -25,13 +25,18 @@ on_name_appeared (GDBusConnection *connection,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
on_name_vanished (GDBusConnection *connection,
|
on_name_vanished (GDBusConnection *connection,
|
||||||
const char *name,
|
const gchar *name,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
if (!name_seen)
|
if (!name_seen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_clear_object (&placeholder);
|
if (placeholder)
|
||||||
|
{
|
||||||
|
gtk_widget_destroy (placeholder);
|
||||||
|
g_object_unref (placeholder);
|
||||||
|
placeholder = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
@@ -47,7 +52,7 @@ do_application_demo (GtkWidget *toplevel)
|
|||||||
|
|
||||||
if (watch == 0)
|
if (watch == 0)
|
||||||
watch = g_bus_watch_name (G_BUS_TYPE_SESSION,
|
watch = g_bus_watch_name (G_BUS_TYPE_SESSION,
|
||||||
"org.gtk.Demo4.App",
|
"org.gtk.Demo2",
|
||||||
0,
|
0,
|
||||||
on_name_appeared,
|
on_name_appeared,
|
||||||
on_name_vanished,
|
on_name_vanished,
|
||||||
@@ -55,7 +60,7 @@ do_application_demo (GtkWidget *toplevel)
|
|||||||
|
|
||||||
if (placeholder == NULL)
|
if (placeholder == NULL)
|
||||||
{
|
{
|
||||||
const char *command;
|
const gchar *command;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
if (g_file_test ("./gtk4-demo-application" APP_EXTENSION, G_FILE_TEST_IS_EXECUTABLE))
|
if (g_file_test ("./gtk4-demo-application" APP_EXTENSION, G_FILE_TEST_IS_EXECUTABLE))
|
||||||
@@ -75,8 +80,8 @@ do_application_demo (GtkWidget *toplevel)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL),
|
g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL),
|
||||||
"org.gtk.Demo4.App",
|
"org.gtk.Demo2",
|
||||||
"/org/gtk/Demo4/App",
|
"/org/gtk/Demo2",
|
||||||
"org.gtk.Actions",
|
"org.gtk.Actions",
|
||||||
"Activate",
|
"Activate",
|
||||||
g_variant_new ("(sava{sv})", "quit", NULL, NULL),
|
g_variant_new ("(sava{sv})", "quit", NULL, NULL),
|
||||||
|
|||||||
19
demos/gtk-demo/appmenu.ui
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<!-- interface-requires gtk+ 3.10 -->
|
||||||
|
<menu id="appmenu">
|
||||||
|
<section>
|
||||||
|
<item>
|
||||||
|
<attribute name="label" translatable="yes">About</attribute>
|
||||||
|
<attribute name="action">app.about</attribute>
|
||||||
|
</item>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<item>
|
||||||
|
<attribute name="label" translatable="yes">_Quit</attribute>
|
||||||
|
<attribute name="action">app.quit</attribute>
|
||||||
|
<attribute name="accel"><Primary>q</attribute>
|
||||||
|
</item>
|
||||||
|
</section>
|
||||||
|
</menu>
|
||||||
|
</interface>
|
||||||
@@ -7,12 +7,13 @@
|
|||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
static GtkWidget *assistant = NULL;
|
||||||
static GtkWidget *progress_bar = NULL;
|
static GtkWidget *progress_bar = NULL;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
apply_changes_gradually (gpointer data)
|
apply_changes_gradually (gpointer data)
|
||||||
{
|
{
|
||||||
double fraction;
|
gdouble fraction;
|
||||||
|
|
||||||
/* Work, work, work... */
|
/* Work, work, work... */
|
||||||
fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (progress_bar));
|
fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (progress_bar));
|
||||||
@@ -26,7 +27,8 @@ apply_changes_gradually (gpointer data)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Close automatically once changes are fully applied. */
|
/* Close automatically once changes are fully applied. */
|
||||||
gtk_window_destroy (GTK_WINDOW (data));
|
gtk_widget_destroy (assistant);
|
||||||
|
assistant = NULL;
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,20 +37,23 @@ static void
|
|||||||
on_assistant_apply (GtkWidget *widget, gpointer data)
|
on_assistant_apply (GtkWidget *widget, gpointer data)
|
||||||
{
|
{
|
||||||
/* Start a timer to simulate changes taking a few seconds to apply. */
|
/* Start a timer to simulate changes taking a few seconds to apply. */
|
||||||
g_timeout_add (100, apply_changes_gradually, widget);
|
g_timeout_add (100, apply_changes_gradually, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_assistant_close_cancel (GtkWidget *widget, gpointer data)
|
on_assistant_close_cancel (GtkWidget *widget, gpointer data)
|
||||||
{
|
{
|
||||||
gtk_window_destroy (GTK_WINDOW (widget));
|
GtkWidget **assistant = (GtkWidget **) data;
|
||||||
|
|
||||||
|
gtk_widget_destroy (*assistant);
|
||||||
|
*assistant = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_assistant_prepare (GtkWidget *widget, GtkWidget *page, gpointer data)
|
on_assistant_prepare (GtkWidget *widget, GtkWidget *page, gpointer data)
|
||||||
{
|
{
|
||||||
int current_page, n_pages;
|
gint current_page, n_pages;
|
||||||
char *title;
|
gchar *title;
|
||||||
|
|
||||||
current_page = gtk_assistant_get_current_page (GTK_ASSISTANT (widget));
|
current_page = gtk_assistant_get_current_page (GTK_ASSISTANT (widget));
|
||||||
n_pages = gtk_assistant_get_n_pages (GTK_ASSISTANT (widget));
|
n_pages = gtk_assistant_get_n_pages (GTK_ASSISTANT (widget));
|
||||||
@@ -70,12 +75,12 @@ on_entry_changed (GtkWidget *widget, gpointer data)
|
|||||||
{
|
{
|
||||||
GtkAssistant *assistant = GTK_ASSISTANT (data);
|
GtkAssistant *assistant = GTK_ASSISTANT (data);
|
||||||
GtkWidget *current_page;
|
GtkWidget *current_page;
|
||||||
int page_number;
|
gint page_number;
|
||||||
const char *text;
|
const gchar *text;
|
||||||
|
|
||||||
page_number = gtk_assistant_get_current_page (assistant);
|
page_number = gtk_assistant_get_current_page (assistant);
|
||||||
current_page = gtk_assistant_get_nth_page (assistant, page_number);
|
current_page = gtk_assistant_get_nth_page (assistant, page_number);
|
||||||
text = gtk_editable_get_text (GTK_EDITABLE (widget));
|
text = gtk_entry_get_text (GTK_ENTRY (widget));
|
||||||
|
|
||||||
if (text && *text)
|
if (text && *text)
|
||||||
gtk_assistant_set_page_complete (assistant, current_page, TRUE);
|
gtk_assistant_set_page_complete (assistant, current_page, TRUE);
|
||||||
@@ -89,18 +94,14 @@ create_page1 (GtkWidget *assistant)
|
|||||||
GtkWidget *box, *label, *entry;
|
GtkWidget *box, *label, *entry;
|
||||||
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
||||||
gtk_widget_set_margin_start (box, 12);
|
|
||||||
gtk_widget_set_margin_end (box, 12);
|
|
||||||
gtk_widget_set_margin_top (box, 12);
|
|
||||||
gtk_widget_set_margin_bottom (box, 12);
|
|
||||||
|
|
||||||
label = gtk_label_new ("You must fill out this entry to continue:");
|
label = gtk_label_new ("You must fill out this entry to continue:");
|
||||||
gtk_box_append (GTK_BOX (box), label);
|
gtk_box_pack_start (GTK_BOX (box), label);
|
||||||
|
|
||||||
entry = gtk_entry_new ();
|
entry = gtk_entry_new ();
|
||||||
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
||||||
gtk_widget_set_valign (entry, GTK_ALIGN_CENTER);
|
gtk_widget_set_valign (entry, GTK_ALIGN_CENTER);
|
||||||
gtk_box_append (GTK_BOX (box), entry);
|
gtk_box_pack_start (GTK_BOX (box), entry);
|
||||||
g_signal_connect (G_OBJECT (entry), "changed",
|
g_signal_connect (G_OBJECT (entry), "changed",
|
||||||
G_CALLBACK (on_entry_changed), assistant);
|
G_CALLBACK (on_entry_changed), assistant);
|
||||||
|
|
||||||
@@ -114,16 +115,11 @@ create_page2 (GtkWidget *assistant)
|
|||||||
{
|
{
|
||||||
GtkWidget *box, *checkbutton;
|
GtkWidget *box, *checkbutton;
|
||||||
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||||
gtk_widget_set_margin_start (box, 12);
|
|
||||||
gtk_widget_set_margin_end (box, 12);
|
|
||||||
gtk_widget_set_margin_top (box, 12);
|
|
||||||
gtk_widget_set_margin_bottom (box, 12);
|
|
||||||
|
|
||||||
checkbutton = gtk_check_button_new_with_label ("This is optional data, you may continue "
|
checkbutton = gtk_check_button_new_with_label ("This is optional data, you may continue "
|
||||||
"even if you do not check this");
|
"even if you do not check this");
|
||||||
gtk_widget_set_valign (checkbutton, GTK_ALIGN_CENTER);
|
gtk_box_pack_start (GTK_BOX (box), checkbutton);
|
||||||
gtk_box_append (GTK_BOX (box), checkbutton);
|
|
||||||
|
|
||||||
gtk_assistant_append_page (GTK_ASSISTANT (assistant), box);
|
gtk_assistant_append_page (GTK_ASSISTANT (assistant), box);
|
||||||
gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), box, TRUE);
|
gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), box, TRUE);
|
||||||
@@ -168,8 +164,6 @@ create_page4 (GtkWidget *assistant)
|
|||||||
GtkWidget*
|
GtkWidget*
|
||||||
do_assistant (GtkWidget *do_widget)
|
do_assistant (GtkWidget *do_widget)
|
||||||
{
|
{
|
||||||
static GtkWidget *assistant;
|
|
||||||
|
|
||||||
if (!assistant)
|
if (!assistant)
|
||||||
{
|
{
|
||||||
assistant = gtk_assistant_new ();
|
assistant = gtk_assistant_new ();
|
||||||
@@ -178,7 +172,6 @@ do_assistant (GtkWidget *do_widget)
|
|||||||
|
|
||||||
gtk_window_set_display (GTK_WINDOW (assistant),
|
gtk_window_set_display (GTK_WINDOW (assistant),
|
||||||
gtk_widget_get_display (do_widget));
|
gtk_widget_get_display (do_widget));
|
||||||
g_object_add_weak_pointer (G_OBJECT (assistant), (gpointer *)&assistant);
|
|
||||||
|
|
||||||
create_page1 (assistant);
|
create_page1 (assistant);
|
||||||
create_page2 (assistant);
|
create_page2 (assistant);
|
||||||
@@ -186,9 +179,9 @@ do_assistant (GtkWidget *do_widget)
|
|||||||
create_page4 (assistant);
|
create_page4 (assistant);
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT (assistant), "cancel",
|
g_signal_connect (G_OBJECT (assistant), "cancel",
|
||||||
G_CALLBACK (on_assistant_close_cancel), NULL);
|
G_CALLBACK (on_assistant_close_cancel), &assistant);
|
||||||
g_signal_connect (G_OBJECT (assistant), "close",
|
g_signal_connect (G_OBJECT (assistant), "close",
|
||||||
G_CALLBACK (on_assistant_close_cancel), NULL);
|
G_CALLBACK (on_assistant_close_cancel), &assistant);
|
||||||
g_signal_connect (G_OBJECT (assistant), "apply",
|
g_signal_connect (G_OBJECT (assistant), "apply",
|
||||||
G_CALLBACK (on_assistant_apply), NULL);
|
G_CALLBACK (on_assistant_apply), NULL);
|
||||||
g_signal_connect (G_OBJECT (assistant), "prepare",
|
g_signal_connect (G_OBJECT (assistant), "prepare",
|
||||||
@@ -198,7 +191,10 @@ do_assistant (GtkWidget *do_widget)
|
|||||||
if (!gtk_widget_get_visible (assistant))
|
if (!gtk_widget_get_visible (assistant))
|
||||||
gtk_widget_show (assistant);
|
gtk_widget_show (assistant);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (assistant));
|
{
|
||||||
|
gtk_widget_destroy (assistant);
|
||||||
|
assistant = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return assistant;
|
return assistant;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,33 +17,34 @@
|
|||||||
<style>
|
<style>
|
||||||
<class name="dim-label"/>
|
<class name="dim-label"/>
|
||||||
</style>
|
</style>
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">0</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow" id="scrolledwindow">
|
<object class="GtkScrolledWindow" id="scrolledwindow">
|
||||||
|
<property name="can-focus">1</property>
|
||||||
<property name="vexpand">1</property>
|
<property name="vexpand">1</property>
|
||||||
<property name="has-frame">1</property>
|
<property name="shadow-type">in</property>
|
||||||
<property name="min-content-width">150</property>
|
<property name="min-content-width">150</property>
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">1</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkStackSwitcher">
|
<object class="GtkStackSwitcher">
|
||||||
<property name="halign">center</property>
|
<property name="halign">center</property>
|
||||||
<property name="hexpand">1</property>
|
<property name="hexpand">1</property>
|
||||||
<property name="stack">stack</property>
|
<property name="stack">stack</property>
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">1</property>
|
||||||
|
<property name="top-attach">0</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkStack" id="stack">
|
<object class="GtkStack" id="stack">
|
||||||
@@ -53,284 +54,279 @@
|
|||||||
<property name="vhomogeneous">0</property>
|
<property name="vhomogeneous">0</property>
|
||||||
<property name="transition-type">crossfade</property>
|
<property name="transition-type">crossfade</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkStackPage">
|
<object class="GtkGrid">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<property name="vexpand">1</property>
|
||||||
|
<property name="row-spacing">12</property>
|
||||||
|
<property name="column-spacing">12</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" translatable="yes">Duck</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" translatable="yes">Background</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">1</property>
|
||||||
|
<property name="top-attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<style>
|
||||||
|
<class name="duck"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<style>
|
||||||
|
<class name="gradient"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">1</property>
|
||||||
|
<property name="top-attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" translatable="yes">
|
||||||
|
Blended picture</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">2</property>
|
||||||
|
<property name="width">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<style>
|
||||||
|
<class name="blend0"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">3</property>
|
||||||
|
<property name="width">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
<property name="name">page0</property>
|
<property name="name">page0</property>
|
||||||
<property name="title" translatable="yes">Ducky</property>
|
<property name="title" translatable="yes">Ducky</property>
|
||||||
<property name="child">
|
</packing>
|
||||||
<object class="GtkGrid">
|
|
||||||
<property name="halign">center</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<property name="vexpand">1</property>
|
|
||||||
<property name="row-spacing">12</property>
|
|
||||||
<property name="column-spacing">12</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label" translatable="yes">Duck</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label" translatable="yes">Background</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<style>
|
|
||||||
<class name="duck"/>
|
|
||||||
</style>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<style>
|
|
||||||
<class name="gradient"/>
|
|
||||||
</style>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label" translatable="yes">
|
|
||||||
Blended picture</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">2</property>
|
|
||||||
<property name="column-span">2</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<property name="halign">center</property>
|
|
||||||
<style>
|
|
||||||
<class name="blend0"/>
|
|
||||||
</style>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">3</property>
|
|
||||||
<property name="column-span">2</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkStackPage">
|
<object class="GtkGrid">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<property name="vexpand">1</property>
|
||||||
|
<property name="row-spacing">12</property>
|
||||||
|
<property name="column-spacing">12</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" translatable="yes">Red</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" translatable="yes">Blue</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">1</property>
|
||||||
|
<property name="top-attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<style>
|
||||||
|
<class name="red"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<style>
|
||||||
|
<class name="blue"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">1</property>
|
||||||
|
<property name="top-attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" translatable="yes">
|
||||||
|
Blended picture</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">2</property>
|
||||||
|
<property name="width">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<style>
|
||||||
|
<class name="blend1"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">3</property>
|
||||||
|
<property name="width">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
<property name="name">page1</property>
|
<property name="name">page1</property>
|
||||||
<property name="title" translatable="yes">Blends</property>
|
<property name="title" translatable="yes">Blends</property>
|
||||||
<property name="child">
|
</packing>
|
||||||
<object class="GtkGrid">
|
|
||||||
<property name="halign">center</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<property name="vexpand">1</property>
|
|
||||||
<property name="row-spacing">12</property>
|
|
||||||
<property name="column-spacing">12</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label" translatable="yes">Red</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label" translatable="yes">Blue</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<style>
|
|
||||||
<class name="red"/>
|
|
||||||
</style>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<style>
|
|
||||||
<class name="blue"/>
|
|
||||||
</style>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label" translatable="yes">
|
|
||||||
Blended picture</property>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">2</property>
|
|
||||||
<property name="column-span">2</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<property name="halign">center</property>
|
|
||||||
<style>
|
|
||||||
<class name="blend1"/>
|
|
||||||
</style>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">3</property>
|
|
||||||
<property name="column-span">2</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkStackPage">
|
<object class="GtkGrid">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<property name="hexpand">1</property>
|
||||||
|
<property name="vexpand">1</property>
|
||||||
|
<property name="row-spacing">6</property>
|
||||||
|
<property name="column-spacing">12</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<style>
|
||||||
|
<class name="cyan"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<style>
|
||||||
|
<class name="magenta"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">1</property>
|
||||||
|
<property name="top-attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<style>
|
||||||
|
<class name="yellow"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<style>
|
||||||
|
<class name="blend2"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">1</property>
|
||||||
|
<property name="top-attach">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" translatable="yes">Cyan</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<style>
|
||||||
|
<class name="dim-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" translatable="yes">Magenta</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<style>
|
||||||
|
<class name="dim-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">1</property>
|
||||||
|
<property name="top-attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" translatable="yes">Yellow</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<style>
|
||||||
|
<class name="dim-label"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">0</property>
|
||||||
|
<property name="top-attach">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" translatable="yes">Blended picture</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="weight" value="bold"/>
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">1</property>
|
||||||
|
<property name="top-attach">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
<property name="name">page2</property>
|
<property name="name">page2</property>
|
||||||
<property name="title" translatable="yes">CMYK</property>
|
<property name="title" translatable="yes">CMYK</property>
|
||||||
<property name="child">
|
</packing>
|
||||||
<object class="GtkGrid">
|
|
||||||
<property name="halign">center</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<property name="hexpand">1</property>
|
|
||||||
<property name="vexpand">1</property>
|
|
||||||
<property name="row-spacing">6</property>
|
|
||||||
<property name="column-spacing">12</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<style>
|
|
||||||
<class name="cyan"/>
|
|
||||||
</style>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<style>
|
|
||||||
<class name="magenta"/>
|
|
||||||
</style>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<style>
|
|
||||||
<class name="yellow"/>
|
|
||||||
</style>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">3</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage">
|
|
||||||
<property name="halign">center</property>
|
|
||||||
<style>
|
|
||||||
<class name="blend2"/>
|
|
||||||
</style>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">3</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label" translatable="yes">Cyan</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<style>
|
|
||||||
<class name="dim-label"/>
|
|
||||||
</style>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label" translatable="yes">Magenta</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<style>
|
|
||||||
<class name="dim-label"/>
|
|
||||||
</style>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">0</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label" translatable="yes">Yellow</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<style>
|
|
||||||
<class name="dim-label"/>
|
|
||||||
</style>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">0</property>
|
|
||||||
<property name="top-attach">2</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel">
|
|
||||||
<property name="label" translatable="yes">Blended picture</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<attributes>
|
|
||||||
<attribute name="weight" value="bold"></attribute>
|
|
||||||
</attributes>
|
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">2</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
</child>
|
||||||
<layout>
|
|
||||||
<property name="left-attach">1</property>
|
|
||||||
<property name="top-attach">1</property>
|
|
||||||
</layout>
|
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left-attach">1</property>
|
||||||
|
<property name="top-attach">1</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child type="titlebar"/>
|
<child type="titlebar">
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</interface>
|
</interface>
|
||||||
|
|||||||
@@ -1,461 +0,0 @@
|
|||||||
/*
|
|
||||||
* bluroverlay.c
|
|
||||||
* This file is part of gtk
|
|
||||||
*
|
|
||||||
* Copyright (C) 2011 - Ignacio Casal Quinteiro, Mike Krüger
|
|
||||||
*
|
|
||||||
* 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 "bluroverlay.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a cut-down copy of gtkoverlay.c with a custom snapshot
|
|
||||||
* function that support a limited form of blur-under.
|
|
||||||
*/
|
|
||||||
typedef struct _BlurOverlayChild BlurOverlayChild;
|
|
||||||
|
|
||||||
struct _BlurOverlayChild
|
|
||||||
{
|
|
||||||
double blur;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
GET_CHILD_POSITION,
|
|
||||||
LAST_SIGNAL
|
|
||||||
};
|
|
||||||
|
|
||||||
static guint signals[LAST_SIGNAL] = { 0 };
|
|
||||||
static GQuark child_data_quark = 0;
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (BlurOverlay, blur_overlay, GTK_TYPE_WIDGET)
|
|
||||||
|
|
||||||
static void
|
|
||||||
blur_overlay_set_overlay_child (GtkWidget *widget,
|
|
||||||
BlurOverlayChild *child_data)
|
|
||||||
{
|
|
||||||
g_object_set_qdata_full (G_OBJECT (widget), child_data_quark, child_data, g_free);
|
|
||||||
}
|
|
||||||
|
|
||||||
static BlurOverlayChild *
|
|
||||||
blur_overlay_get_overlay_child (GtkWidget *widget)
|
|
||||||
{
|
|
||||||
return (BlurOverlayChild *) g_object_get_qdata (G_OBJECT (widget), child_data_quark);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
blur_overlay_measure (GtkWidget *widget,
|
|
||||||
GtkOrientation orientation,
|
|
||||||
int for_size,
|
|
||||||
int *minimum,
|
|
||||||
int *natural,
|
|
||||||
int *minimum_baseline,
|
|
||||||
int *natural_baseline)
|
|
||||||
{
|
|
||||||
GtkWidget *child;
|
|
||||||
|
|
||||||
for (child = gtk_widget_get_first_child (widget);
|
|
||||||
child != NULL;
|
|
||||||
child = gtk_widget_get_next_sibling (child))
|
|
||||||
{
|
|
||||||
int child_min, child_nat, child_min_baseline, child_nat_baseline;
|
|
||||||
|
|
||||||
gtk_widget_measure (child,
|
|
||||||
orientation,
|
|
||||||
for_size,
|
|
||||||
&child_min, &child_nat,
|
|
||||||
&child_min_baseline, &child_nat_baseline);
|
|
||||||
|
|
||||||
*minimum = MAX (*minimum, child_min);
|
|
||||||
*natural = MAX (*natural, child_nat);
|
|
||||||
if (child_min_baseline > -1)
|
|
||||||
*minimum_baseline = MAX (*minimum_baseline, child_min_baseline);
|
|
||||||
if (child_nat_baseline > -1)
|
|
||||||
*natural_baseline = MAX (*natural_baseline, child_nat_baseline);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
blur_overlay_compute_child_allocation (BlurOverlay *overlay,
|
|
||||||
GtkWidget *widget,
|
|
||||||
BlurOverlayChild *child,
|
|
||||||
GtkAllocation *widget_allocation)
|
|
||||||
{
|
|
||||||
GtkAllocation allocation;
|
|
||||||
gboolean result;
|
|
||||||
|
|
||||||
g_signal_emit (overlay, signals[GET_CHILD_POSITION],
|
|
||||||
0, widget, &allocation, &result);
|
|
||||||
|
|
||||||
widget_allocation->x = allocation.x;
|
|
||||||
widget_allocation->y = allocation.y;
|
|
||||||
widget_allocation->width = allocation.width;
|
|
||||||
widget_allocation->height = allocation.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GtkAlign
|
|
||||||
effective_align (GtkAlign align,
|
|
||||||
GtkTextDirection direction)
|
|
||||||
{
|
|
||||||
switch (align)
|
|
||||||
{
|
|
||||||
case GTK_ALIGN_START:
|
|
||||||
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_END : GTK_ALIGN_START;
|
|
||||||
case GTK_ALIGN_END:
|
|
||||||
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_START : GTK_ALIGN_END;
|
|
||||||
case GTK_ALIGN_FILL:
|
|
||||||
case GTK_ALIGN_CENTER:
|
|
||||||
case GTK_ALIGN_BASELINE:
|
|
||||||
default:
|
|
||||||
return align;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
blur_overlay_child_update_style_classes (BlurOverlay *overlay,
|
|
||||||
GtkWidget *child,
|
|
||||||
GtkAllocation *child_allocation)
|
|
||||||
{
|
|
||||||
int width, height;
|
|
||||||
GtkAlign valign, halign;
|
|
||||||
gboolean is_left, is_right, is_top, is_bottom;
|
|
||||||
gboolean has_left, has_right, has_top, has_bottom;
|
|
||||||
|
|
||||||
has_left = gtk_widget_has_css_class (child, GTK_STYLE_CLASS_LEFT);
|
|
||||||
has_right = gtk_widget_has_css_class (child, GTK_STYLE_CLASS_RIGHT);
|
|
||||||
has_top = gtk_widget_has_css_class (child, GTK_STYLE_CLASS_TOP);
|
|
||||||
has_bottom = gtk_widget_has_css_class (child, GTK_STYLE_CLASS_BOTTOM);
|
|
||||||
|
|
||||||
is_left = is_right = is_top = is_bottom = FALSE;
|
|
||||||
|
|
||||||
width = gtk_widget_get_width (GTK_WIDGET (overlay));
|
|
||||||
height = gtk_widget_get_height (GTK_WIDGET (overlay));
|
|
||||||
|
|
||||||
halign = effective_align (gtk_widget_get_halign (child),
|
|
||||||
gtk_widget_get_direction (child));
|
|
||||||
|
|
||||||
if (halign == GTK_ALIGN_START)
|
|
||||||
is_left = (child_allocation->x == 0);
|
|
||||||
else if (halign == GTK_ALIGN_END)
|
|
||||||
is_right = (child_allocation->x + child_allocation->width == width);
|
|
||||||
|
|
||||||
valign = gtk_widget_get_valign (child);
|
|
||||||
|
|
||||||
if (valign == GTK_ALIGN_START)
|
|
||||||
is_top = (child_allocation->y == 0);
|
|
||||||
else if (valign == GTK_ALIGN_END)
|
|
||||||
is_bottom = (child_allocation->y + child_allocation->height == height);
|
|
||||||
|
|
||||||
if (has_left && !is_left)
|
|
||||||
gtk_widget_remove_css_class (child, GTK_STYLE_CLASS_LEFT);
|
|
||||||
else if (!has_left && is_left)
|
|
||||||
gtk_widget_add_css_class (child, GTK_STYLE_CLASS_LEFT);
|
|
||||||
|
|
||||||
if (has_right && !is_right)
|
|
||||||
gtk_widget_remove_css_class (child, GTK_STYLE_CLASS_RIGHT);
|
|
||||||
else if (!has_right && is_right)
|
|
||||||
gtk_widget_add_css_class (child, GTK_STYLE_CLASS_RIGHT);
|
|
||||||
|
|
||||||
if (has_top && !is_top)
|
|
||||||
gtk_widget_remove_css_class (child, GTK_STYLE_CLASS_TOP);
|
|
||||||
else if (!has_top && is_top)
|
|
||||||
gtk_widget_add_css_class (child, GTK_STYLE_CLASS_TOP);
|
|
||||||
|
|
||||||
if (has_bottom && !is_bottom)
|
|
||||||
gtk_widget_remove_css_class (child, GTK_STYLE_CLASS_BOTTOM);
|
|
||||||
else if (!has_bottom && is_bottom)
|
|
||||||
gtk_widget_add_css_class (child, GTK_STYLE_CLASS_BOTTOM);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
blur_overlay_child_allocate (BlurOverlay *overlay,
|
|
||||||
GtkWidget *widget,
|
|
||||||
BlurOverlayChild *child)
|
|
||||||
{
|
|
||||||
GtkAllocation child_allocation;
|
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (widget))
|
|
||||||
return;
|
|
||||||
|
|
||||||
blur_overlay_compute_child_allocation (overlay, widget, child, &child_allocation);
|
|
||||||
|
|
||||||
blur_overlay_child_update_style_classes (overlay, widget, &child_allocation);
|
|
||||||
gtk_widget_size_allocate (widget, &child_allocation, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
blur_overlay_size_allocate (GtkWidget *widget,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int baseline)
|
|
||||||
{
|
|
||||||
BlurOverlay *overlay = BLUR_OVERLAY (widget);
|
|
||||||
GtkWidget *child;
|
|
||||||
GtkWidget *main_widget;
|
|
||||||
|
|
||||||
main_widget = overlay->main_widget;
|
|
||||||
if (main_widget && gtk_widget_get_visible (main_widget))
|
|
||||||
gtk_widget_size_allocate (main_widget,
|
|
||||||
&(GtkAllocation) {
|
|
||||||
0, 0,
|
|
||||||
width, height
|
|
||||||
}, -1);
|
|
||||||
|
|
||||||
for (child = gtk_widget_get_first_child (widget);
|
|
||||||
child != NULL;
|
|
||||||
child = gtk_widget_get_next_sibling (child))
|
|
||||||
{
|
|
||||||
if (child != main_widget)
|
|
||||||
{
|
|
||||||
BlurOverlayChild *child_data = blur_overlay_get_overlay_child (child);
|
|
||||||
blur_overlay_child_allocate (overlay, child, child_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
blur_overlay_get_child_position (BlurOverlay *overlay,
|
|
||||||
GtkWidget *widget,
|
|
||||||
GtkAllocation *alloc)
|
|
||||||
{
|
|
||||||
GtkRequisition min, req;
|
|
||||||
GtkAlign halign;
|
|
||||||
GtkTextDirection direction;
|
|
||||||
int width, height;
|
|
||||||
|
|
||||||
gtk_widget_get_preferred_size (widget, &min, &req);
|
|
||||||
width = gtk_widget_get_width (GTK_WIDGET (overlay));
|
|
||||||
height = gtk_widget_get_height (GTK_WIDGET (overlay));
|
|
||||||
|
|
||||||
alloc->x = 0;
|
|
||||||
alloc->width = MAX (min.width, MIN (width, req.width));
|
|
||||||
|
|
||||||
direction = gtk_widget_get_direction (widget);
|
|
||||||
|
|
||||||
halign = gtk_widget_get_halign (widget);
|
|
||||||
switch (effective_align (halign, direction))
|
|
||||||
{
|
|
||||||
case GTK_ALIGN_START:
|
|
||||||
/* nothing to do */
|
|
||||||
break;
|
|
||||||
case GTK_ALIGN_FILL:
|
|
||||||
alloc->width = MAX (alloc->width, width);
|
|
||||||
break;
|
|
||||||
case GTK_ALIGN_CENTER:
|
|
||||||
alloc->x += width / 2 - alloc->width / 2;
|
|
||||||
break;
|
|
||||||
case GTK_ALIGN_END:
|
|
||||||
alloc->x += width - alloc->width;
|
|
||||||
break;
|
|
||||||
case GTK_ALIGN_BASELINE:
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
alloc->y = 0;
|
|
||||||
alloc->height = MAX (min.height, MIN (height, req.height));
|
|
||||||
|
|
||||||
switch (gtk_widget_get_valign (widget))
|
|
||||||
{
|
|
||||||
case GTK_ALIGN_START:
|
|
||||||
/* nothing to do */
|
|
||||||
break;
|
|
||||||
case GTK_ALIGN_FILL:
|
|
||||||
alloc->height = MAX (alloc->height, height);
|
|
||||||
break;
|
|
||||||
case GTK_ALIGN_CENTER:
|
|
||||||
alloc->y += height / 2 - alloc->height / 2;
|
|
||||||
break;
|
|
||||||
case GTK_ALIGN_END:
|
|
||||||
alloc->y += height - alloc->height;
|
|
||||||
break;
|
|
||||||
case GTK_ALIGN_BASELINE:
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
blur_overlay_snapshot (GtkWidget *widget,
|
|
||||||
GtkSnapshot *snapshot)
|
|
||||||
{
|
|
||||||
GtkWidget *main_widget;
|
|
||||||
GskRenderNode *main_widget_node = NULL;
|
|
||||||
GtkWidget *child;
|
|
||||||
GtkAllocation main_alloc;
|
|
||||||
cairo_region_t *clip = NULL;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
main_widget = BLUR_OVERLAY (widget)->main_widget;
|
|
||||||
gtk_widget_get_allocation (widget, &main_alloc);
|
|
||||||
|
|
||||||
for (child = gtk_widget_get_first_child (widget);
|
|
||||||
child != NULL;
|
|
||||||
child = gtk_widget_get_next_sibling (child))
|
|
||||||
{
|
|
||||||
BlurOverlayChild *child_info = blur_overlay_get_overlay_child (child);
|
|
||||||
double blur = 0;
|
|
||||||
if (child_info)
|
|
||||||
blur = child_info->blur;
|
|
||||||
|
|
||||||
if (blur > 0)
|
|
||||||
{
|
|
||||||
GtkAllocation alloc;
|
|
||||||
graphene_rect_t bounds;
|
|
||||||
|
|
||||||
if (main_widget_node == NULL)
|
|
||||||
{
|
|
||||||
GtkSnapshot *child_snapshot;
|
|
||||||
|
|
||||||
child_snapshot = gtk_snapshot_new ();
|
|
||||||
gtk_widget_snapshot_child (widget, main_widget, child_snapshot);
|
|
||||||
main_widget_node = gtk_snapshot_free_to_node (child_snapshot);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_widget_get_allocation (child, &alloc);
|
|
||||||
graphene_rect_init (&bounds, alloc.x, alloc.y, alloc.width, alloc.height);
|
|
||||||
gtk_snapshot_push_blur (snapshot, blur);
|
|
||||||
gtk_snapshot_push_clip (snapshot, &bounds);
|
|
||||||
gtk_snapshot_append_node (snapshot, main_widget_node);
|
|
||||||
gtk_snapshot_pop (snapshot);
|
|
||||||
gtk_snapshot_pop (snapshot);
|
|
||||||
|
|
||||||
if (clip == NULL)
|
|
||||||
{
|
|
||||||
cairo_rectangle_int_t rect;
|
|
||||||
rect.x = rect.y = 0;
|
|
||||||
rect.width = main_alloc.width;
|
|
||||||
rect.height = main_alloc.height;
|
|
||||||
clip = cairo_region_create_rectangle (&rect);
|
|
||||||
}
|
|
||||||
cairo_region_subtract_rectangle (clip, (cairo_rectangle_int_t *)&alloc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clip == NULL)
|
|
||||||
{
|
|
||||||
for (child = gtk_widget_get_first_child (widget);
|
|
||||||
child != NULL;
|
|
||||||
child = gtk_widget_get_next_sibling (child))
|
|
||||||
{
|
|
||||||
gtk_widget_snapshot_child (widget, child, snapshot);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < cairo_region_num_rectangles (clip); i++)
|
|
||||||
{
|
|
||||||
cairo_rectangle_int_t rect;
|
|
||||||
graphene_rect_t bounds;
|
|
||||||
|
|
||||||
cairo_region_get_rectangle (clip, i, &rect);
|
|
||||||
graphene_rect_init (&bounds, rect.x, rect.y, rect.width, rect.height);
|
|
||||||
gtk_snapshot_push_clip (snapshot, &bounds);
|
|
||||||
gtk_snapshot_append_node (snapshot, main_widget_node);
|
|
||||||
gtk_snapshot_pop (snapshot);
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_region_destroy (clip);
|
|
||||||
|
|
||||||
for (child = gtk_widget_get_first_child (widget);
|
|
||||||
child != NULL;
|
|
||||||
child = gtk_widget_get_next_sibling (child))
|
|
||||||
{
|
|
||||||
if (child != main_widget)
|
|
||||||
gtk_widget_snapshot_child (widget, child, snapshot);
|
|
||||||
}
|
|
||||||
|
|
||||||
gsk_render_node_unref (main_widget_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
blur_overlay_dispose (GObject *object)
|
|
||||||
{
|
|
||||||
BlurOverlay *overlay = BLUR_OVERLAY (object);
|
|
||||||
GtkWidget *child;
|
|
||||||
|
|
||||||
g_clear_pointer (&overlay->main_widget, gtk_widget_unparent);
|
|
||||||
|
|
||||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (overlay))))
|
|
||||||
gtk_widget_unparent (child);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (blur_overlay_parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
blur_overlay_class_init (BlurOverlayClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
||||||
|
|
||||||
object_class->dispose = blur_overlay_dispose;
|
|
||||||
|
|
||||||
widget_class->measure = blur_overlay_measure;
|
|
||||||
widget_class->size_allocate = blur_overlay_size_allocate;
|
|
||||||
widget_class->snapshot = blur_overlay_snapshot;
|
|
||||||
|
|
||||||
klass->get_child_position = blur_overlay_get_child_position;
|
|
||||||
|
|
||||||
signals[GET_CHILD_POSITION] =
|
|
||||||
g_signal_new ("get-child-position",
|
|
||||||
G_TYPE_FROM_CLASS (object_class),
|
|
||||||
G_SIGNAL_RUN_LAST,
|
|
||||||
G_STRUCT_OFFSET (BlurOverlayClass, get_child_position),
|
|
||||||
g_signal_accumulator_true_handled, NULL,
|
|
||||||
NULL,
|
|
||||||
G_TYPE_BOOLEAN, 2,
|
|
||||||
GTK_TYPE_WIDGET,
|
|
||||||
GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
|
|
||||||
|
|
||||||
child_data_quark = g_quark_from_static_string ("gtk-overlay-child-data");
|
|
||||||
|
|
||||||
gtk_widget_class_set_css_name (widget_class, "overlay");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
blur_overlay_init (BlurOverlay *overlay)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget *
|
|
||||||
blur_overlay_new (void)
|
|
||||||
{
|
|
||||||
return g_object_new (BLUR_TYPE_OVERLAY, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
blur_overlay_add_overlay (BlurOverlay *overlay,
|
|
||||||
GtkWidget *widget,
|
|
||||||
double blur)
|
|
||||||
{
|
|
||||||
BlurOverlayChild *child = g_new0 (BlurOverlayChild, 1);
|
|
||||||
|
|
||||||
gtk_widget_insert_before (widget, GTK_WIDGET (overlay), NULL);
|
|
||||||
|
|
||||||
child->blur = blur;
|
|
||||||
|
|
||||||
blur_overlay_set_overlay_child (widget, child);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
blur_overlay_set_child (BlurOverlay *overlay,
|
|
||||||
GtkWidget *widget)
|
|
||||||
{
|
|
||||||
gtk_widget_insert_after (widget, GTK_WIDGET (overlay), NULL);
|
|
||||||
overlay->main_widget = widget;
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* bluroverlay.h
|
|
||||||
* This file is part of gtk
|
|
||||||
*
|
|
||||||
* Copyright (C) 2011 - Ignacio Casal Quinteiro, Mike Krüger
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __BLUR_OVERLAY_H__
|
|
||||||
#define __BLUR_OVERLAY_H__
|
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define BLUR_TYPE_OVERLAY (blur_overlay_get_type ())
|
|
||||||
#define BLUR_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BLUR_TYPE_OVERLAY, BlurOverlay))
|
|
||||||
#define BLUR_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BLUR_TYPE_OVERLAY, BlurOverlayClass))
|
|
||||||
#define BLUR_IS_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BLUR_TYPE_OVERLAY))
|
|
||||||
#define BLUR_IS_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BLUR_TYPE_OVERLAY))
|
|
||||||
#define BLUR_OVERLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BLUR_TYPE_OVERLAY, BlurOverlayClass))
|
|
||||||
|
|
||||||
typedef struct _BlurOverlay BlurOverlay;
|
|
||||||
typedef struct _BlurOverlayClass BlurOverlayClass;
|
|
||||||
|
|
||||||
struct _BlurOverlay
|
|
||||||
{
|
|
||||||
GtkWidget parent_instance;
|
|
||||||
|
|
||||||
GtkWidget *main_widget;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _BlurOverlayClass
|
|
||||||
{
|
|
||||||
GtkWidgetClass parent_class;
|
|
||||||
|
|
||||||
gboolean (*get_child_position) (BlurOverlay *overlay,
|
|
||||||
GtkWidget *widget,
|
|
||||||
GtkAllocation *allocation);
|
|
||||||
};
|
|
||||||
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
|
||||||
GType blur_overlay_get_type (void) G_GNUC_CONST;
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
|
||||||
GtkWidget *blur_overlay_new (void);
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
|
||||||
void blur_overlay_add_overlay (BlurOverlay *overlay,
|
|
||||||
GtkWidget *widget,
|
|
||||||
double blur);
|
|
||||||
GDK_AVAILABLE_IN_ALL
|
|
||||||
void blur_overlay_set_child (BlurOverlay *overlay,
|
|
||||||
GtkWidget *widget);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __BLUR_OVERLAY_H__ */
|
|
||||||
@@ -12,7 +12,7 @@ quit_activate (GSimpleAction *action,
|
|||||||
{
|
{
|
||||||
GtkWidget *window = user_data;
|
GtkWidget *window = user_data;
|
||||||
|
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_widget_destroy (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -26,10 +26,8 @@ about_activate (GSimpleAction *action,
|
|||||||
|
|
||||||
builder = g_object_get_data (G_OBJECT (window), "builder");
|
builder = g_object_get_data (G_OBJECT (window), "builder");
|
||||||
about_dlg = GTK_WIDGET (gtk_builder_get_object (builder, "aboutdialog1"));
|
about_dlg = GTK_WIDGET (gtk_builder_get_object (builder, "aboutdialog1"));
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (about_dlg), GTK_WINDOW (window));
|
gtk_dialog_run (GTK_DIALOG (about_dlg));
|
||||||
gtk_window_set_hide_on_close (GTK_WINDOW (about_dlg), TRUE);
|
gtk_widget_hide (about_dlg);
|
||||||
g_signal_connect (about_dlg, "response", G_CALLBACK (gtk_widget_hide), NULL);
|
|
||||||
gtk_widget_show (about_dlg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -40,22 +38,7 @@ help_activate (GSimpleAction *action,
|
|||||||
g_print ("Help not available\n");
|
g_print ("Help not available\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
not_implemented (GSimpleAction *action,
|
|
||||||
GVariant *parameter,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
g_print ("Action “%s” not implemented\n", g_action_get_name (G_ACTION (action)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static GActionEntry win_entries[] = {
|
static GActionEntry win_entries[] = {
|
||||||
{ "new", not_implemented, NULL, NULL, NULL },
|
|
||||||
{ "open", not_implemented, NULL, NULL, NULL },
|
|
||||||
{ "save", not_implemented, NULL, NULL, NULL },
|
|
||||||
{ "save-as", not_implemented, NULL, NULL, NULL },
|
|
||||||
{ "copy", not_implemented, NULL, NULL, NULL },
|
|
||||||
{ "cut", not_implemented, NULL, NULL, NULL },
|
|
||||||
{ "paste", not_implemented, NULL, NULL, NULL },
|
|
||||||
{ "quit", quit_activate, NULL, NULL, NULL },
|
{ "quit", quit_activate, NULL, NULL, NULL },
|
||||||
{ "about", about_activate, NULL, NULL, NULL },
|
{ "about", about_activate, NULL, NULL, NULL },
|
||||||
{ "help", help_activate, NULL, NULL, NULL }
|
{ "help", help_activate, NULL, NULL, NULL }
|
||||||
@@ -65,7 +48,10 @@ GtkWidget *
|
|||||||
do_builder (GtkWidget *do_widget)
|
do_builder (GtkWidget *do_widget)
|
||||||
{
|
{
|
||||||
static GtkWidget *window = NULL;
|
static GtkWidget *window = NULL;
|
||||||
|
GtkWidget *toolbar;
|
||||||
GActionGroup *actions;
|
GActionGroup *actions;
|
||||||
|
GtkAccelGroup *accel_group;
|
||||||
|
GtkWidget *item;
|
||||||
|
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
@@ -73,23 +59,66 @@ do_builder (GtkWidget *do_widget)
|
|||||||
|
|
||||||
builder = gtk_builder_new_from_resource ("/builder/demo.ui");
|
builder = gtk_builder_new_from_resource ("/builder/demo.ui");
|
||||||
|
|
||||||
|
gtk_builder_connect_signals (builder, NULL);
|
||||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||||
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));
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
toolbar = GTK_WIDGET (gtk_builder_get_object (builder, "toolbar1"));
|
||||||
|
gtk_style_context_add_class (gtk_widget_get_style_context (toolbar),
|
||||||
|
"primary-toolbar");
|
||||||
actions = (GActionGroup*)g_simple_action_group_new ();
|
actions = (GActionGroup*)g_simple_action_group_new ();
|
||||||
g_action_map_add_action_entries (G_ACTION_MAP (actions),
|
g_action_map_add_action_entries (G_ACTION_MAP (actions),
|
||||||
win_entries, G_N_ELEMENTS (win_entries),
|
win_entries, G_N_ELEMENTS (win_entries),
|
||||||
window);
|
window);
|
||||||
gtk_widget_insert_action_group (window, "win", actions);
|
gtk_widget_insert_action_group (window, "win", actions);
|
||||||
|
accel_group = gtk_accel_group_new ();
|
||||||
|
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
|
||||||
|
|
||||||
g_object_unref (builder);
|
item = (GtkWidget*)gtk_builder_get_object (builder, "new_item");
|
||||||
|
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||||
|
GDK_KEY_n, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||||
|
|
||||||
|
item = (GtkWidget*)gtk_builder_get_object (builder, "open_item");
|
||||||
|
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||||
|
GDK_KEY_o, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||||
|
|
||||||
|
item = (GtkWidget*)gtk_builder_get_object (builder, "save_item");
|
||||||
|
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||||
|
GDK_KEY_s, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||||
|
|
||||||
|
item = (GtkWidget*)gtk_builder_get_object (builder, "quit_item");
|
||||||
|
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||||
|
GDK_KEY_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||||
|
|
||||||
|
item = (GtkWidget*)gtk_builder_get_object (builder, "copy_item");
|
||||||
|
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||||
|
GDK_KEY_c, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||||
|
|
||||||
|
item = (GtkWidget*)gtk_builder_get_object (builder, "cut_item");
|
||||||
|
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||||
|
GDK_KEY_x, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||||
|
|
||||||
|
item = (GtkWidget*)gtk_builder_get_object (builder, "paste_item");
|
||||||
|
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||||
|
GDK_KEY_v, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||||
|
|
||||||
|
item = (GtkWidget*)gtk_builder_get_object (builder, "help_item");
|
||||||
|
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||||
|
GDK_KEY_F1, 0, GTK_ACCEL_VISIBLE);
|
||||||
|
|
||||||
|
item = (GtkWidget*)gtk_builder_get_object (builder, "about_item");
|
||||||
|
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||||
|
GDK_KEY_F7, 0, GTK_ACCEL_VISIBLE);
|
||||||
|
|
||||||
|
g_object_set_data_full (G_OBJECT(window), "builder", builder, g_object_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|||||||
127
demos/gtk-demo/button_box.c
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
/* Button Boxes
|
||||||
|
*
|
||||||
|
* The Button Box widgets are used to arrange buttons with padding.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
static GtkWidget *
|
||||||
|
create_bbox (gint horizontal,
|
||||||
|
char *title,
|
||||||
|
gint spacing,
|
||||||
|
gint layout)
|
||||||
|
{
|
||||||
|
GtkWidget *frame;
|
||||||
|
GtkWidget *bbox;
|
||||||
|
GtkWidget *button;
|
||||||
|
|
||||||
|
frame = gtk_frame_new (title);
|
||||||
|
|
||||||
|
if (horizontal)
|
||||||
|
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
|
||||||
|
else
|
||||||
|
bbox = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
|
||||||
|
|
||||||
|
g_object_set (bbox, "margin", 5, NULL);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (frame), bbox);
|
||||||
|
|
||||||
|
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), layout);
|
||||||
|
gtk_box_set_spacing (GTK_BOX (bbox), spacing);
|
||||||
|
|
||||||
|
button = gtk_button_new_with_label (_("OK"));
|
||||||
|
gtk_container_add (GTK_CONTAINER (bbox), button);
|
||||||
|
|
||||||
|
button = gtk_button_new_with_label (_("Cancel"));
|
||||||
|
gtk_container_add (GTK_CONTAINER (bbox), button);
|
||||||
|
|
||||||
|
button = gtk_button_new_with_label (_("Help"));
|
||||||
|
gtk_container_add (GTK_CONTAINER (bbox), button);
|
||||||
|
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
do_button_box (GtkWidget *do_widget)
|
||||||
|
{
|
||||||
|
static GtkWidget *window = NULL;
|
||||||
|
GtkWidget *main_vbox;
|
||||||
|
GtkWidget *vbox;
|
||||||
|
GtkWidget *hbox;
|
||||||
|
GtkWidget *frame_horz;
|
||||||
|
GtkWidget *frame_vert;
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
gtk_window_set_display (GTK_WINDOW (window),
|
||||||
|
gtk_widget_get_display (do_widget));
|
||||||
|
gtk_window_set_title (GTK_WINDOW (window), "Button Boxes");
|
||||||
|
|
||||||
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed),
|
||||||
|
&window);
|
||||||
|
|
||||||
|
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||||
|
g_object_set (main_vbox, "margin", 10, NULL);
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), main_vbox);
|
||||||
|
|
||||||
|
frame_horz = gtk_frame_new ("Horizontal Button Boxes");
|
||||||
|
gtk_widget_set_margin_top (frame_horz, 10);
|
||||||
|
gtk_widget_set_margin_bottom (frame_horz, 10);
|
||||||
|
gtk_box_pack_start (GTK_BOX (main_vbox), frame_horz);
|
||||||
|
|
||||||
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||||
|
g_object_set (vbox, "margin", 10, NULL);
|
||||||
|
gtk_container_add (GTK_CONTAINER (frame_horz), vbox);
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox),
|
||||||
|
create_bbox (TRUE, "Spread", 40, GTK_BUTTONBOX_SPREAD));
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox),
|
||||||
|
create_bbox (TRUE, "Edge", 40, GTK_BUTTONBOX_EDGE));
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox),
|
||||||
|
create_bbox (TRUE, "Start", 40, GTK_BUTTONBOX_START));
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox),
|
||||||
|
create_bbox (TRUE, "End", 40, GTK_BUTTONBOX_END));
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox),
|
||||||
|
create_bbox (TRUE, "Center", 40, GTK_BUTTONBOX_CENTER));
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox),
|
||||||
|
create_bbox (TRUE, "Expand", 0, GTK_BUTTONBOX_EXPAND));
|
||||||
|
|
||||||
|
frame_vert = gtk_frame_new ("Vertical Button Boxes");
|
||||||
|
gtk_box_pack_start (GTK_BOX (main_vbox), frame_vert);
|
||||||
|
|
||||||
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||||
|
g_object_set (hbox, "margin", 10, NULL);
|
||||||
|
gtk_container_add (GTK_CONTAINER (frame_vert), hbox);
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (hbox),
|
||||||
|
create_bbox (FALSE, "Spread", 10, GTK_BUTTONBOX_SPREAD));
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (hbox),
|
||||||
|
create_bbox (FALSE, "Edge", 10, GTK_BUTTONBOX_EDGE));
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (hbox),
|
||||||
|
create_bbox (FALSE, "Start", 10, GTK_BUTTONBOX_START));
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (hbox),
|
||||||
|
create_bbox (FALSE, "End", 10, GTK_BUTTONBOX_END));
|
||||||
|
gtk_box_pack_start (GTK_BOX (hbox),
|
||||||
|
create_bbox (FALSE, "Center", 10, GTK_BUTTONBOX_CENTER));
|
||||||
|
gtk_box_pack_start (GTK_BOX (hbox),
|
||||||
|
create_bbox (FALSE, "Expand", 0, GTK_BUTTONBOX_EXPAND));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gtk_widget_get_visible (window))
|
||||||
|
gtk_widget_show (window);
|
||||||
|
else
|
||||||
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
||||||
556
demos/gtk-demo/changedisplay.c
Normal file
@@ -0,0 +1,556 @@
|
|||||||
|
/* Change Display
|
||||||
|
*
|
||||||
|
* Demonstrates migrating a window between different displays.
|
||||||
|
* A display is a mouse and keyboard with some number of
|
||||||
|
* associated monitors. The neat thing about having multiple
|
||||||
|
* displays is that they can be on a completely separate
|
||||||
|
* computers, as long as there is a network connection to the
|
||||||
|
* computer where the application is running.
|
||||||
|
*
|
||||||
|
* Only some of the windowing systems where GTK+ runs have the
|
||||||
|
* concept of multiple displays. (The X Window System is the
|
||||||
|
* main example.) Other windowing systems can only handle one
|
||||||
|
* keyboard and mouse, and combine all monitors into
|
||||||
|
* a single display.
|
||||||
|
*
|
||||||
|
* This is a moderately complex example, and demonstrates:
|
||||||
|
*
|
||||||
|
* - Tracking the currently open displays
|
||||||
|
*
|
||||||
|
* - Changing the display for a window
|
||||||
|
*
|
||||||
|
* - Letting the user choose a window by clicking on it
|
||||||
|
*
|
||||||
|
* - Using GtkListStore and GtkTreeView
|
||||||
|
*
|
||||||
|
* - Using GtkDialog
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
/* The ChangeDisplayInfo structure corresponds to a toplevel window and
|
||||||
|
* holds pointers to widgets inside the toplevel window along with other
|
||||||
|
* information about the contents of the window.
|
||||||
|
* This is a common organizational structure in real applications.
|
||||||
|
*/
|
||||||
|
typedef struct _ChangeDisplayInfo ChangeDisplayInfo;
|
||||||
|
|
||||||
|
struct _ChangeDisplayInfo
|
||||||
|
{
|
||||||
|
GtkWidget *window;
|
||||||
|
GtkSizeGroup *size_group;
|
||||||
|
|
||||||
|
GtkTreeModel *display_model;
|
||||||
|
|
||||||
|
GdkDisplay *current_display;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* These enumerations provide symbolic names for the columns
|
||||||
|
* in the two GtkListStore models.
|
||||||
|
*/
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
DISPLAY_COLUMN_NAME,
|
||||||
|
DISPLAY_COLUMN_DISPLAY,
|
||||||
|
DISPLAY_NUM_COLUMNS
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SCREEN_COLUMN_NUMBER,
|
||||||
|
SCREEN_COLUMN_SCREEN,
|
||||||
|
SCREEN_NUM_COLUMNS
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Finds the toplevel window under the mouse pointer, if any.
|
||||||
|
*/
|
||||||
|
static GtkWidget *
|
||||||
|
find_toplevel_at_pointer (GdkDisplay *display)
|
||||||
|
{
|
||||||
|
GdkSurface *pointer_window;
|
||||||
|
GtkWidget *widget = NULL;
|
||||||
|
|
||||||
|
pointer_window = gdk_device_get_surface_at_position (gtk_get_current_event_device (),
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
/* The user data field of a GdkSurface is used to store a pointer
|
||||||
|
* to the widget that created it.
|
||||||
|
*/
|
||||||
|
if (pointer_window)
|
||||||
|
{
|
||||||
|
gpointer widget_ptr;
|
||||||
|
gdk_surface_get_user_data (pointer_window, &widget_ptr);
|
||||||
|
widget = widget_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return widget ? gtk_widget_get_toplevel (widget) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
release_event_cb (GtkWidget *widget,
|
||||||
|
GdkEvent *event,
|
||||||
|
gboolean *clicked)
|
||||||
|
{
|
||||||
|
if (gdk_event_get_event_type (event) == GDK_BUTTON_RELEASE)
|
||||||
|
*clicked = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Asks the user to click on a window, then waits for them click
|
||||||
|
* the mouse. When the mouse is released, returns the toplevel
|
||||||
|
* window under the pointer, or NULL, if there is none.
|
||||||
|
*/
|
||||||
|
static GtkWidget *
|
||||||
|
query_for_toplevel (GdkDisplay *display,
|
||||||
|
const char *prompt)
|
||||||
|
{
|
||||||
|
GtkWidget *popup, *label, *frame;
|
||||||
|
GdkCursor *cursor;
|
||||||
|
GtkWidget *toplevel = NULL;
|
||||||
|
GdkDevice *device;
|
||||||
|
|
||||||
|
popup = gtk_window_new (GTK_WINDOW_POPUP);
|
||||||
|
gtk_window_set_display (GTK_WINDOW (popup), display);
|
||||||
|
gtk_window_set_modal (GTK_WINDOW (popup), TRUE);
|
||||||
|
gtk_window_set_position (GTK_WINDOW (popup), GTK_WIN_POS_CENTER);
|
||||||
|
|
||||||
|
frame = gtk_frame_new (NULL);
|
||||||
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
|
||||||
|
gtk_container_add (GTK_CONTAINER (popup), frame);
|
||||||
|
|
||||||
|
label = gtk_label_new (prompt);
|
||||||
|
g_object_set (label, "margin", 10, NULL);
|
||||||
|
gtk_container_add (GTK_CONTAINER (frame), label);
|
||||||
|
|
||||||
|
gtk_widget_show (popup);
|
||||||
|
cursor = gdk_cursor_new_from_name ("crosshair", NULL);
|
||||||
|
device = gtk_get_current_event_device ();
|
||||||
|
|
||||||
|
if (gdk_seat_grab (gdk_device_get_seat (device),
|
||||||
|
gtk_widget_get_surface (popup),
|
||||||
|
GDK_SEAT_CAPABILITY_ALL_POINTING,
|
||||||
|
FALSE, cursor, NULL, NULL, NULL) == GDK_GRAB_SUCCESS)
|
||||||
|
{
|
||||||
|
gboolean clicked = FALSE;
|
||||||
|
|
||||||
|
g_signal_connect (popup, "event",
|
||||||
|
G_CALLBACK (release_event_cb), &clicked);
|
||||||
|
|
||||||
|
/* Process events until clicked is set by our button release event handler.
|
||||||
|
* We pass in may_block=TRUE since we want to wait if there
|
||||||
|
* are no events currently.
|
||||||
|
*/
|
||||||
|
while (!clicked)
|
||||||
|
g_main_context_iteration (NULL, TRUE);
|
||||||
|
|
||||||
|
toplevel = find_toplevel_at_pointer (display);
|
||||||
|
if (toplevel == popup)
|
||||||
|
toplevel = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (cursor);
|
||||||
|
gtk_widget_destroy (popup);
|
||||||
|
|
||||||
|
return toplevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prompts the user for a toplevel window to move, and then moves
|
||||||
|
* that window to the currently selected display
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
query_change_display (ChangeDisplayInfo *info)
|
||||||
|
{
|
||||||
|
GdkDisplay *display = gtk_widget_get_display (info->window);
|
||||||
|
GtkWidget *toplevel;
|
||||||
|
|
||||||
|
toplevel = query_for_toplevel (display,
|
||||||
|
"Please select the toplevel\n"
|
||||||
|
"to move to the new display");
|
||||||
|
|
||||||
|
if (toplevel)
|
||||||
|
gtk_window_set_display (GTK_WINDOW (toplevel), info->current_display);
|
||||||
|
else
|
||||||
|
gdk_display_beep (display);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called when the user clicks on a button in our dialog or
|
||||||
|
* closes the dialog through the window manager. Unless the
|
||||||
|
* "Change" button was clicked, we destroy the dialog.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
response_cb (GtkDialog *dialog,
|
||||||
|
gint response_id,
|
||||||
|
ChangeDisplayInfo *info)
|
||||||
|
{
|
||||||
|
if (response_id == GTK_RESPONSE_OK)
|
||||||
|
query_change_display (info);
|
||||||
|
else
|
||||||
|
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called when the user clicks on "Open..." in the display
|
||||||
|
* frame. Prompts for a new display, and then opens a connection
|
||||||
|
* to that display.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
open_display_cb (GtkWidget *button,
|
||||||
|
ChangeDisplayInfo *info)
|
||||||
|
{
|
||||||
|
GtkWidget *content_area;
|
||||||
|
GtkWidget *dialog;
|
||||||
|
GtkWidget *display_entry;
|
||||||
|
GtkWidget *dialog_label;
|
||||||
|
gchar *new_screen_name = NULL;
|
||||||
|
GdkDisplay *result = NULL;
|
||||||
|
|
||||||
|
dialog = gtk_dialog_new_with_buttons ("Open Display",
|
||||||
|
GTK_WINDOW (info->window),
|
||||||
|
GTK_DIALOG_MODAL,
|
||||||
|
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||||
|
_("_OK"), GTK_RESPONSE_OK,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
|
||||||
|
display_entry = gtk_entry_new ();
|
||||||
|
gtk_entry_set_activates_default (GTK_ENTRY (display_entry), TRUE);
|
||||||
|
dialog_label =
|
||||||
|
gtk_label_new ("Please enter the name of\nthe new display\n");
|
||||||
|
|
||||||
|
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (content_area), dialog_label);
|
||||||
|
gtk_container_add (GTK_CONTAINER (content_area), display_entry);
|
||||||
|
|
||||||
|
gtk_widget_grab_focus (display_entry);
|
||||||
|
|
||||||
|
while (!result)
|
||||||
|
{
|
||||||
|
gint response_id = gtk_dialog_run (GTK_DIALOG (dialog));
|
||||||
|
if (response_id != GTK_RESPONSE_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
new_screen_name = gtk_editable_get_chars (GTK_EDITABLE (display_entry),
|
||||||
|
0, -1);
|
||||||
|
|
||||||
|
if (strcmp (new_screen_name, "") != 0)
|
||||||
|
{
|
||||||
|
result = gdk_display_open (new_screen_name);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
gchar *error_msg =
|
||||||
|
g_strdup_printf ("Can't open display:\n\t%s\nplease try another one\n",
|
||||||
|
new_screen_name);
|
||||||
|
gtk_label_set_text (GTK_LABEL (dialog_label), error_msg);
|
||||||
|
g_free (error_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (new_screen_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_destroy (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called when the user clicks on the "Close" button in the
|
||||||
|
* "Display" frame. Closes the selected display.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
close_display_cb (GtkWidget *button,
|
||||||
|
ChangeDisplayInfo *info)
|
||||||
|
{
|
||||||
|
if (info->current_display)
|
||||||
|
gdk_display_close (info->current_display);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called when the selected row in the display list changes.
|
||||||
|
* Updates info->current_display, then refills the list of
|
||||||
|
* screens.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
display_changed_cb (GtkTreeSelection *selection,
|
||||||
|
ChangeDisplayInfo *info)
|
||||||
|
{
|
||||||
|
GtkTreeModel *model;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
if (info->current_display)
|
||||||
|
g_object_unref (info->current_display);
|
||||||
|
if (gtk_tree_selection_get_selected (selection, &model, &iter))
|
||||||
|
gtk_tree_model_get (model, &iter,
|
||||||
|
DISPLAY_COLUMN_DISPLAY, &info->current_display,
|
||||||
|
-1);
|
||||||
|
else
|
||||||
|
info->current_display = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is used both for creating the "Display" and
|
||||||
|
* "Screen" frames, since they have a similar structure. The
|
||||||
|
* caller hooks up the right context for the value returned
|
||||||
|
* in tree_view, and packs any relevant buttons into button_vbox.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
create_frame (ChangeDisplayInfo *info,
|
||||||
|
const char *title,
|
||||||
|
GtkWidget **frame,
|
||||||
|
GtkWidget **tree_view,
|
||||||
|
GtkWidget **button_vbox)
|
||||||
|
{
|
||||||
|
GtkTreeSelection *selection;
|
||||||
|
GtkWidget *scrollwin;
|
||||||
|
GtkWidget *hbox;
|
||||||
|
|
||||||
|
*frame = gtk_frame_new (title);
|
||||||
|
|
||||||
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||||
|
g_object_set (hbox, "margin", 8, NULL);
|
||||||
|
gtk_container_add (GTK_CONTAINER (*frame), hbox);
|
||||||
|
|
||||||
|
scrollwin = gtk_scrolled_window_new (NULL, NULL);
|
||||||
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin),
|
||||||
|
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||||
|
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin),
|
||||||
|
GTK_SHADOW_IN);
|
||||||
|
gtk_box_pack_start (GTK_BOX (hbox), scrollwin);
|
||||||
|
|
||||||
|
*tree_view = gtk_tree_view_new ();
|
||||||
|
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (*tree_view), FALSE);
|
||||||
|
gtk_container_add (GTK_CONTAINER (scrollwin), *tree_view);
|
||||||
|
|
||||||
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (*tree_view));
|
||||||
|
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
|
||||||
|
|
||||||
|
*button_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
||||||
|
gtk_box_pack_start (GTK_BOX (hbox), *button_vbox);
|
||||||
|
|
||||||
|
if (!info->size_group)
|
||||||
|
info->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
||||||
|
|
||||||
|
gtk_size_group_add_widget (GTK_SIZE_GROUP (info->size_group), *button_vbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have a stack of buttons, it often looks better if their contents
|
||||||
|
* are left-aligned, rather than centered. This function creates a button
|
||||||
|
* and left-aligns it contents.
|
||||||
|
*/
|
||||||
|
GtkWidget *
|
||||||
|
left_align_button_new (const char *label)
|
||||||
|
{
|
||||||
|
GtkWidget *button = gtk_button_new_with_mnemonic (label);
|
||||||
|
GtkWidget *child = gtk_bin_get_child (GTK_BIN (button));
|
||||||
|
|
||||||
|
gtk_widget_set_halign (child, GTK_ALIGN_START);
|
||||||
|
gtk_widget_set_valign (child, GTK_ALIGN_CENTER);
|
||||||
|
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Creates the "Display" frame in the main window.
|
||||||
|
*/
|
||||||
|
GtkWidget *
|
||||||
|
create_display_frame (ChangeDisplayInfo *info)
|
||||||
|
{
|
||||||
|
GtkWidget *frame;
|
||||||
|
GtkWidget *tree_view;
|
||||||
|
GtkWidget *button_vbox;
|
||||||
|
GtkTreeViewColumn *column;
|
||||||
|
GtkTreeSelection *selection;
|
||||||
|
GtkWidget *button;
|
||||||
|
|
||||||
|
create_frame (info, "Display", &frame, &tree_view, &button_vbox);
|
||||||
|
|
||||||
|
button = left_align_button_new ("_Open...");
|
||||||
|
g_signal_connect (button, "clicked", G_CALLBACK (open_display_cb), info);
|
||||||
|
gtk_box_pack_start (GTK_BOX (button_vbox), button);
|
||||||
|
|
||||||
|
button = left_align_button_new ("_Close");
|
||||||
|
g_signal_connect (button, "clicked", G_CALLBACK (close_display_cb), info);
|
||||||
|
gtk_box_pack_start (GTK_BOX (button_vbox), button);
|
||||||
|
|
||||||
|
info->display_model = (GtkTreeModel *)gtk_list_store_new (DISPLAY_NUM_COLUMNS,
|
||||||
|
G_TYPE_STRING,
|
||||||
|
GDK_TYPE_DISPLAY);
|
||||||
|
|
||||||
|
gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), info->display_model);
|
||||||
|
|
||||||
|
column = gtk_tree_view_column_new_with_attributes ("Name",
|
||||||
|
gtk_cell_renderer_text_new (),
|
||||||
|
"text", DISPLAY_COLUMN_NAME,
|
||||||
|
NULL);
|
||||||
|
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
|
||||||
|
|
||||||
|
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
|
||||||
|
g_signal_connect (selection, "changed",
|
||||||
|
G_CALLBACK (display_changed_cb), info);
|
||||||
|
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called when one of the currently open displays is closed.
|
||||||
|
* Remove it from our list of displays.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
display_closed_cb (GdkDisplay *display,
|
||||||
|
gboolean is_error,
|
||||||
|
ChangeDisplayInfo *info)
|
||||||
|
{
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gboolean valid;
|
||||||
|
|
||||||
|
for (valid = gtk_tree_model_get_iter_first (info->display_model, &iter);
|
||||||
|
valid;
|
||||||
|
valid = gtk_tree_model_iter_next (info->display_model, &iter))
|
||||||
|
{
|
||||||
|
GdkDisplay *tmp_display;
|
||||||
|
|
||||||
|
gtk_tree_model_get (info->display_model, &iter,
|
||||||
|
DISPLAY_COLUMN_DISPLAY, &tmp_display,
|
||||||
|
-1);
|
||||||
|
if (tmp_display == display)
|
||||||
|
{
|
||||||
|
gtk_list_store_remove (GTK_LIST_STORE (info->display_model), &iter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adds a new display to our list of displays, and connects
|
||||||
|
* to the "closed" signal so that we can remove it from the
|
||||||
|
* list of displays again.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
add_display (ChangeDisplayInfo *info,
|
||||||
|
GdkDisplay *display)
|
||||||
|
{
|
||||||
|
const gchar *name = gdk_display_get_name (display);
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
gtk_list_store_append (GTK_LIST_STORE (info->display_model), &iter);
|
||||||
|
gtk_list_store_set (GTK_LIST_STORE (info->display_model), &iter,
|
||||||
|
DISPLAY_COLUMN_NAME, name,
|
||||||
|
DISPLAY_COLUMN_DISPLAY, display,
|
||||||
|
-1);
|
||||||
|
|
||||||
|
g_signal_connect (display, "closed",
|
||||||
|
G_CALLBACK (display_closed_cb), info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called when a new display is opened
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
display_opened_cb (GdkDisplayManager *manager,
|
||||||
|
GdkDisplay *display,
|
||||||
|
ChangeDisplayInfo *info)
|
||||||
|
{
|
||||||
|
add_display (info, display);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adds all currently open displays to our list of displays,
|
||||||
|
* and set up a signal connection so that we'll be notified
|
||||||
|
* when displays are opened in the future as well.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
initialize_displays (ChangeDisplayInfo *info)
|
||||||
|
{
|
||||||
|
GdkDisplayManager *manager = gdk_display_manager_get ();
|
||||||
|
GSList *displays = gdk_display_manager_list_displays (manager);
|
||||||
|
GSList *tmp_list;
|
||||||
|
|
||||||
|
for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
|
||||||
|
add_display (info, tmp_list->data);
|
||||||
|
|
||||||
|
g_slist_free (tmp_list);
|
||||||
|
|
||||||
|
g_signal_connect (manager, "display-opened",
|
||||||
|
G_CALLBACK (display_opened_cb), info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cleans up when the toplevel is destroyed; we remove the
|
||||||
|
* connections we use to track currently open displays, then
|
||||||
|
* free the ChangeDisplayInfo structure.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
destroy_info (ChangeDisplayInfo *info)
|
||||||
|
{
|
||||||
|
GdkDisplayManager *manager = gdk_display_manager_get ();
|
||||||
|
GSList *displays = gdk_display_manager_list_displays (manager);
|
||||||
|
GSList *tmp_list;
|
||||||
|
|
||||||
|
g_signal_handlers_disconnect_by_func (manager,
|
||||||
|
display_opened_cb,
|
||||||
|
info);
|
||||||
|
|
||||||
|
for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
|
||||||
|
g_signal_handlers_disconnect_by_func (tmp_list->data,
|
||||||
|
display_closed_cb,
|
||||||
|
info);
|
||||||
|
|
||||||
|
g_slist_free (tmp_list);
|
||||||
|
|
||||||
|
g_object_unref (info->size_group);
|
||||||
|
g_object_unref (info->display_model);
|
||||||
|
|
||||||
|
if (info->current_display)
|
||||||
|
g_object_unref (info->current_display);
|
||||||
|
|
||||||
|
g_free (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_cb (GObject *object,
|
||||||
|
ChangeDisplayInfo **info)
|
||||||
|
{
|
||||||
|
destroy_info (*info);
|
||||||
|
*info = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main entry point. If the dialog for this demo doesn't yet exist, creates
|
||||||
|
* it. Otherwise, destroys it.
|
||||||
|
*/
|
||||||
|
GtkWidget *
|
||||||
|
do_changedisplay (GtkWidget *do_widget)
|
||||||
|
{
|
||||||
|
static ChangeDisplayInfo *info = NULL;
|
||||||
|
|
||||||
|
if (!info)
|
||||||
|
{
|
||||||
|
GtkWidget *content_area;
|
||||||
|
GtkWidget *vbox;
|
||||||
|
GtkWidget *frame;
|
||||||
|
|
||||||
|
info = g_new0 (ChangeDisplayInfo, 1);
|
||||||
|
|
||||||
|
info->window = gtk_dialog_new_with_buttons ("Change Display",
|
||||||
|
GTK_WINDOW (do_widget),
|
||||||
|
0,
|
||||||
|
"Close", GTK_RESPONSE_CLOSE,
|
||||||
|
"Change", GTK_RESPONSE_OK,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
gtk_window_set_default_size (GTK_WINDOW (info->window), 300, 400);
|
||||||
|
|
||||||
|
g_signal_connect (info->window, "response",
|
||||||
|
G_CALLBACK (response_cb), info);
|
||||||
|
g_signal_connect (info->window, "destroy",
|
||||||
|
G_CALLBACK (destroy_cb), &info);
|
||||||
|
|
||||||
|
content_area = gtk_dialog_get_content_area (GTK_DIALOG (info->window));
|
||||||
|
|
||||||
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
||||||
|
g_object_set (vbox, "margin", 8, NULL);
|
||||||
|
gtk_box_pack_start (GTK_BOX (content_area), vbox);
|
||||||
|
|
||||||
|
frame = create_display_frame (info);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||||
|
|
||||||
|
initialize_displays (info);
|
||||||
|
|
||||||
|
gtk_widget_show (info->window);
|
||||||
|
return info->window;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_widget_destroy (info->window);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,11 +12,10 @@
|
|||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "demoimage.h"
|
|
||||||
|
|
||||||
static GtkWidget *window = NULL;
|
static GtkWidget *window = NULL;
|
||||||
|
|
||||||
static void
|
void
|
||||||
copy_button_clicked (GtkWidget *button,
|
copy_button_clicked (GtkWidget *button,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
@@ -29,10 +28,10 @@ copy_button_clicked (GtkWidget *button,
|
|||||||
clipboard = gtk_widget_get_clipboard (entry);
|
clipboard = gtk_widget_get_clipboard (entry);
|
||||||
|
|
||||||
/* Set clipboard text */
|
/* Set clipboard text */
|
||||||
gdk_clipboard_set_text (clipboard, gtk_editable_get_text (GTK_EDITABLE (entry)));
|
gdk_clipboard_set_text (clipboard, gtk_entry_get_text (GTK_ENTRY (entry)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
paste_received (GObject *source_object,
|
paste_received (GObject *source_object,
|
||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
@@ -51,7 +50,7 @@ paste_received (GObject *source_object,
|
|||||||
if (text)
|
if (text)
|
||||||
{
|
{
|
||||||
/* Set the entry text */
|
/* Set the entry text */
|
||||||
gtk_editable_set_text (GTK_EDITABLE (entry), text);
|
gtk_entry_set_text (GTK_ENTRY (entry), text);
|
||||||
g_free (text);
|
g_free (text);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -69,14 +68,14 @@ paste_received (GObject *source_object,
|
|||||||
"Could not paste text: %s",
|
"Could not paste text: %s",
|
||||||
error->message);
|
error->message);
|
||||||
g_signal_connect (dialog, "response",
|
g_signal_connect (dialog, "response",
|
||||||
G_CALLBACK (gtk_window_destroy), NULL);
|
G_CALLBACK (gtk_widget_destroy), NULL);
|
||||||
gtk_widget_show (dialog);
|
gtk_widget_show (dialog);
|
||||||
|
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
paste_button_clicked (GtkWidget *button,
|
paste_button_clicked (GtkWidget *button,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
@@ -94,6 +93,146 @@ paste_button_clicked (GtkWidget *button,
|
|||||||
gdk_clipboard_read_text_async (clipboard, NULL, paste_received, entry);
|
gdk_clipboard_read_text_async (clipboard, NULL, paste_received, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GdkPaintable *
|
||||||
|
get_image_paintable (GtkImage *image)
|
||||||
|
{
|
||||||
|
const gchar *icon_name;
|
||||||
|
GtkIconTheme *icon_theme;
|
||||||
|
GtkIconInfo *icon_info;
|
||||||
|
|
||||||
|
switch (gtk_image_get_storage_type (image))
|
||||||
|
{
|
||||||
|
case GTK_IMAGE_PAINTABLE:
|
||||||
|
return g_object_ref (gtk_image_get_paintable (image));
|
||||||
|
case GTK_IMAGE_ICON_NAME:
|
||||||
|
icon_name = gtk_image_get_icon_name (image);
|
||||||
|
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image)));
|
||||||
|
icon_info = gtk_icon_theme_lookup_icon (icon_theme, icon_name, 48, GTK_ICON_LOOKUP_GENERIC_FALLBACK);
|
||||||
|
if (icon_info == NULL)
|
||||||
|
return NULL;
|
||||||
|
return GDK_PAINTABLE (gtk_icon_info_load_texture (icon_info));
|
||||||
|
default:
|
||||||
|
g_warning ("Image storage type %d not handled",
|
||||||
|
gtk_image_get_storage_type (image));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drag_begin (GtkWidget *widget,
|
||||||
|
GdkDrag *drag,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GdkPaintable *paintable;
|
||||||
|
|
||||||
|
paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||||
|
if (paintable)
|
||||||
|
{
|
||||||
|
gtk_drag_set_icon_paintable (drag, paintable, -2, -2);
|
||||||
|
g_object_unref (paintable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
drag_data_get (GtkWidget *widget,
|
||||||
|
GdkDrag *drag,
|
||||||
|
GtkSelectionData *selection_data,
|
||||||
|
guint info,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GdkPaintable *paintable;
|
||||||
|
|
||||||
|
paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||||
|
if (GDK_IS_TEXTURE (paintable))
|
||||||
|
gtk_selection_data_set_texture (selection_data, GDK_TEXTURE (paintable));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drag_data_received (GtkWidget *widget,
|
||||||
|
GdkDrop *drop,
|
||||||
|
GtkSelectionData *selection_data,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
if (gtk_selection_data_get_length (selection_data) > 0)
|
||||||
|
{
|
||||||
|
GdkTexture *texture;
|
||||||
|
|
||||||
|
texture = gtk_selection_data_get_texture (selection_data);
|
||||||
|
gtk_image_set_from_paintable (GTK_IMAGE (data), GDK_PAINTABLE (texture));
|
||||||
|
g_object_unref (texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
copy_image (GtkMenuItem *item,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GdkClipboard *clipboard;
|
||||||
|
GdkPaintable *paintable;
|
||||||
|
|
||||||
|
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||||
|
paintable = get_image_paintable (GTK_IMAGE (data));
|
||||||
|
|
||||||
|
if (GDK_IS_TEXTURE (paintable))
|
||||||
|
gdk_clipboard_set_texture (clipboard, GDK_TEXTURE (paintable));
|
||||||
|
|
||||||
|
if (paintable)
|
||||||
|
g_object_unref (paintable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
paste_image_received (GObject *source,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GdkTexture *texture;
|
||||||
|
|
||||||
|
texture = gdk_clipboard_read_texture_finish (GDK_CLIPBOARD (source), result, NULL);
|
||||||
|
if (texture == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gtk_image_set_from_paintable (GTK_IMAGE (data), GDK_PAINTABLE (texture));
|
||||||
|
g_object_unref (texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
paste_image (GtkMenuItem *item,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GdkClipboard *clipboard;
|
||||||
|
|
||||||
|
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||||
|
gdk_clipboard_read_texture_async (clipboard,
|
||||||
|
NULL,
|
||||||
|
paste_image_received,
|
||||||
|
data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pressed_cb (GtkGesture *gesture,
|
||||||
|
int n_press,
|
||||||
|
double x,
|
||||||
|
double y,
|
||||||
|
GtkWidget *image)
|
||||||
|
{
|
||||||
|
GtkWidget *menu;
|
||||||
|
GtkWidget *item;
|
||||||
|
|
||||||
|
menu = gtk_menu_new ();
|
||||||
|
|
||||||
|
item = gtk_menu_item_new_with_mnemonic (_("_Copy"));
|
||||||
|
g_signal_connect (item, "activate", G_CALLBACK (copy_image), image);
|
||||||
|
gtk_widget_show (item);
|
||||||
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
||||||
|
|
||||||
|
item = gtk_menu_item_new_with_mnemonic (_("_Paste"));
|
||||||
|
g_signal_connect (item, "activate", G_CALLBACK (paste_image), image);
|
||||||
|
gtk_widget_show (item);
|
||||||
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
||||||
|
|
||||||
|
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
do_clipboard (GtkWidget *do_widget)
|
do_clipboard (GtkWidget *do_widget)
|
||||||
{
|
{
|
||||||
@@ -103,89 +242,118 @@ do_clipboard (GtkWidget *do_widget)
|
|||||||
GtkWidget *label;
|
GtkWidget *label;
|
||||||
GtkWidget *entry, *button;
|
GtkWidget *entry, *button;
|
||||||
GtkWidget *image;
|
GtkWidget *image;
|
||||||
|
GtkGesture *gesture;
|
||||||
|
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
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));
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Clipboard");
|
gtk_window_set_title (GTK_WINDOW (window), "Clipboard");
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
|
||||||
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||||
gtk_widget_set_margin_start (vbox, 8);
|
g_object_set (vbox, "margin", 8, NULL);
|
||||||
gtk_widget_set_margin_end (vbox, 8);
|
|
||||||
gtk_widget_set_margin_top (vbox, 8);
|
|
||||||
gtk_widget_set_margin_bottom (vbox, 8);
|
|
||||||
|
|
||||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||||
|
|
||||||
label = gtk_label_new ("\"Copy\" will copy the text\nin the entry to the clipboard");
|
label = gtk_label_new ("\"Copy\" will copy the text\nin the entry to the clipboard");
|
||||||
|
|
||||||
gtk_box_append (GTK_BOX (vbox), label);
|
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||||
|
|
||||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||||
gtk_widget_set_margin_start (hbox, 8);
|
g_object_set (hbox, "margin", 8, NULL);
|
||||||
gtk_widget_set_margin_end (hbox, 8);
|
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||||
gtk_widget_set_margin_top (hbox, 8);
|
|
||||||
gtk_widget_set_margin_bottom (hbox, 8);
|
|
||||||
gtk_box_append (GTK_BOX (vbox), hbox);
|
|
||||||
|
|
||||||
/* Create the first entry */
|
/* Create the first entry */
|
||||||
entry = gtk_entry_new ();
|
entry = gtk_entry_new ();
|
||||||
gtk_box_append (GTK_BOX (hbox), entry);
|
gtk_box_pack_start (GTK_BOX (hbox), entry);
|
||||||
|
|
||||||
/* Create the button */
|
/* Create the button */
|
||||||
button = gtk_button_new_with_mnemonic (_("_Copy"));
|
button = gtk_button_new_with_mnemonic (_("_Copy"));
|
||||||
gtk_box_append (GTK_BOX (hbox), button);
|
gtk_box_pack_start (GTK_BOX (hbox), button);
|
||||||
g_signal_connect (button, "clicked",
|
g_signal_connect (button, "clicked",
|
||||||
G_CALLBACK (copy_button_clicked), entry);
|
G_CALLBACK (copy_button_clicked), entry);
|
||||||
|
|
||||||
label = gtk_label_new ("\"Paste\" will paste the text from the clipboard to the entry");
|
label = gtk_label_new ("\"Paste\" will paste the text from the clipboard to the entry");
|
||||||
gtk_box_append (GTK_BOX (vbox), label);
|
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||||
|
|
||||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||||
gtk_widget_set_margin_start (hbox, 8);
|
g_object_set (hbox, "margin", 8, NULL);
|
||||||
gtk_widget_set_margin_end (hbox, 8);
|
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||||
gtk_widget_set_margin_top (hbox, 8);
|
|
||||||
gtk_widget_set_margin_bottom (hbox, 8);
|
|
||||||
gtk_box_append (GTK_BOX (vbox), hbox);
|
|
||||||
|
|
||||||
/* Create the second entry */
|
/* Create the second entry */
|
||||||
entry = gtk_entry_new ();
|
entry = gtk_entry_new ();
|
||||||
gtk_box_append (GTK_BOX (hbox), entry);
|
gtk_box_pack_start (GTK_BOX (hbox), entry);
|
||||||
|
|
||||||
/* Create the button */
|
/* Create the button */
|
||||||
button = gtk_button_new_with_mnemonic (_("_Paste"));
|
button = gtk_button_new_with_mnemonic (_("_Paste"));
|
||||||
gtk_box_append (GTK_BOX (hbox), button);
|
gtk_box_pack_start (GTK_BOX (hbox), button);
|
||||||
g_signal_connect (button, "clicked",
|
g_signal_connect (button, "clicked",
|
||||||
G_CALLBACK (paste_button_clicked), entry);
|
G_CALLBACK (paste_button_clicked), entry);
|
||||||
|
|
||||||
label = gtk_label_new ("Images can be transferred via the clipboard, too");
|
label = gtk_label_new ("Images can be transferred via the clipboard, too");
|
||||||
gtk_box_append (GTK_BOX (vbox), label);
|
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||||
|
|
||||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||||
gtk_widget_set_margin_start (hbox, 8);
|
g_object_set (hbox, "margin", 8, NULL);
|
||||||
gtk_widget_set_margin_end (hbox, 8);
|
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||||
gtk_widget_set_margin_top (hbox, 8);
|
|
||||||
gtk_widget_set_margin_bottom (hbox, 8);
|
|
||||||
gtk_box_append (GTK_BOX (vbox), hbox);
|
|
||||||
|
|
||||||
/* Create the first image */
|
/* Create the first image */
|
||||||
image = demo_image_new ("dialog-warning");
|
image = gtk_image_new_from_icon_name ("dialog-warning");
|
||||||
gtk_box_append (GTK_BOX (hbox), image);
|
gtk_container_add (GTK_CONTAINER (hbox), image);
|
||||||
|
|
||||||
|
/* make image a drag source */
|
||||||
|
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, GDK_ACTION_COPY);
|
||||||
|
gtk_drag_source_add_image_targets (image);
|
||||||
|
g_signal_connect (image, "drag-begin",
|
||||||
|
G_CALLBACK (drag_begin), image);
|
||||||
|
g_signal_connect (image, "drag-data-get",
|
||||||
|
G_CALLBACK (drag_data_get), image);
|
||||||
|
|
||||||
|
/* accept drops on image */
|
||||||
|
gtk_drag_dest_set (image, GTK_DEST_DEFAULT_ALL,
|
||||||
|
NULL, GDK_ACTION_COPY);
|
||||||
|
gtk_drag_dest_add_image_targets (image);
|
||||||
|
g_signal_connect (image, "drag-data-received",
|
||||||
|
G_CALLBACK (drag_data_received), image);
|
||||||
|
|
||||||
|
/* context menu on image */
|
||||||
|
gesture = gtk_gesture_multi_press_new ();
|
||||||
|
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||||
|
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
|
||||||
|
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
|
||||||
|
|
||||||
/* Create the second image */
|
/* Create the second image */
|
||||||
image = demo_image_new ("process-stop");
|
image = gtk_image_new_from_icon_name ("process-stop");
|
||||||
gtk_box_append (GTK_BOX (hbox), image);
|
gtk_container_add (GTK_CONTAINER (hbox), image);
|
||||||
|
|
||||||
/* Create the third image */
|
/* make image a drag source */
|
||||||
image = demo_image_new ("weather-clear");
|
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, GDK_ACTION_COPY);
|
||||||
gtk_box_append (GTK_BOX (hbox), image);
|
gtk_drag_source_add_image_targets (image);
|
||||||
|
g_signal_connect (image, "drag-begin",
|
||||||
|
G_CALLBACK (drag_begin), image);
|
||||||
|
g_signal_connect (image, "drag-data-get",
|
||||||
|
G_CALLBACK (drag_data_get), image);
|
||||||
|
|
||||||
|
/* accept drops on image */
|
||||||
|
gtk_drag_dest_set (image, GTK_DEST_DEFAULT_ALL,
|
||||||
|
NULL, GDK_ACTION_COPY);
|
||||||
|
gtk_drag_dest_add_image_targets (image);
|
||||||
|
g_signal_connect (image, "drag-data-received",
|
||||||
|
G_CALLBACK (drag_data_received), image);
|
||||||
|
|
||||||
|
/* context menu on image */
|
||||||
|
gesture = gtk_gesture_multi_press_new ();
|
||||||
|
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||||
|
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
|
||||||
|
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|||||||
116
demos/gtk-demo/colorsel.c
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/* Color Chooser
|
||||||
|
*
|
||||||
|
* A GtkColorChooser lets the user choose a color. There are several
|
||||||
|
* implementations of the GtkColorChooser interface in GTK+. The
|
||||||
|
* GtkColorChooserDialog is a prebuilt dialog containing a
|
||||||
|
* GtkColorChooserWidget.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
static GtkWidget *window = NULL;
|
||||||
|
static GtkWidget *da;
|
||||||
|
static GdkRGBA color;
|
||||||
|
static GtkWidget *frame;
|
||||||
|
|
||||||
|
/* draw callback for the drawing area
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
draw_function (GtkDrawingArea *da,
|
||||||
|
cairo_t *cr,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
gdk_cairo_set_source_rgba (cr, &color);
|
||||||
|
cairo_paint (cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
response_cb (GtkDialog *dialog,
|
||||||
|
gint response_id,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
if (response_id == GTK_RESPONSE_OK)
|
||||||
|
{
|
||||||
|
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (dialog), &color);
|
||||||
|
gtk_widget_queue_draw (da);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
change_color_callback (GtkWidget *button,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GtkWidget *dialog;
|
||||||
|
|
||||||
|
dialog = gtk_color_chooser_dialog_new ("Changing color", GTK_WINDOW (window));
|
||||||
|
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||||
|
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (dialog), &color);
|
||||||
|
|
||||||
|
g_signal_connect (dialog, "response",
|
||||||
|
G_CALLBACK (response_cb), NULL);
|
||||||
|
|
||||||
|
gtk_widget_show (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
do_colorsel (GtkWidget *do_widget)
|
||||||
|
{
|
||||||
|
GtkWidget *vbox;
|
||||||
|
GtkWidget *button;
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
color.red = 0;
|
||||||
|
color.blue = 1;
|
||||||
|
color.green = 0;
|
||||||
|
color.alpha = 1;
|
||||||
|
|
||||||
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
gtk_window_set_display (GTK_WINDOW (window),
|
||||||
|
gtk_widget_get_display (do_widget));
|
||||||
|
gtk_window_set_title (GTK_WINDOW (window), "Color Chooser");
|
||||||
|
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||||
|
|
||||||
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
|
||||||
|
g_object_set (vbox, "margin", 12, NULL);
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the color swatch area
|
||||||
|
*/
|
||||||
|
|
||||||
|
frame = gtk_frame_new (NULL);
|
||||||
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||||
|
|
||||||
|
da = gtk_drawing_area_new ();
|
||||||
|
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 200);
|
||||||
|
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 200);
|
||||||
|
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), draw_function, NULL, NULL);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (frame), da);
|
||||||
|
|
||||||
|
button = gtk_button_new_with_mnemonic ("_Change the above color");
|
||||||
|
gtk_widget_set_halign (button, GTK_ALIGN_END);
|
||||||
|
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), button);
|
||||||
|
|
||||||
|
g_signal_connect (button, "clicked",
|
||||||
|
G_CALLBACK (change_color_callback), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gtk_widget_get_visible (window))
|
||||||
|
gtk_widget_show (window);
|
||||||
|
else
|
||||||
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ enum
|
|||||||
static GtkTreeModel *
|
static GtkTreeModel *
|
||||||
create_icon_store (void)
|
create_icon_store (void)
|
||||||
{
|
{
|
||||||
const char *icon_names[6] = {
|
const gchar *icon_names[6] = {
|
||||||
"dialog-warning",
|
"dialog-warning",
|
||||||
"process-stop",
|
"process-stop",
|
||||||
"document-new",
|
"document-new",
|
||||||
@@ -27,7 +27,7 @@ create_icon_store (void)
|
|||||||
NULL,
|
NULL,
|
||||||
"document-open"
|
"document-open"
|
||||||
};
|
};
|
||||||
const char *labels[6] = {
|
const gchar *labels[6] = {
|
||||||
N_("Warning"),
|
N_("Warning"),
|
||||||
N_("Stop"),
|
N_("Stop"),
|
||||||
N_("New"),
|
N_("New"),
|
||||||
@@ -38,7 +38,7 @@ create_icon_store (void)
|
|||||||
|
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
GtkListStore *store;
|
GtkListStore *store;
|
||||||
int i;
|
gint i;
|
||||||
|
|
||||||
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
|
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ set_sensitive (GtkCellLayout *cell_layout,
|
|||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
GtkTreePath *path;
|
GtkTreePath *path;
|
||||||
int *indices;
|
gint *indices;
|
||||||
gboolean sensitive;
|
gboolean sensitive;
|
||||||
|
|
||||||
path = gtk_tree_model_get_path (tree_model, iter);
|
path = gtk_tree_model_get_path (tree_model, iter);
|
||||||
@@ -111,8 +111,8 @@ static GtkTreeModel *
|
|||||||
create_capital_store (void)
|
create_capital_store (void)
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
const char *group;
|
gchar *group;
|
||||||
const char *capital;
|
gchar *capital;
|
||||||
} capitals[] = {
|
} capitals[] = {
|
||||||
{ "A - B", NULL },
|
{ "A - B", NULL },
|
||||||
{ NULL, "Albany" },
|
{ NULL, "Albany" },
|
||||||
@@ -144,7 +144,7 @@ create_capital_store (void)
|
|||||||
{ NULL, "Jackson" },
|
{ NULL, "Jackson" },
|
||||||
{ NULL, "Jefferson City" },
|
{ NULL, "Jefferson City" },
|
||||||
{ NULL, "Juneau" },
|
{ NULL, "Juneau" },
|
||||||
{ "K - O", NULL },
|
{ "K - O" },
|
||||||
{ NULL, "Lansing" },
|
{ NULL, "Lansing" },
|
||||||
{ NULL, "Lincoln" },
|
{ NULL, "Lincoln" },
|
||||||
{ NULL, "Little Rock" },
|
{ NULL, "Little Rock" },
|
||||||
@@ -154,7 +154,7 @@ create_capital_store (void)
|
|||||||
{ NULL, "Nashville" },
|
{ NULL, "Nashville" },
|
||||||
{ NULL, "Oklahoma City" },
|
{ NULL, "Oklahoma City" },
|
||||||
{ NULL, "Olympia" },
|
{ NULL, "Olympia" },
|
||||||
{ "P - S", NULL },
|
{ NULL, "P - S" },
|
||||||
{ NULL, "Phoenix" },
|
{ NULL, "Phoenix" },
|
||||||
{ NULL, "Pierre" },
|
{ NULL, "Pierre" },
|
||||||
{ NULL, "Providence" },
|
{ NULL, "Providence" },
|
||||||
@@ -175,7 +175,7 @@ create_capital_store (void)
|
|||||||
|
|
||||||
GtkTreeIter iter, iter2;
|
GtkTreeIter iter, iter2;
|
||||||
GtkTreeStore *store;
|
GtkTreeStore *store;
|
||||||
int i;
|
gint i;
|
||||||
|
|
||||||
store = gtk_tree_store_new (1, G_TYPE_STRING);
|
store = gtk_tree_store_new (1, G_TYPE_STRING);
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ typedef struct _MaskEntry MaskEntry;
|
|||||||
struct _MaskEntry
|
struct _MaskEntry
|
||||||
{
|
{
|
||||||
GtkEntry entry;
|
GtkEntry entry;
|
||||||
const char *mask;
|
gchar *mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _MaskEntryClass MaskEntryClass;
|
typedef struct _MaskEntryClass MaskEntryClass;
|
||||||
@@ -246,7 +246,6 @@ struct _MaskEntryClass
|
|||||||
|
|
||||||
static void mask_entry_editable_init (GtkEditableInterface *iface);
|
static void mask_entry_editable_init (GtkEditableInterface *iface);
|
||||||
|
|
||||||
static GType mask_entry_get_type (void);
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (MaskEntry, mask_entry, GTK_TYPE_ENTRY,
|
G_DEFINE_TYPE_WITH_CODE (MaskEntry, mask_entry, GTK_TYPE_ENTRY,
|
||||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
|
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
|
||||||
mask_entry_editable_init));
|
mask_entry_editable_init));
|
||||||
@@ -257,7 +256,7 @@ mask_entry_set_background (MaskEntry *entry)
|
|||||||
{
|
{
|
||||||
if (entry->mask)
|
if (entry->mask)
|
||||||
{
|
{
|
||||||
if (!g_regex_match_simple (entry->mask, gtk_editable_get_text (GTK_EDITABLE (entry)), 0, 0))
|
if (!g_regex_match_simple (entry->mask, gtk_entry_get_text (GTK_ENTRY (entry)), 0, 0))
|
||||||
{
|
{
|
||||||
PangoAttrList *attrs;
|
PangoAttrList *attrs;
|
||||||
|
|
||||||
@@ -311,36 +310,32 @@ do_combobox (GtkWidget *do_widget)
|
|||||||
|
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
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));
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Combo Boxes");
|
gtk_window_set_title (GTK_WINDOW (window), "Combo Boxes");
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
|
||||||
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
||||||
gtk_widget_set_margin_start (vbox, 10);
|
g_object_set (vbox, "margin", 10, NULL);
|
||||||
gtk_widget_set_margin_end (vbox, 10);
|
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||||
gtk_widget_set_margin_top (vbox, 10);
|
|
||||||
gtk_widget_set_margin_bottom (vbox, 10);
|
|
||||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
|
||||||
|
|
||||||
/* A combobox demonstrating cell renderers, separators and
|
/* A combobox demonstrating cell renderers, separators and
|
||||||
* insensitive rows
|
* insensitive rows
|
||||||
*/
|
*/
|
||||||
frame = gtk_frame_new ("Items with icons");
|
frame = gtk_frame_new ("Items with icons");
|
||||||
gtk_box_append (GTK_BOX (vbox), frame);
|
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||||
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||||
gtk_widget_set_margin_start (box, 5);
|
g_object_set (box, "margin", 5, NULL);
|
||||||
gtk_widget_set_margin_end (box, 5);
|
gtk_container_add (GTK_CONTAINER (frame), box);
|
||||||
gtk_widget_set_margin_top (box, 5);
|
|
||||||
gtk_widget_set_margin_bottom (box, 5);
|
|
||||||
gtk_frame_set_child (GTK_FRAME (frame), box);
|
|
||||||
|
|
||||||
model = create_icon_store ();
|
model = create_icon_store ();
|
||||||
combo = gtk_combo_box_new_with_model (model);
|
combo = gtk_combo_box_new_with_model (model);
|
||||||
g_object_unref (model);
|
g_object_unref (model);
|
||||||
gtk_box_append (GTK_BOX (box), combo);
|
gtk_container_add (GTK_CONTAINER (box), combo);
|
||||||
|
|
||||||
renderer = gtk_cell_renderer_pixbuf_new ();
|
renderer = gtk_cell_renderer_pixbuf_new ();
|
||||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
|
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
|
||||||
@@ -372,19 +367,16 @@ do_combobox (GtkWidget *do_widget)
|
|||||||
/* A combobox demonstrating trees.
|
/* A combobox demonstrating trees.
|
||||||
*/
|
*/
|
||||||
frame = gtk_frame_new ("Where are we ?");
|
frame = gtk_frame_new ("Where are we ?");
|
||||||
gtk_box_append (GTK_BOX (vbox), frame);
|
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||||
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||||
gtk_widget_set_margin_start (box, 5);
|
g_object_set (box, "margin", 5, NULL);
|
||||||
gtk_widget_set_margin_end (box, 5);
|
gtk_container_add (GTK_CONTAINER (frame), box);
|
||||||
gtk_widget_set_margin_top (box, 5);
|
|
||||||
gtk_widget_set_margin_bottom (box, 5);
|
|
||||||
gtk_frame_set_child (GTK_FRAME (frame), box);
|
|
||||||
|
|
||||||
model = create_capital_store ();
|
model = create_capital_store ();
|
||||||
combo = gtk_combo_box_new_with_model (model);
|
combo = gtk_combo_box_new_with_model (model);
|
||||||
g_object_unref (model);
|
g_object_unref (model);
|
||||||
gtk_box_append (GTK_BOX (box), combo);
|
gtk_container_add (GTK_CONTAINER (box), combo);
|
||||||
|
|
||||||
renderer = gtk_cell_renderer_text_new ();
|
renderer = gtk_cell_renderer_text_new ();
|
||||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
|
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
|
||||||
@@ -403,52 +395,47 @@ do_combobox (GtkWidget *do_widget)
|
|||||||
|
|
||||||
/* A GtkComboBoxEntry with validation */
|
/* A GtkComboBoxEntry with validation */
|
||||||
frame = gtk_frame_new ("Editable");
|
frame = gtk_frame_new ("Editable");
|
||||||
gtk_box_append (GTK_BOX (vbox), frame);
|
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||||
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||||
gtk_widget_set_margin_start (box, 5);
|
g_object_set (box, "margin", 5, NULL);
|
||||||
gtk_widget_set_margin_end (box, 5);
|
gtk_container_add (GTK_CONTAINER (frame), box);
|
||||||
gtk_widget_set_margin_top (box, 5);
|
|
||||||
gtk_widget_set_margin_bottom (box, 5);
|
|
||||||
gtk_frame_set_child (GTK_FRAME (frame), box);
|
|
||||||
|
|
||||||
combo = gtk_combo_box_text_new_with_entry ();
|
combo = gtk_combo_box_text_new_with_entry ();
|
||||||
fill_combo_entry (combo);
|
fill_combo_entry (combo);
|
||||||
gtk_box_append (GTK_BOX (box), combo);
|
gtk_container_add (GTK_CONTAINER (box), combo);
|
||||||
|
|
||||||
entry = g_object_new (TYPE_MASK_ENTRY, NULL);
|
entry = g_object_new (TYPE_MASK_ENTRY, NULL);
|
||||||
MASK_ENTRY (entry)->mask = "^([0-9]*|One|Two|2\302\275|Three)$";
|
MASK_ENTRY (entry)->mask = "^([0-9]*|One|Two|2\302\275|Three)$";
|
||||||
|
|
||||||
gtk_combo_box_set_child (GTK_COMBO_BOX (combo), entry);
|
gtk_container_remove (GTK_CONTAINER (combo), gtk_bin_get_child (GTK_BIN (combo)));
|
||||||
|
gtk_container_add (GTK_CONTAINER (combo), entry);
|
||||||
|
|
||||||
/* A combobox with string IDs */
|
/* A combobox with string IDs */
|
||||||
frame = gtk_frame_new ("String IDs");
|
frame = gtk_frame_new ("String IDs");
|
||||||
gtk_box_append (GTK_BOX (vbox), frame);
|
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||||
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||||
gtk_widget_set_margin_start (box, 5);
|
g_object_set (box, "margin", 5, NULL);
|
||||||
gtk_widget_set_margin_end (box, 5);
|
gtk_container_add (GTK_CONTAINER (frame), box);
|
||||||
gtk_widget_set_margin_top (box, 5);
|
|
||||||
gtk_widget_set_margin_bottom (box, 5);
|
|
||||||
gtk_frame_set_child (GTK_FRAME (frame), box);
|
|
||||||
|
|
||||||
combo = gtk_combo_box_text_new ();
|
combo = gtk_combo_box_text_new ();
|
||||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "never", "Not visible");
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "never", "Not visible");
|
||||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "when-active", "Visible when active");
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "when-active", "Visible when active");
|
||||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "always", "Always visible");
|
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "always", "Always visible");
|
||||||
gtk_box_append (GTK_BOX (box), combo);
|
gtk_container_add (GTK_CONTAINER (box), combo);
|
||||||
|
|
||||||
entry = gtk_entry_new ();
|
entry = gtk_entry_new ();
|
||||||
g_object_bind_property (combo, "active-id",
|
g_object_bind_property (combo, "active-id",
|
||||||
entry, "text",
|
entry, "text",
|
||||||
G_BINDING_BIDIRECTIONAL);
|
G_BINDING_BIDIRECTIONAL);
|
||||||
gtk_box_append (GTK_BOX (box), entry);
|
gtk_container_add (GTK_CONTAINER (box), entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,289 +0,0 @@
|
|||||||
/* Constraints/Simple
|
|
||||||
*
|
|
||||||
* GtkConstraintLayout provides a layout manager that uses relations
|
|
||||||
* between widgets (also known as "constraints") to compute the position
|
|
||||||
* and size of each child.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (SimpleGrid, simple_grid, SIMPLE, GRID, GtkWidget)
|
|
||||||
|
|
||||||
struct _SimpleGrid
|
|
||||||
{
|
|
||||||
GtkWidget parent_instance;
|
|
||||||
|
|
||||||
GtkWidget *button1, *button2;
|
|
||||||
GtkWidget *button3;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (SimpleGrid, simple_grid, GTK_TYPE_WIDGET)
|
|
||||||
|
|
||||||
static void
|
|
||||||
simple_grid_dispose (GObject *object)
|
|
||||||
{
|
|
||||||
SimpleGrid *self = SIMPLE_GRID (object);
|
|
||||||
|
|
||||||
g_clear_pointer (&self->button1, gtk_widget_unparent);
|
|
||||||
g_clear_pointer (&self->button2, gtk_widget_unparent);
|
|
||||||
g_clear_pointer (&self->button3, gtk_widget_unparent);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (simple_grid_parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
simple_grid_class_init (SimpleGridClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
||||||
|
|
||||||
object_class->dispose = simple_grid_dispose;
|
|
||||||
|
|
||||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Layout:
|
|
||||||
*
|
|
||||||
* +-------------------------------------+
|
|
||||||
* | +-----------++-------++-----------+ |
|
|
||||||
* | | Child 1 || Space || Child 2 | |
|
|
||||||
* | +-----------++-------++-----------+ |
|
|
||||||
* | +---------------------------------+ |
|
|
||||||
* | | Child 3 | |
|
|
||||||
* | +---------------------------------+ |
|
|
||||||
* +-------------------------------------+
|
|
||||||
*
|
|
||||||
* Constraints:
|
|
||||||
*
|
|
||||||
* super.start = child1.start - 8
|
|
||||||
* child1.width = child2.width
|
|
||||||
* child1.end = space.start
|
|
||||||
* space.end = child2.start
|
|
||||||
* child2.end = super.end - 8
|
|
||||||
* super.start = child3.start - 8
|
|
||||||
* child3.end = super.end - 8
|
|
||||||
* super.top = child1.top - 8
|
|
||||||
* super.top = child2.top - 8
|
|
||||||
* child1.bottom = child3.top - 12
|
|
||||||
* child2.bottom = child3.top - 12
|
|
||||||
* child3.height = child1.height
|
|
||||||
* child3.height = child2.height
|
|
||||||
* child3.bottom = super.bottom - 8
|
|
||||||
*
|
|
||||||
* To add some flexibility, we make the space
|
|
||||||
* stretchable:
|
|
||||||
*
|
|
||||||
* space.width >= 10
|
|
||||||
* space.width = 100
|
|
||||||
* space.width <= 200
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
build_constraints (SimpleGrid *self,
|
|
||||||
GtkConstraintLayout *manager)
|
|
||||||
{
|
|
||||||
GtkConstraintGuide *guide;
|
|
||||||
|
|
||||||
guide = gtk_constraint_guide_new ();
|
|
||||||
gtk_constraint_guide_set_name (guide, "space");
|
|
||||||
gtk_constraint_guide_set_min_size (guide, 10, 10);
|
|
||||||
gtk_constraint_guide_set_nat_size (guide, 100, 10);
|
|
||||||
gtk_constraint_guide_set_max_size (guide, 200, 20);
|
|
||||||
gtk_constraint_guide_set_strength (guide, GTK_CONSTRAINT_STRENGTH_STRONG);
|
|
||||||
gtk_constraint_layout_add_guide (manager, guide);
|
|
||||||
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->button1),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
|
||||||
GTK_CONSTRAINT_RELATION_LE,
|
|
||||||
200.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (NULL,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
self->button1,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
|
||||||
1.0,
|
|
||||||
-8.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (self->button1,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
self->button2,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (self->button1,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
guide,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (guide,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
self->button2,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (self->button2,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
NULL,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
|
||||||
1.0,
|
|
||||||
-8.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (NULL,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
self->button3,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
|
||||||
1.0,
|
|
||||||
-8.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (self->button3,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
NULL,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
|
||||||
1.0,
|
|
||||||
-8.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (NULL,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
self->button1,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
|
||||||
1.0,
|
|
||||||
-8.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (NULL,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
self->button2,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
|
||||||
1.0,
|
|
||||||
-8.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (self->button1,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
self->button3,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
|
||||||
1.0,
|
|
||||||
-12.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (self->button2,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
self->button3,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
|
||||||
1.0,
|
|
||||||
-12.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (self->button3,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
self->button1,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (self->button3,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
self->button2,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (self->button3,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
NULL,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
|
||||||
1.0,
|
|
||||||
-8.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
simple_grid_init (SimpleGrid *self)
|
|
||||||
{
|
|
||||||
GtkWidget *widget = GTK_WIDGET (self);
|
|
||||||
|
|
||||||
self->button1 = gtk_button_new_with_label ("Child 1");
|
|
||||||
gtk_widget_set_parent (self->button1, widget);
|
|
||||||
gtk_widget_set_name (self->button1, "button1");
|
|
||||||
|
|
||||||
self->button2 = gtk_button_new_with_label ("Child 2");
|
|
||||||
gtk_widget_set_parent (self->button2, widget);
|
|
||||||
gtk_widget_set_name (self->button2, "button2");
|
|
||||||
|
|
||||||
self->button3 = gtk_button_new_with_label ("Child 3");
|
|
||||||
gtk_widget_set_parent (self->button3, widget);
|
|
||||||
gtk_widget_set_name (self->button3, "button3");
|
|
||||||
|
|
||||||
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
|
||||||
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget *
|
|
||||||
do_constraints (GtkWidget *do_widget)
|
|
||||||
{
|
|
||||||
static GtkWidget *window;
|
|
||||||
|
|
||||||
if (!window)
|
|
||||||
{
|
|
||||||
GtkWidget *header, *box, *grid, *button;
|
|
||||||
|
|
||||||
window = gtk_window_new ();
|
|
||||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
|
|
||||||
|
|
||||||
header = gtk_header_bar_new ();
|
|
||||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
|
||||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
|
||||||
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
|
||||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
|
||||||
|
|
||||||
grid = g_object_new (simple_grid_get_type (), NULL);
|
|
||||||
gtk_widget_set_hexpand (grid, TRUE);
|
|
||||||
gtk_widget_set_vexpand (grid, TRUE);
|
|
||||||
gtk_box_append (GTK_BOX (box), grid);
|
|
||||||
|
|
||||||
button = gtk_button_new_with_label ("Close");
|
|
||||||
gtk_box_append (GTK_BOX (box), button);
|
|
||||||
gtk_widget_set_hexpand (grid, TRUE);
|
|
||||||
g_signal_connect_swapped (button, "clicked",
|
|
||||||
G_CALLBACK (gtk_window_destroy), window);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
|
||||||
gtk_widget_show (window);
|
|
||||||
else
|
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
|
||||||
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
@@ -1,245 +0,0 @@
|
|||||||
/* Constraints/Interactive
|
|
||||||
*
|
|
||||||
* Demonstrate how constraints can be updates during user interaction.
|
|
||||||
* The vertical edge between the buttons can be dragged with the mouse.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (InteractiveGrid, interactive_grid, INTERACTIVE, GRID, GtkWidget)
|
|
||||||
|
|
||||||
struct _InteractiveGrid
|
|
||||||
{
|
|
||||||
GtkWidget parent_instance;
|
|
||||||
|
|
||||||
GtkWidget *button1, *button2;
|
|
||||||
GtkWidget *button3;
|
|
||||||
GtkConstraintGuide *guide;
|
|
||||||
GtkConstraint *constraint;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (InteractiveGrid, interactive_grid, GTK_TYPE_WIDGET)
|
|
||||||
|
|
||||||
static void
|
|
||||||
interactive_grid_dispose (GObject *object)
|
|
||||||
{
|
|
||||||
InteractiveGrid *self = INTERACTIVE_GRID (object);
|
|
||||||
|
|
||||||
g_clear_pointer (&self->button1, gtk_widget_unparent);
|
|
||||||
g_clear_pointer (&self->button2, gtk_widget_unparent);
|
|
||||||
g_clear_pointer (&self->button3, gtk_widget_unparent);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (interactive_grid_parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
interactive_grid_class_init (InteractiveGridClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
||||||
|
|
||||||
object_class->dispose = interactive_grid_dispose;
|
|
||||||
|
|
||||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
build_constraints (InteractiveGrid *self,
|
|
||||||
GtkConstraintLayout *manager)
|
|
||||||
{
|
|
||||||
self->guide = g_object_new (GTK_TYPE_CONSTRAINT_GUIDE, NULL);
|
|
||||||
gtk_constraint_layout_add_guide (manager, self->guide);
|
|
||||||
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
0.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (NULL,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
GTK_CONSTRAINT_TARGET (self->button1),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
|
||||||
1.0,
|
|
||||||
-8.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button1),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
GTK_CONSTRAINT_TARGET (self->guide),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
GTK_CONSTRAINT_TARGET (self->guide),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
NULL,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
|
||||||
1.0,
|
|
||||||
-8.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (NULL,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
GTK_CONSTRAINT_TARGET (self->button3),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
|
||||||
1.0,
|
|
||||||
-8.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
GTK_CONSTRAINT_TARGET (self->guide),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (NULL,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
GTK_CONSTRAINT_TARGET (self->button1),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
|
||||||
1.0,
|
|
||||||
-8.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
GTK_CONSTRAINT_TARGET (self->button1),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
GTK_CONSTRAINT_TARGET (self->button2),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
gtk_constraint_layout_add_constraint (manager,
|
|
||||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
NULL,
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
|
||||||
1.0,
|
|
||||||
-8.0,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
drag_cb (GtkGestureDrag *drag,
|
|
||||||
double offset_x,
|
|
||||||
double offset_y,
|
|
||||||
InteractiveGrid *self)
|
|
||||||
{
|
|
||||||
GtkConstraintLayout *layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (self)));
|
|
||||||
double x, y;
|
|
||||||
|
|
||||||
if (self->constraint)
|
|
||||||
{
|
|
||||||
gtk_constraint_layout_remove_constraint (layout, self->constraint);
|
|
||||||
g_clear_object (&self->constraint);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_gesture_drag_get_start_point (drag, &x, &y);
|
|
||||||
self->constraint = gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide),
|
|
||||||
GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
|
||||||
GTK_CONSTRAINT_RELATION_EQ,
|
|
||||||
x + offset_x,
|
|
||||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
|
||||||
gtk_constraint_layout_add_constraint (layout, g_object_ref (self->constraint));
|
|
||||||
gtk_widget_queue_allocate (GTK_WIDGET (self));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
interactive_grid_init (InteractiveGrid *self)
|
|
||||||
{
|
|
||||||
GtkWidget *widget = GTK_WIDGET (self);
|
|
||||||
GtkGesture *drag;
|
|
||||||
|
|
||||||
self->button1 = gtk_button_new_with_label ("Child 1");
|
|
||||||
gtk_widget_set_parent (self->button1, widget);
|
|
||||||
gtk_widget_set_name (self->button1, "button1");
|
|
||||||
|
|
||||||
self->button2 = gtk_button_new_with_label ("Child 2");
|
|
||||||
gtk_widget_set_parent (self->button2, widget);
|
|
||||||
gtk_widget_set_name (self->button2, "button2");
|
|
||||||
|
|
||||||
self->button3 = gtk_button_new_with_label ("Child 3");
|
|
||||||
gtk_widget_set_parent (self->button3, widget);
|
|
||||||
gtk_widget_set_name (self->button3, "button3");
|
|
||||||
|
|
||||||
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
|
||||||
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
|
|
||||||
|
|
||||||
drag = gtk_gesture_drag_new ();
|
|
||||||
g_signal_connect (drag, "drag-update", G_CALLBACK (drag_cb), self);
|
|
||||||
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (drag));
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget *
|
|
||||||
do_constraints2 (GtkWidget *do_widget)
|
|
||||||
{
|
|
||||||
static GtkWidget *window;
|
|
||||||
|
|
||||||
if (!window)
|
|
||||||
{
|
|
||||||
GtkWidget *header, *box, *grid, *button;
|
|
||||||
|
|
||||||
window = gtk_window_new ();
|
|
||||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
|
|
||||||
|
|
||||||
header = gtk_header_bar_new ();
|
|
||||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
|
||||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
|
||||||
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
|
||||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
|
||||||
|
|
||||||
grid = g_object_new (interactive_grid_get_type (), NULL);
|
|
||||||
gtk_widget_set_hexpand (grid, TRUE);
|
|
||||||
gtk_widget_set_vexpand (grid, TRUE);
|
|
||||||
gtk_box_append (GTK_BOX (box), grid);
|
|
||||||
|
|
||||||
button = gtk_button_new_with_label ("Close");
|
|
||||||
gtk_box_append (GTK_BOX (box), button);
|
|
||||||
gtk_widget_set_hexpand (grid, TRUE);
|
|
||||||
g_signal_connect_swapped (button, "clicked",
|
|
||||||
G_CALLBACK (gtk_window_destroy), window);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
|
||||||
gtk_widget_show (window);
|
|
||||||
else
|
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
|
||||||
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
/* Constraints/VFL
|
|
||||||
*
|
|
||||||
* GtkConstraintLayout allows defining constraints using a
|
|
||||||
* compact syntax called Visual Format Language, or VFL.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (VflGrid, vfl_grid, VFL, GRID, GtkWidget)
|
|
||||||
|
|
||||||
struct _VflGrid
|
|
||||||
{
|
|
||||||
GtkWidget parent_instance;
|
|
||||||
|
|
||||||
GtkWidget *button1, *button2;
|
|
||||||
GtkWidget *button3;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (VflGrid, vfl_grid, GTK_TYPE_WIDGET)
|
|
||||||
|
|
||||||
static void
|
|
||||||
vfl_grid_dispose (GObject *object)
|
|
||||||
{
|
|
||||||
VflGrid *self = VFL_GRID (object);
|
|
||||||
|
|
||||||
g_clear_pointer (&self->button1, gtk_widget_unparent);
|
|
||||||
g_clear_pointer (&self->button2, gtk_widget_unparent);
|
|
||||||
g_clear_pointer (&self->button3, gtk_widget_unparent);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (vfl_grid_parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vfl_grid_class_init (VflGridClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
||||||
|
|
||||||
object_class->dispose = vfl_grid_dispose;
|
|
||||||
|
|
||||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Layout:
|
|
||||||
*
|
|
||||||
* +-----------------------------+
|
|
||||||
* | +-----------+ +-----------+ |
|
|
||||||
* | | Child 1 | | Child 2 | |
|
|
||||||
* | +-----------+ +-----------+ |
|
|
||||||
* | +-------------------------+ |
|
|
||||||
* | | Child 3 | |
|
|
||||||
* | +-------------------------+ |
|
|
||||||
* +-----------------------------+
|
|
||||||
*
|
|
||||||
* Constraints:
|
|
||||||
*
|
|
||||||
* super.start = child1.start - 8
|
|
||||||
* child1.width = child2.width
|
|
||||||
* child1.end = child2.start - 12
|
|
||||||
* child2.end = super.end - 8
|
|
||||||
* super.start = child3.start - 8
|
|
||||||
* child3.end = super.end - 8
|
|
||||||
* super.top = child1.top - 8
|
|
||||||
* super.top = child2.top - 8
|
|
||||||
* child1.bottom = child3.top - 12
|
|
||||||
* child2.bottom = child3.top - 12
|
|
||||||
* child3.height = child1.height
|
|
||||||
* child3.height = child2.height
|
|
||||||
* child3.bottom = super.bottom - 8
|
|
||||||
*
|
|
||||||
* Visual format:
|
|
||||||
*
|
|
||||||
* H:|-8-[view1(==view2)-12-[view2]-8-|
|
|
||||||
* H:|-8-[view3]-8-|
|
|
||||||
* V:|-8-[view1]-12-[view3(==view1)]-8-|
|
|
||||||
* V:|-8-[view2]-12-[view3(==view2)]-8-|
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
build_constraints (VflGrid *self,
|
|
||||||
GtkConstraintLayout *manager)
|
|
||||||
{
|
|
||||||
const char * const vfl[] = {
|
|
||||||
"H:|-[button1(==button2)]-12-[button2]-|",
|
|
||||||
"H:|-[button3]-|",
|
|
||||||
"V:|-[button1]-12-[button3(==button1)]-|",
|
|
||||||
"V:|-[button2]-12-[button3(==button2)]-|",
|
|
||||||
};
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
gtk_constraint_layout_add_constraints_from_description (manager, vfl, G_N_ELEMENTS (vfl),
|
|
||||||
8, 8,
|
|
||||||
&error,
|
|
||||||
"button1", self->button1,
|
|
||||||
"button2", self->button2,
|
|
||||||
"button3", self->button3,
|
|
||||||
NULL);
|
|
||||||
if (error != NULL)
|
|
||||||
{
|
|
||||||
g_printerr ("VFL parsing error:\n%s", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vfl_grid_init (VflGrid *self)
|
|
||||||
{
|
|
||||||
GtkWidget *widget = GTK_WIDGET (self);
|
|
||||||
|
|
||||||
self->button1 = gtk_button_new_with_label ("Child 1");
|
|
||||||
gtk_widget_set_parent (self->button1, widget);
|
|
||||||
gtk_widget_set_name (self->button1, "button1");
|
|
||||||
|
|
||||||
self->button2 = gtk_button_new_with_label ("Child 2");
|
|
||||||
gtk_widget_set_parent (self->button2, widget);
|
|
||||||
gtk_widget_set_name (self->button2, "button2");
|
|
||||||
|
|
||||||
self->button3 = gtk_button_new_with_label ("Child 3");
|
|
||||||
gtk_widget_set_parent (self->button3, widget);
|
|
||||||
gtk_widget_set_name (self->button3, "button3");
|
|
||||||
|
|
||||||
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
|
||||||
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget *
|
|
||||||
do_constraints3 (GtkWidget *do_widget)
|
|
||||||
{
|
|
||||||
static GtkWidget *window;
|
|
||||||
|
|
||||||
if (!window)
|
|
||||||
{
|
|
||||||
GtkWidget *header, *box, *grid, *button;
|
|
||||||
|
|
||||||
window = gtk_window_new ();
|
|
||||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
|
|
||||||
|
|
||||||
header = gtk_header_bar_new ();
|
|
||||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
|
||||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
|
||||||
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
|
||||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
|
||||||
|
|
||||||
grid = g_object_new (vfl_grid_get_type (), NULL);
|
|
||||||
gtk_widget_set_hexpand (grid, TRUE);
|
|
||||||
gtk_widget_set_vexpand (grid, TRUE);
|
|
||||||
gtk_box_append (GTK_BOX (box), grid);
|
|
||||||
|
|
||||||
button = gtk_button_new_with_label ("Close");
|
|
||||||
gtk_box_append (GTK_BOX (box), button);
|
|
||||||
gtk_widget_set_hexpand (grid, TRUE);
|
|
||||||
g_signal_connect_swapped (button, "clicked",
|
|
||||||
G_CALLBACK (gtk_window_destroy), window);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
|
||||||
gtk_widget_show (window);
|
|
||||||
else
|
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
|
||||||
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
@@ -9,13 +9,9 @@
|
|||||||
static void
|
static void
|
||||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||||
{
|
{
|
||||||
GtkWidget *child;
|
|
||||||
|
|
||||||
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||||
for (child = gtk_widget_get_first_child (widget);
|
if (GTK_IS_CONTAINER (widget))
|
||||||
child != NULL;
|
gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback) apply_css, provider);
|
||||||
child = gtk_widget_get_next_sibling (child))
|
|
||||||
apply_css (child, provider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
@@ -28,34 +24,35 @@ do_css_accordion (GtkWidget *do_widget)
|
|||||||
GtkWidget *container, *child;
|
GtkWidget *container, *child;
|
||||||
GtkStyleProvider *provider;
|
GtkStyleProvider *provider;
|
||||||
|
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "CSS Accordion");
|
gtk_window_set_title (GTK_WINDOW (window), "CSS Accordion");
|
||||||
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), 600, 300);
|
gtk_window_set_default_size (GTK_WINDOW (window), 600, 300);
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
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_window_set_child (GTK_WINDOW (window), container);
|
gtk_container_add (GTK_CONTAINER (window), container);
|
||||||
|
|
||||||
child = gtk_button_new_with_label ("This");
|
child = gtk_button_new_with_label ("This");
|
||||||
gtk_box_append (GTK_BOX (container), child);
|
gtk_container_add (GTK_CONTAINER (container), child);
|
||||||
|
|
||||||
child = gtk_button_new_with_label ("Is");
|
child = gtk_button_new_with_label ("Is");
|
||||||
gtk_box_append (GTK_BOX (container), child);
|
gtk_container_add (GTK_CONTAINER (container), child);
|
||||||
|
|
||||||
child = gtk_button_new_with_label ("A");
|
child = gtk_button_new_with_label ("A");
|
||||||
gtk_box_append (GTK_BOX (container), child);
|
gtk_container_add (GTK_CONTAINER (container), child);
|
||||||
|
|
||||||
child = gtk_button_new_with_label ("CSS");
|
child = gtk_button_new_with_label ("CSS");
|
||||||
gtk_box_append (GTK_BOX (container), child);
|
gtk_container_add (GTK_CONTAINER (container), child);
|
||||||
|
|
||||||
child = gtk_button_new_with_label ("Accordion");
|
child = gtk_button_new_with_label ("Accordion");
|
||||||
gtk_box_append (GTK_BOX (container), child);
|
gtk_container_add (GTK_CONTAINER (container), child);
|
||||||
|
|
||||||
child = gtk_button_new_with_label (":-)");
|
child = gtk_button_new_with_label (":-)");
|
||||||
gtk_box_append (GTK_BOX (container), child);
|
gtk_container_add (GTK_CONTAINER (container), child);
|
||||||
|
|
||||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||||
gtk_css_provider_load_from_resource (GTK_CSS_PROVIDER (provider), "/css_accordion/css_accordion.css");
|
gtk_css_provider_load_from_resource (GTK_CSS_PROVIDER (provider), "/css_accordion/css_accordion.css");
|
||||||
@@ -66,7 +63,7 @@ do_css_accordion (GtkWidget *do_widget)
|
|||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,22 +13,19 @@ show_parsing_error (GtkCssProvider *provider,
|
|||||||
const GError *error,
|
const GError *error,
|
||||||
GtkTextBuffer *buffer)
|
GtkTextBuffer *buffer)
|
||||||
{
|
{
|
||||||
const GtkCssLocation *start_location, *end_location;
|
|
||||||
GtkTextIter start, end;
|
GtkTextIter start, end;
|
||||||
const char *tag_name;
|
const char *tag_name;
|
||||||
|
|
||||||
start_location = gtk_css_section_get_start_location (section);
|
|
||||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||||
&start,
|
&start,
|
||||||
start_location->lines,
|
gtk_css_section_get_start_line (section),
|
||||||
start_location->line_bytes);
|
gtk_css_section_get_start_position (section));
|
||||||
end_location = gtk_css_section_get_end_location (section);
|
|
||||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||||
&end,
|
&end,
|
||||||
end_location->lines,
|
gtk_css_section_get_end_line (section),
|
||||||
end_location->line_bytes);
|
gtk_css_section_get_end_position (section));
|
||||||
|
|
||||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||||
tag_name = "warning";
|
tag_name = "warning";
|
||||||
else
|
else
|
||||||
tag_name = "error";
|
tag_name = "error";
|
||||||
@@ -55,13 +52,9 @@ css_text_changed (GtkTextBuffer *buffer,
|
|||||||
static void
|
static void
|
||||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||||
{
|
{
|
||||||
GtkWidget *child;
|
|
||||||
|
|
||||||
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||||
for (child = gtk_widget_get_first_child (widget);
|
if (GTK_IS_CONTAINER (widget))
|
||||||
child != NULL;
|
gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback) apply_css, provider);
|
||||||
child = gtk_widget_get_next_sibling (child))
|
|
||||||
apply_css (child, provider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
@@ -76,11 +69,12 @@ do_css_basics (GtkWidget *do_widget)
|
|||||||
GtkTextBuffer *text;
|
GtkTextBuffer *text;
|
||||||
GBytes *bytes;
|
GBytes *bytes;
|
||||||
|
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
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);
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
text = gtk_text_buffer_new (NULL);
|
text = gtk_text_buffer_new (NULL);
|
||||||
gtk_text_buffer_create_tag (text,
|
gtk_text_buffer_create_tag (text,
|
||||||
@@ -94,10 +88,10 @@ do_css_basics (GtkWidget *do_widget)
|
|||||||
|
|
||||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||||
|
|
||||||
container = gtk_scrolled_window_new ();
|
container = gtk_scrolled_window_new (NULL, NULL);
|
||||||
gtk_window_set_child (GTK_WINDOW (window), container);
|
gtk_container_add (GTK_CONTAINER (window), container);
|
||||||
child = gtk_text_view_new_with_buffer (text);
|
child = gtk_text_view_new_with_buffer (text);
|
||||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (container), child);
|
gtk_container_add (GTK_CONTAINER (container), child);
|
||||||
g_signal_connect (text, "changed",
|
g_signal_connect (text, "changed",
|
||||||
G_CALLBACK (css_text_changed), provider);
|
G_CALLBACK (css_text_changed), provider);
|
||||||
|
|
||||||
@@ -116,7 +110,7 @@ do_css_basics (GtkWidget *do_widget)
|
|||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
* These are the available blend modes.
|
* These are the available blend modes.
|
||||||
*/
|
*/
|
||||||
struct {
|
struct {
|
||||||
const char *name;
|
gchar *name;
|
||||||
const char *id;
|
gchar *id;
|
||||||
} blend_modes[] =
|
} blend_modes[] =
|
||||||
{
|
{
|
||||||
{ "Color", "color" },
|
{ "Color", "color" },
|
||||||
@@ -38,14 +38,14 @@ struct {
|
|||||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||||
static void
|
static void
|
||||||
update_css_for_blend_mode (GtkCssProvider *provider,
|
update_css_for_blend_mode (GtkCssProvider *provider,
|
||||||
const char *blend_mode)
|
const gchar *blend_mode)
|
||||||
{
|
{
|
||||||
GBytes *bytes;
|
GBytes *bytes;
|
||||||
char *css;
|
gchar *css;
|
||||||
|
|
||||||
bytes = g_resources_lookup_data ("/css_blendmodes/css_blendmodes.css", 0, NULL);
|
bytes = g_resources_lookup_data ("/css_blendmodes/css_blendmodes.css", 0, NULL);
|
||||||
|
|
||||||
css = g_strdup_printf ((char *) g_bytes_get_data (bytes, NULL),
|
css = g_strdup_printf ((gchar*) g_bytes_get_data (bytes, NULL),
|
||||||
blend_mode,
|
blend_mode,
|
||||||
blend_mode,
|
blend_mode,
|
||||||
blend_mode);
|
blend_mode);
|
||||||
@@ -62,7 +62,7 @@ row_activated (GtkListBox *listbox,
|
|||||||
GtkListBoxRow *row,
|
GtkListBoxRow *row,
|
||||||
GtkCssProvider *provider)
|
GtkCssProvider *provider)
|
||||||
{
|
{
|
||||||
const char *blend_mode;
|
const gchar *blend_mode;
|
||||||
|
|
||||||
blend_mode = blend_modes[gtk_list_box_row_get_index (row)].id;
|
blend_mode = blend_modes[gtk_list_box_row_get_index (row)].id;
|
||||||
|
|
||||||
@@ -75,11 +75,11 @@ setup_listbox (GtkBuilder *builder,
|
|||||||
{
|
{
|
||||||
GtkWidget *normal_row;
|
GtkWidget *normal_row;
|
||||||
GtkWidget *listbox;
|
GtkWidget *listbox;
|
||||||
int i;
|
gint i;
|
||||||
|
|
||||||
normal_row = NULL;
|
normal_row = NULL;
|
||||||
listbox = gtk_list_box_new ();
|
listbox = gtk_list_box_new ();
|
||||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (WID ("scrolledwindow")), listbox);
|
gtk_container_add (GTK_CONTAINER (WID ("scrolledwindow")), listbox);
|
||||||
|
|
||||||
g_signal_connect (listbox, "row-activated", G_CALLBACK (row_activated), provider);
|
g_signal_connect (listbox, "row-activated", G_CALLBACK (row_activated), provider);
|
||||||
|
|
||||||
@@ -95,8 +95,9 @@ setup_listbox (GtkBuilder *builder,
|
|||||||
"xalign", 0.0,
|
"xalign", 0.0,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), label);
|
gtk_container_add (GTK_CONTAINER (row), label);
|
||||||
gtk_list_box_insert (GTK_LIST_BOX (listbox), row, -1);
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (listbox), row);
|
||||||
|
|
||||||
/* The first selected row is "normal" */
|
/* The first selected row is "normal" */
|
||||||
if (g_strcmp0 (blend_modes[i].id, "normal") == 0)
|
if (g_strcmp0 (blend_modes[i].id, "normal") == 0)
|
||||||
@@ -124,7 +125,7 @@ do_css_blendmodes (GtkWidget *do_widget)
|
|||||||
|
|
||||||
window = WID ("window");
|
window = WID ("window");
|
||||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
/* Setup the CSS provider for window */
|
/* Setup the CSS provider for window */
|
||||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||||
@@ -134,14 +135,12 @@ do_css_blendmodes (GtkWidget *do_widget)
|
|||||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||||
|
|
||||||
setup_listbox (builder, provider);
|
setup_listbox (builder, provider);
|
||||||
|
|
||||||
g_object_unref (builder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,23 +13,19 @@ show_parsing_error (GtkCssProvider *provider,
|
|||||||
const GError *error,
|
const GError *error,
|
||||||
GtkTextBuffer *buffer)
|
GtkTextBuffer *buffer)
|
||||||
{
|
{
|
||||||
const GtkCssLocation *start_location, *end_location;
|
|
||||||
GtkTextIter start, end;
|
GtkTextIter start, end;
|
||||||
const char *tag_name;
|
const char *tag_name;
|
||||||
|
|
||||||
start_location = gtk_css_section_get_start_location (section);
|
|
||||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||||
&start,
|
&start,
|
||||||
start_location->lines,
|
gtk_css_section_get_start_line (section),
|
||||||
start_location->line_bytes);
|
gtk_css_section_get_start_position (section));
|
||||||
end_location = gtk_css_section_get_end_location (section);
|
|
||||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||||
&end,
|
&end,
|
||||||
end_location->lines,
|
gtk_css_section_get_end_line (section),
|
||||||
end_location->line_bytes);
|
gtk_css_section_get_end_position (section));
|
||||||
|
|
||||||
|
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
|
||||||
tag_name = "warning";
|
tag_name = "warning";
|
||||||
else
|
else
|
||||||
tag_name = "error";
|
tag_name = "error";
|
||||||
@@ -69,13 +65,9 @@ drawing_area_draw (GtkDrawingArea *da,
|
|||||||
static void
|
static void
|
||||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||||
{
|
{
|
||||||
GtkWidget *child;
|
|
||||||
|
|
||||||
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||||
for (child = gtk_widget_get_first_child (widget);
|
if (GTK_IS_CONTAINER (widget))
|
||||||
child != NULL;
|
gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback) apply_css, provider);
|
||||||
child = gtk_widget_get_next_sibling (child))
|
|
||||||
apply_css (child, provider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
@@ -85,40 +77,41 @@ do_css_multiplebgs (GtkWidget *do_widget)
|
|||||||
|
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
GtkWidget *paned, *overlay, *child, *sw;
|
GtkWidget *paned, *container, *child;
|
||||||
GtkStyleProvider *provider;
|
GtkStyleProvider *provider;
|
||||||
GtkTextBuffer *text;
|
GtkTextBuffer *text;
|
||||||
GBytes *bytes;
|
GBytes *bytes;
|
||||||
|
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
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);
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
overlay = gtk_overlay_new ();
|
container = gtk_overlay_new ();
|
||||||
gtk_window_set_child (GTK_WINDOW (window), overlay);
|
gtk_container_add (GTK_CONTAINER (window), container);
|
||||||
|
|
||||||
child = gtk_drawing_area_new ();
|
child = gtk_drawing_area_new ();
|
||||||
gtk_widget_set_name (child, "canvas");
|
gtk_widget_set_name (child, "canvas");
|
||||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (child),
|
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (child),
|
||||||
drawing_area_draw,
|
drawing_area_draw,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
gtk_overlay_set_child (GTK_OVERLAY (overlay), child);
|
gtk_container_add (GTK_CONTAINER (container), child);
|
||||||
|
|
||||||
child = gtk_button_new ();
|
child = gtk_button_new ();
|
||||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), child);
|
gtk_overlay_add_overlay (GTK_OVERLAY (container), child);
|
||||||
gtk_widget_set_name (child, "bricks-button");
|
gtk_widget_set_name (child, "bricks-button");
|
||||||
gtk_widget_set_halign (child, GTK_ALIGN_CENTER);
|
gtk_widget_set_halign (child, GTK_ALIGN_CENTER);
|
||||||
gtk_widget_set_valign (child, GTK_ALIGN_CENTER);
|
gtk_widget_set_valign (child, GTK_ALIGN_CENTER);
|
||||||
gtk_widget_set_size_request (child, 250, 84);
|
gtk_widget_set_size_request (child, 250, 84);
|
||||||
|
|
||||||
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
||||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), paned);
|
gtk_overlay_add_overlay (GTK_OVERLAY (container), paned);
|
||||||
|
|
||||||
/* Need a filler so we get a handle */
|
/* Need a filler so we get a handle */
|
||||||
child = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
child = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||||
gtk_paned_set_start_child (GTK_PANED (paned), child);
|
gtk_container_add (GTK_CONTAINER (paned), child);
|
||||||
|
|
||||||
text = gtk_text_buffer_new (NULL);
|
text = gtk_text_buffer_new (NULL);
|
||||||
gtk_text_buffer_create_tag (text,
|
gtk_text_buffer_create_tag (text,
|
||||||
@@ -132,10 +125,10 @@ do_css_multiplebgs (GtkWidget *do_widget)
|
|||||||
|
|
||||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||||
|
|
||||||
sw = gtk_scrolled_window_new ();
|
container = gtk_scrolled_window_new (NULL, NULL);
|
||||||
gtk_paned_set_end_child (GTK_PANED (paned), sw);
|
gtk_container_add (GTK_CONTAINER (paned), container);
|
||||||
child = gtk_text_view_new_with_buffer (text);
|
child = gtk_text_view_new_with_buffer (text);
|
||||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), child);
|
gtk_container_add (GTK_CONTAINER (container), child);
|
||||||
g_signal_connect (text,
|
g_signal_connect (text,
|
||||||
"changed",
|
"changed",
|
||||||
G_CALLBACK (css_text_changed),
|
G_CALLBACK (css_text_changed),
|
||||||
@@ -156,7 +149,7 @@ do_css_multiplebgs (GtkWidget *do_widget)
|
|||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,23 +12,19 @@ show_parsing_error (GtkCssProvider *provider,
|
|||||||
const GError *error,
|
const GError *error,
|
||||||
GtkTextBuffer *buffer)
|
GtkTextBuffer *buffer)
|
||||||
{
|
{
|
||||||
const GtkCssLocation *start_location, *end_location;
|
|
||||||
GtkTextIter start, end;
|
GtkTextIter start, end;
|
||||||
const char *tag_name;
|
const char *tag_name;
|
||||||
|
|
||||||
start_location = gtk_css_section_get_start_location (section);
|
|
||||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||||
&start,
|
&start,
|
||||||
start_location->lines,
|
gtk_css_section_get_start_line (section),
|
||||||
start_location->line_bytes);
|
gtk_css_section_get_start_position (section));
|
||||||
end_location = gtk_css_section_get_end_location (section);
|
|
||||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||||
&end,
|
&end,
|
||||||
end_location->lines,
|
gtk_css_section_get_end_line (section),
|
||||||
end_location->line_bytes);
|
gtk_css_section_get_end_position (section));
|
||||||
|
|
||||||
|
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
|
||||||
tag_name = "warning";
|
tag_name = "warning";
|
||||||
else
|
else
|
||||||
tag_name = "error";
|
tag_name = "error";
|
||||||
@@ -55,13 +51,9 @@ css_text_changed (GtkTextBuffer *buffer,
|
|||||||
static void
|
static void
|
||||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||||
{
|
{
|
||||||
GtkWidget *child;
|
|
||||||
|
|
||||||
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||||
for (child = gtk_widget_get_first_child (widget);
|
if (GTK_IS_CONTAINER (widget))
|
||||||
child != NULL;
|
gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback) apply_css, provider);
|
||||||
child = gtk_widget_get_next_sibling (child))
|
|
||||||
apply_css (child, provider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
@@ -76,18 +68,19 @@ do_css_pixbufs (GtkWidget *do_widget)
|
|||||||
GtkTextBuffer *text;
|
GtkTextBuffer *text;
|
||||||
GBytes *bytes;
|
GBytes *bytes;
|
||||||
|
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
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);
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
||||||
gtk_window_set_child (GTK_WINDOW (window), paned);
|
gtk_container_add (GTK_CONTAINER (window), paned);
|
||||||
|
|
||||||
/* Need a filler so we get a handle */
|
/* Need a filler so we get a handle */
|
||||||
child = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
child = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||||
gtk_paned_set_start_child (GTK_PANED (paned), child);
|
gtk_container_add (GTK_CONTAINER (paned), child);
|
||||||
|
|
||||||
text = gtk_text_buffer_new (NULL);
|
text = gtk_text_buffer_new (NULL);
|
||||||
gtk_text_buffer_create_tag (text,
|
gtk_text_buffer_create_tag (text,
|
||||||
@@ -101,10 +94,10 @@ do_css_pixbufs (GtkWidget *do_widget)
|
|||||||
|
|
||||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||||
|
|
||||||
container = gtk_scrolled_window_new ();
|
container = gtk_scrolled_window_new (NULL, NULL);
|
||||||
gtk_paned_set_end_child (GTK_PANED (paned), container);
|
gtk_container_add (GTK_CONTAINER (paned), container);
|
||||||
child = gtk_text_view_new_with_buffer (text);
|
child = gtk_text_view_new_with_buffer (text);
|
||||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (container), child);
|
gtk_container_add (GTK_CONTAINER (container), child);
|
||||||
g_signal_connect (text, "changed",
|
g_signal_connect (text, "changed",
|
||||||
G_CALLBACK (css_text_changed), provider);
|
G_CALLBACK (css_text_changed), provider);
|
||||||
|
|
||||||
@@ -123,7 +116,7 @@ do_css_pixbufs (GtkWidget *do_widget)
|
|||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,22 +11,19 @@ show_parsing_error (GtkCssProvider *provider,
|
|||||||
const GError *error,
|
const GError *error,
|
||||||
GtkTextBuffer *buffer)
|
GtkTextBuffer *buffer)
|
||||||
{
|
{
|
||||||
const GtkCssLocation *start_location, *end_location;
|
|
||||||
GtkTextIter start, end;
|
GtkTextIter start, end;
|
||||||
const char *tag_name;
|
const char *tag_name;
|
||||||
|
|
||||||
start_location = gtk_css_section_get_start_location (section);
|
|
||||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||||
&start,
|
&start,
|
||||||
start_location->lines,
|
gtk_css_section_get_start_line (section),
|
||||||
start_location->line_bytes);
|
gtk_css_section_get_start_position (section));
|
||||||
end_location = gtk_css_section_get_end_location (section);
|
|
||||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||||
&end,
|
&end,
|
||||||
end_location->lines,
|
gtk_css_section_get_end_line (section),
|
||||||
end_location->line_bytes);
|
gtk_css_section_get_end_position (section));
|
||||||
|
|
||||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||||
tag_name = "warning";
|
tag_name = "warning";
|
||||||
else
|
else
|
||||||
tag_name = "error";
|
tag_name = "error";
|
||||||
@@ -53,32 +50,31 @@ css_text_changed (GtkTextBuffer *buffer,
|
|||||||
static void
|
static void
|
||||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||||
{
|
{
|
||||||
GtkWidget *child;
|
|
||||||
|
|
||||||
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||||
for (child = gtk_widget_get_first_child (widget);
|
if (GTK_IS_CONTAINER (widget))
|
||||||
child != NULL;
|
gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback) apply_css, provider);
|
||||||
child = gtk_widget_get_next_sibling (child))
|
|
||||||
apply_css (child, provider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkWidget *
|
GtkWidget *
|
||||||
create_toolbar (void)
|
create_toolbar (void)
|
||||||
{
|
{
|
||||||
GtkWidget *toolbar;
|
GtkWidget *toolbar;
|
||||||
GtkWidget *item;
|
GtkToolItem *item;
|
||||||
|
|
||||||
toolbar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
toolbar = gtk_toolbar_new ();
|
||||||
gtk_widget_set_valign (toolbar, GTK_ALIGN_CENTER);
|
gtk_widget_set_valign (toolbar, GTK_ALIGN_CENTER);
|
||||||
|
|
||||||
item = gtk_button_new_from_icon_name ("go-next");
|
item = gtk_tool_button_new (NULL, NULL);
|
||||||
gtk_box_append (GTK_BOX (toolbar), item);
|
gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (item), "go-next");
|
||||||
|
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
|
||||||
|
|
||||||
item = gtk_button_new_from_icon_name ("go-previous");
|
item = gtk_tool_button_new (NULL, NULL);
|
||||||
gtk_box_append (GTK_BOX (toolbar), item);
|
gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (item), "go-previous");
|
||||||
|
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
|
||||||
|
|
||||||
item = gtk_button_new_with_label ("Hello World");
|
item = gtk_tool_button_new (NULL, "Hello World");
|
||||||
gtk_box_append (GTK_BOX (toolbar), item);
|
gtk_tool_item_set_is_important (item, TRUE);
|
||||||
|
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
|
||||||
|
|
||||||
return toolbar;
|
return toolbar;
|
||||||
}
|
}
|
||||||
@@ -95,17 +91,18 @@ do_css_shadows (GtkWidget *do_widget)
|
|||||||
GtkTextBuffer *text;
|
GtkTextBuffer *text;
|
||||||
GBytes *bytes;
|
GBytes *bytes;
|
||||||
|
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
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);
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
||||||
gtk_window_set_child (GTK_WINDOW (window), paned);
|
gtk_container_add (GTK_CONTAINER (window), paned);
|
||||||
|
|
||||||
child = create_toolbar ();
|
child = create_toolbar ();
|
||||||
gtk_paned_set_start_child (GTK_PANED (paned), child);
|
gtk_container_add (GTK_CONTAINER (paned), child);
|
||||||
|
|
||||||
text = gtk_text_buffer_new (NULL);
|
text = gtk_text_buffer_new (NULL);
|
||||||
gtk_text_buffer_create_tag (text,
|
gtk_text_buffer_create_tag (text,
|
||||||
@@ -119,10 +116,10 @@ do_css_shadows (GtkWidget *do_widget)
|
|||||||
|
|
||||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||||
|
|
||||||
container = gtk_scrolled_window_new ();
|
container = gtk_scrolled_window_new (NULL, NULL);
|
||||||
gtk_paned_set_end_child (GTK_PANED (paned), container);
|
gtk_container_add (GTK_CONTAINER (paned), container);
|
||||||
child = gtk_text_view_new_with_buffer (text);
|
child = gtk_text_view_new_with_buffer (text);
|
||||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (container), child);
|
gtk_container_add (GTK_CONTAINER (container), child);
|
||||||
g_signal_connect (text, "changed",
|
g_signal_connect (text, "changed",
|
||||||
G_CALLBACK (css_text_changed), provider);
|
G_CALLBACK (css_text_changed), provider);
|
||||||
|
|
||||||
@@ -141,7 +138,7 @@ do_css_shadows (GtkWidget *do_widget)
|
|||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
/* Cursors
|
/* Cursors
|
||||||
*
|
*
|
||||||
* Demonstrates a useful set of available cursors. The cursors shown here are the
|
* Demonstrates a useful set of available cursors. The cursors shown here are the ones
|
||||||
* ones defined by CSS, which we assume to be available. The example shows creating
|
* defined by CSS, which we assume to be available.
|
||||||
* cursors by name or from an image, with or without a fallback.
|
*
|
||||||
|
* The example shows creating cursors by name or from an image, with or without a fallback.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
@@ -23,19 +24,20 @@ do_cursors (GtkWidget *do_widget)
|
|||||||
GtkBuilder *builder;
|
GtkBuilder *builder;
|
||||||
|
|
||||||
builder = gtk_builder_new_from_resource ("/cursors/cursors.ui");
|
builder = gtk_builder_new_from_resource ("/cursors/cursors.ui");
|
||||||
|
gtk_builder_connect_signals (builder, NULL);
|
||||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||||
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));
|
||||||
g_signal_connect (window, "destroy",
|
g_signal_connect (window, "destroy",
|
||||||
G_CALLBACK (on_destroy), NULL);
|
G_CALLBACK (on_destroy), NULL);
|
||||||
g_object_unref (builder);
|
g_object_set_data_full (G_OBJECT (window), "builder", builder, g_object_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_widget_destroy (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<interface>
|
<interface>
|
||||||
|
<!-- interface-requires gtk+ 3.94 -->
|
||||||
<object class="GdkCursor" id="default_cursor">
|
<object class="GdkCursor" id="default_cursor">
|
||||||
<property name="name">default</property>
|
<property name="name">default</property>
|
||||||
</object>
|
</object>
|
||||||
@@ -656,10 +657,7 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<property name="margin-start">60</property>
|
<property name="margin">60</property>
|
||||||
<property name="margin-end">60</property>
|
|
||||||
<property name="margin-top">60</property>
|
|
||||||
<property name="margin-bottom">60</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<property name="halign">center</property>
|
<property name="halign">center</property>
|
||||||
<child>
|
<child>
|
||||||
@@ -675,10 +673,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -735,10 +730,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -795,10 +787,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -868,10 +857,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -928,10 +914,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -988,10 +971,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1048,10 +1028,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1108,10 +1085,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1181,10 +1155,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1241,10 +1212,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1301,10 +1269,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1361,10 +1326,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1434,10 +1396,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1494,10 +1453,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1554,10 +1510,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1614,10 +1567,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1674,10 +1624,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1734,10 +1681,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1794,10 +1738,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1867,10 +1808,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1927,10 +1865,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -1987,10 +1922,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -2047,10 +1979,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -2107,10 +2036,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -2167,10 +2093,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -2227,10 +2150,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -2287,10 +2207,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -2347,10 +2264,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -2407,10 +2321,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -2467,10 +2378,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -2527,10 +2435,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -2587,10 +2492,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -2647,10 +2549,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -2707,10 +2606,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -2780,10 +2676,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
@@ -2840,10 +2733,7 @@
|
|||||||
<property name="activatable">0</property>
|
<property name="activatable">0</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="margin-start">10</property>
|
<property name="margin">10</property>
|
||||||
<property name="margin-end">10</property>
|
|
||||||
<property name="margin-top">10</property>
|
|
||||||
<property name="margin-bottom">10</property>
|
|
||||||
<property name="spacing">10</property>
|
<property name="spacing">10</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImage">
|
<object class="GtkImage">
|
||||||
|
|||||||
BIN
demos/gtk-demo/data/16x16/gtk4-demo-symbolic.symbolic.png
Normal file
|
After Width: | Height: | Size: 324 B |
BIN
demos/gtk-demo/data/16x16/gtk4-demo.png
Normal file
|
After Width: | Height: | Size: 874 B |
BIN
demos/gtk-demo/data/22x22/gtk4-demo-symbolic.symbolic.png
Normal file
|
After Width: | Height: | Size: 437 B |
BIN
demos/gtk-demo/data/22x22/gtk4-demo.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
demos/gtk-demo/data/24x24/gtk4-demo-symbolic.symbolic.png
Normal file
|
After Width: | Height: | Size: 465 B |
BIN
demos/gtk-demo/data/24x24/gtk4-demo.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
demos/gtk-demo/data/256x256/gtk4-demo-symbolic.symbolic.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
demos/gtk-demo/data/256x256/gtk4-demo.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
demos/gtk-demo/data/32x32/gtk4-demo-symbolic.symbolic.png
Normal file
|
After Width: | Height: | Size: 581 B |
BIN
demos/gtk-demo/data/32x32/gtk4-demo.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
demos/gtk-demo/data/48x48/gtk4-demo-symbolic.symbolic.png
Normal file
|
After Width: | Height: | Size: 854 B |
BIN
demos/gtk-demo/data/48x48/gtk4-demo.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
demos/gtk-demo/data/512x512/gtk4-demo-symbolic.symbolic.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
demos/gtk-demo/data/512x512/gtk4-demo.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128" version="1.0"><defs><linearGradient id="f"><stop offset="0" stop-color="#ff7800"/><stop offset="1" stop-color="#ed333b"/></linearGradient><linearGradient id="e"><stop offset="0" stop-color="#f5c211"/><stop offset="1" stop-color="#33d17a" stop-opacity=".899"/></linearGradient><linearGradient id="d"><stop offset="0" stop-color="#c0bfbc"/><stop offset=".036" stop-color="#fafaf9"/><stop offset=".088" stop-color="#c0bfbc"/><stop offset=".399" stop-color="#d5d5d3"/><stop offset=".491" stop-color="#eaeae9"/><stop offset=".569" stop-color="#a7a5a1"/><stop offset=".966" stop-color="#a9a7a3"/><stop offset="1" stop-color="#fff"/></linearGradient><linearGradient id="a"><stop offset="0" stop-color="#d5d3cf"/><stop offset="1" stop-color="#f6f5f4"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#d5d3cf"/><stop offset="1" stop-color="#949390"/></linearGradient><linearGradient id="c"><stop offset="0" stop-color="#9a9996"/><stop offset="1" stop-color="#77767b"/></linearGradient><linearGradient xlink:href="#d" id="g" x1="-142.049" y1="236.001" x2="-9.951" y2="236.001" gradientUnits="userSpaceOnUse"/><radialGradient xlink:href="#e" id="h" cx="90.974" cy="263.479" fx="90.974" fy="263.479" r="22.703" gradientTransform="matrix(1.90297 -.05506 .0501 1.73133 -89.25 -176.863)" gradientUnits="userSpaceOnUse"/><radialGradient xlink:href="#f" id="i" cx="61.718" cy="270.719" fx="61.718" fy="270.719" r="22.703" gradientTransform="matrix(2.49049 0 0 2.92132 -91.99 -503.52)" gradientUnits="userSpaceOnUse"/></defs><path transform="translate(123.265 -118.118) scale(.7798)" d="M-75.74 161.438a10.997 10.997 0 0 0-5.758 1.468l-55.053 31.785a10.997 10.997 0 0 0-5.498 9.524v63.57a10.997 10.997 0 0 0 5.498 9.524l55.053 31.785a10.997 10.997 0 0 0 10.996 0l55.053-31.785a10.997 10.997 0 0 0 5.498-9.524v-63.57a10.997 10.997 0 0 0-5.498-9.524l-55.053-31.785a10.997 10.997 0 0 0-5.238-1.469z" style="marker:none" fill="url(#g)"/><path style="marker:none" d="M64.203 3.77a8.575 8.575 0 0 0-4.49 1.146l-42.93 24.786a8.575 8.575 0 0 0-4.288 7.427V86.7a8.575 8.575 0 0 0 4.287 7.426l42.93 24.786a8.575 8.575 0 0 0 8.575 0l42.93-24.786a8.575 8.575 0 0 0 4.288-7.426V37.129a8.575 8.575 0 0 0-4.287-7.427L68.288 4.916a8.575 8.575 0 0 0-4.085-1.145z" fill="#fff"/><path style="marker:none" d="M109.869 33.297L64 59.779 18.131 33.297 64 6.814z" fill="#98c1f1"/><path style="marker:none" d="M66.263 287.505l45.35-25.884.056-52.762-45.406 26.215z" fill="url(#h)" transform="translate(0 -172)"/><path d="M61.718 287.34l-45.35-25.885-.056-52.761 45.406 26.215z" style="marker:none" fill="url(#i)" transform="translate(0 -172)"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.7 KiB |
2886
demos/gtk-demo/data/source.svg
Normal file
|
After Width: | Height: | Size: 101 KiB |
29
demos/gtk-demo/data/symbolic-source.svg
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:dc='http://purl.org/dc/elements/1.1/' sodipodi:docname='gtk3-demo-symbolic.svg' height='16.000015' id='svg7384' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' xmlns:osb='http://www.openswatchbook.org/uri/2009/osb' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:svg='http://www.w3.org/2000/svg' inkscape:version='0.48.5 r10040' version='1.1' width='16' xmlns='http://www.w3.org/2000/svg'>
|
||||||
|
<metadata id='metadata90'>
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work rdf:about=''>
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
|
||||||
|
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<sodipodi:namedview inkscape:bbox-paths='true' bordercolor='#666666' borderopacity='1' inkscape:current-layer='layer9' inkscape:cx='-12.5126' inkscape:cy='-0.73412416' gridtolerance='10' inkscape:guide-bbox='true' guidetolerance='10' id='namedview88' inkscape:object-nodes='false' inkscape:object-paths='false' objecttolerance='10' pagecolor='#555753' inkscape:pageopacity='1' inkscape:pageshadow='2' showborder='false' showgrid='false' showguides='true' inkscape:snap-bbox='true' inkscape:snap-bbox-midpoints='false' inkscape:snap-global='true' inkscape:snap-grids='true' inkscape:snap-nodes='true' inkscape:snap-others='false' inkscape:snap-to-guides='true' inkscape:window-height='1375' inkscape:window-maximized='1' inkscape:window-width='2560' inkscape:window-x='0' inkscape:window-y='27' inkscape:zoom='5.6568542'>
|
||||||
|
<inkscape:grid empspacing='2' enabled='true' id='grid4866' originx='-182.99998px' originy='-251.99998px' snapvisiblegridlinesonly='true' spacingx='1px' spacingy='1px' type='xygrid' visible='true'/>
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<title id='title9167'>Gnome Symbolic Icon Theme</title>
|
||||||
|
<defs id='defs7386'>
|
||||||
|
<linearGradient id='linearGradient7212' osb:paint='solid'>
|
||||||
|
<stop id='stop7214' offset='0' style='stop-color:#000000;stop-opacity:1;'/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g inkscape:groupmode='layer' id='layer9' inkscape:label='apps' style='display:inline' transform='translate(-424.00018,35)'>
|
||||||
|
|
||||||
|
<rect height='8.0000048' id='rect7866' style='opacity:0.3;color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.39999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new' transform='matrix(0.83205029,0.5547002,0,1,0,0)' width='7.2111053' x='510.78668' y='-314.33347'/>
|
||||||
|
<rect height='8.0000086' id='rect7868' style='opacity:0.5;color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.39999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new' transform='matrix(-0.86824295,0.49613928,0,1,0,0)' width='8.0622425' x='-505.61908' y='219.8575'/>
|
||||||
|
<path inkscape:connector-curvature='0' d='m 431.53145,-28 -5.875,-3.65625 6.8125,-3.34375 6.03125,3 z' id='path7870' sodipodi:nodetypes='ccccc' style='color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.39999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new'/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.3 KiB |
@@ -1,114 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
sodipodi:docname="org.gtk.Demo4-symbolic.svg"
|
|
||||||
height="16.03125"
|
|
||||||
id="svg7384"
|
|
||||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
|
||||||
version="1.1"
|
|
||||||
width="16">
|
|
||||||
<metadata
|
|
||||||
id="metadata90">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<sodipodi:namedview
|
|
||||||
inkscape:bbox-paths="true"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:current-layer="layer9"
|
|
||||||
inkscape:cx="0.53203442"
|
|
||||||
inkscape:cy="9.1822592"
|
|
||||||
gridtolerance="10"
|
|
||||||
inkscape:guide-bbox="true"
|
|
||||||
guidetolerance="10"
|
|
||||||
id="namedview88"
|
|
||||||
inkscape:object-nodes="false"
|
|
||||||
inkscape:object-paths="false"
|
|
||||||
objecttolerance="10"
|
|
||||||
pagecolor="#555753"
|
|
||||||
inkscape:pageopacity="1"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
showborder="true"
|
|
||||||
showgrid="false"
|
|
||||||
showguides="true"
|
|
||||||
inkscape:snap-bbox="true"
|
|
||||||
inkscape:snap-bbox-midpoints="false"
|
|
||||||
inkscape:snap-global="true"
|
|
||||||
inkscape:snap-grids="true"
|
|
||||||
inkscape:snap-nodes="true"
|
|
||||||
inkscape:snap-others="false"
|
|
||||||
inkscape:snap-to-guides="true"
|
|
||||||
inkscape:window-height="1375"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:window-width="2560"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="27"
|
|
||||||
inkscape:zoom="1">
|
|
||||||
<inkscape:grid
|
|
||||||
empspacing="2"
|
|
||||||
enabled="true"
|
|
||||||
id="grid4866"
|
|
||||||
originx="-203"
|
|
||||||
originy="-251.96875"
|
|
||||||
snapvisiblegridlinesonly="true"
|
|
||||||
spacingx="1"
|
|
||||||
spacingy="1"
|
|
||||||
type="xygrid"
|
|
||||||
visible="true" />
|
|
||||||
</sodipodi:namedview>
|
|
||||||
<title
|
|
||||||
id="title9167">Gnome Symbolic Icon Theme</title>
|
|
||||||
<defs
|
|
||||||
id="defs7386">
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient7212"
|
|
||||||
osb:paint="solid">
|
|
||||||
<stop
|
|
||||||
id="stop7214"
|
|
||||||
offset="0"
|
|
||||||
style="stop-color:#000000;stop-opacity:1;" />
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
<g
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer9"
|
|
||||||
inkscape:label="apps"
|
|
||||||
style="display:inline"
|
|
||||||
transform="translate(-444.0002,35)">
|
|
||||||
<path
|
|
||||||
style="display:inline;opacity:0.3;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
|
||||||
d="m 457.97232,-31.569556 -5.96212,3.44224 -5.96215,-3.44224 v 0 l 5.96215,-3.44226 z"
|
|
||||||
id="path870-6"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="cccccc" />
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="cccccc"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path886-9"
|
|
||||||
d="m 450.98519,-19.648086 -5.99273,-3.42041 -0.007,-6.97219 v 0 l 6.00018,3.4642 z"
|
|
||||||
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new" />
|
|
||||||
<path
|
|
||||||
style="display:inline;opacity:0.60100002;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
|
||||||
d="m 452.98577,-19.648086 5.99273,-3.42041 0.007,-6.97219 v 0 l -6.00018,3.4642 z"
|
|
||||||
id="path931"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
sodipodi:nodetypes="cccccc" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.3 KiB |
@@ -1,10 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<gresources>
|
<gresources>
|
||||||
<gresource prefix="/">
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/ui">
|
<gresource prefix="/ui">
|
||||||
<file preprocess="xml-stripblanks">main.ui</file>
|
<file preprocess="xml-stripblanks">main.ui</file>
|
||||||
<file preprocess="xml-stripblanks">main-listitem.ui</file>
|
<file preprocess="xml-stripblanks">appmenu.ui</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/application_demo">
|
<gresource prefix="/application_demo">
|
||||||
<file>application.c</file>
|
<file>application.c</file>
|
||||||
@@ -14,10 +12,6 @@
|
|||||||
<gresource prefix="/builder">
|
<gresource prefix="/builder">
|
||||||
<file>demo.ui</file>
|
<file>demo.ui</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/clipboard">
|
|
||||||
<file>demoimage.c</file>
|
|
||||||
<file>demoimage.h</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/css_accordion">
|
<gresource prefix="/css_accordion">
|
||||||
<file>css_accordion.css</file>
|
<file>css_accordion.css</file>
|
||||||
<file>reset.css</file>
|
<file>reset.css</file>
|
||||||
@@ -43,9 +37,6 @@
|
|||||||
<gresource prefix="/theming_style_classes">
|
<gresource prefix="/theming_style_classes">
|
||||||
<file>theming.ui</file>
|
<file>theming.ui</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/themes">
|
|
||||||
<file>themes.ui</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/css_pixbufs">
|
<gresource prefix="/css_pixbufs">
|
||||||
<file alias="gtk.css">css_pixbufs.css</file>
|
<file alias="gtk.css">css_pixbufs.css</file>
|
||||||
<file>cssview.css</file>
|
<file>cssview.css</file>
|
||||||
@@ -105,43 +96,15 @@
|
|||||||
<file>zoom_in_cursor.png</file>
|
<file>zoom_in_cursor.png</file>
|
||||||
<file>zoom_out_cursor.png</file>
|
<file>zoom_out_cursor.png</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/dnd">
|
|
||||||
<file>dnd.css</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/fishbowl">
|
<gresource prefix="/fishbowl">
|
||||||
<file>fishbowl.ui</file>
|
<file>fishbowl.ui</file>
|
||||||
<file>gtkfishbowl.c</file>
|
<file>gtkfishbowl.c</file>
|
||||||
<file>gtkfishbowl.h</file>
|
<file>gtkfishbowl.h</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/gears">
|
|
||||||
<file>gtkgears.c</file>
|
|
||||||
<file>gtkgears.h</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/iconscroll">
|
|
||||||
<file>iconscroll.ui</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/iconview">
|
<gresource prefix="/iconview">
|
||||||
<file>gnome-fs-directory.png</file>
|
<file>gnome-fs-directory.png</file>
|
||||||
<file>gnome-fs-regular.png</file>
|
<file>gnome-fs-regular.png</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/listview_filebrowser">
|
|
||||||
<file>listview_filebrowser.ui</file>
|
|
||||||
<file>listview_filebrowser.css</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/listview_minesweeper">
|
|
||||||
<file>listview_minesweeper.ui</file>
|
|
||||||
<file>listview_minesweeper_cell.ui</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/listview_settings">
|
|
||||||
<file>listview_settings.ui</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/listview_weather">
|
|
||||||
<file compressed="true">listview_weather.txt</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/listview_colors">
|
|
||||||
<file compressed="true">color.names.txt</file>
|
|
||||||
<file>listview_colors.css</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/shortcuts">
|
<gresource prefix="/shortcuts">
|
||||||
<file>shortcuts.ui</file>
|
<file>shortcuts.ui</file>
|
||||||
<file>shortcuts-builder.ui</file>
|
<file>shortcuts-builder.ui</file>
|
||||||
@@ -180,11 +143,11 @@
|
|||||||
<file>application_demo.c</file>
|
<file>application_demo.c</file>
|
||||||
<file>assistant.c</file>
|
<file>assistant.c</file>
|
||||||
<file>builder.c</file>
|
<file>builder.c</file>
|
||||||
|
<file>button_box.c</file>
|
||||||
|
<file>changedisplay.c</file>
|
||||||
<file>clipboard.c</file>
|
<file>clipboard.c</file>
|
||||||
|
<file>colorsel.c</file>
|
||||||
<file>combobox.c</file>
|
<file>combobox.c</file>
|
||||||
<file>constraints.c</file>
|
|
||||||
<file>constraints2.c</file>
|
|
||||||
<file>constraints3.c</file>
|
|
||||||
<file>css_accordion.c</file>
|
<file>css_accordion.c</file>
|
||||||
<file>css_basics.c</file>
|
<file>css_basics.c</file>
|
||||||
<file>css_blendmodes.c</file>
|
<file>css_blendmodes.c</file>
|
||||||
@@ -194,41 +157,32 @@
|
|||||||
<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_buffer.c</file>
|
||||||
<file>entry_completion.c</file>
|
<file>entry_completion.c</file>
|
||||||
<file>entry_undo.c</file>
|
<file>event_axes.c</file>
|
||||||
<file>expander.c</file>
|
<file>expander.c</file>
|
||||||
<file>filtermodel.c</file>
|
<file>filtermodel.c</file>
|
||||||
<file>fishbowl.c</file>
|
<file>fishbowl.c</file>
|
||||||
<file>fixed.c</file>
|
|
||||||
<file>flowbox.c</file>
|
<file>flowbox.c</file>
|
||||||
|
<file>foreigndrawing.c</file>
|
||||||
<file>font_features.c</file>
|
<file>font_features.c</file>
|
||||||
<file>fontplane.c</file>
|
<file>fontplane.c</file>
|
||||||
<file>fontrendering.c</file>
|
<file>fontrendering.c</file>
|
||||||
<file>gears.c</file>
|
|
||||||
<file>gestures.c</file>
|
<file>gestures.c</file>
|
||||||
<file>glarea.c</file>
|
<file>glarea.c</file>
|
||||||
<file>headerbar.c</file>
|
<file>headerbar.c</file>
|
||||||
<file>hypertext.c</file>
|
<file>hypertext.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>images.c</file>
|
<file>images.c</file>
|
||||||
<file>infobar.c</file>
|
<file>infobar.c</file>
|
||||||
<file>links.c</file>
|
<file>links.c</file>
|
||||||
<file>listbox.c</file>
|
<file>listbox.c</file>
|
||||||
<file>listview_applauncher.c</file>
|
|
||||||
<file>listview_colors.c</file>
|
|
||||||
<file>listview_clocks.c</file>
|
|
||||||
<file>listview_filebrowser.c</file>
|
|
||||||
<file>listview_minesweeper.c</file>
|
|
||||||
<file>listview_settings.c</file>
|
|
||||||
<file>listview_weather.c</file>
|
|
||||||
<file>listview_words.c</file>
|
|
||||||
<file>list_store.c</file>
|
<file>list_store.c</file>
|
||||||
<file>markup.c</file>
|
<file>markup.c</file>
|
||||||
|
<file>menus.c</file>
|
||||||
<file>modelbutton.c</file>
|
<file>modelbutton.c</file>
|
||||||
<file>overlay.c</file>
|
<file>overlay.c</file>
|
||||||
<file>overlay2.c</file>
|
<file>overlay2.c</file>
|
||||||
@@ -238,10 +192,9 @@
|
|||||||
<file>paintable_animated.c</file>
|
<file>paintable_animated.c</file>
|
||||||
<file>paintable_mediastream.c</file>
|
<file>paintable_mediastream.c</file>
|
||||||
<file>panes.c</file>
|
<file>panes.c</file>
|
||||||
<file>password_entry.c</file>
|
|
||||||
<file>peg_solitaire.c</file>
|
|
||||||
<file>pickers.c</file>
|
<file>pickers.c</file>
|
||||||
<file>pixbufs.c</file>
|
<file>pixbufs.c</file>
|
||||||
|
<file>popover.c</file>
|
||||||
<file>printing.c</file>
|
<file>printing.c</file>
|
||||||
<file>revealer.c</file>
|
<file>revealer.c</file>
|
||||||
<file>rotated_text.c</file>
|
<file>rotated_text.c</file>
|
||||||
@@ -249,7 +202,6 @@
|
|||||||
<file>search_entry.c</file>
|
<file>search_entry.c</file>
|
||||||
<file>search_entry2.c</file>
|
<file>search_entry2.c</file>
|
||||||
<file>shortcuts.c</file>
|
<file>shortcuts.c</file>
|
||||||
<file>shortcut_triggers.c</file>
|
|
||||||
<file>sizegroup.c</file>
|
<file>sizegroup.c</file>
|
||||||
<file>sidebar.c</file>
|
<file>sidebar.c</file>
|
||||||
<file>sliding_puzzle.c</file>
|
<file>sliding_puzzle.c</file>
|
||||||
@@ -257,12 +209,9 @@
|
|||||||
<file>spinbutton.c</file>
|
<file>spinbutton.c</file>
|
||||||
<file>spinner.c</file>
|
<file>spinner.c</file>
|
||||||
<file>tabs.c</file>
|
<file>tabs.c</file>
|
||||||
<file>tagged_entry.c</file>
|
|
||||||
<file>textundo.c</file>
|
|
||||||
<file>textview.c</file>
|
<file>textview.c</file>
|
||||||
<file>textscroll.c</file>
|
<file>textscroll.c</file>
|
||||||
<file>theming_style_classes.c</file>
|
<file>theming_style_classes.c</file>
|
||||||
<file>themes.c</file>
|
|
||||||
<file>transparent.c</file>
|
<file>transparent.c</file>
|
||||||
<file>tree_store.c</file>
|
<file>tree_store.c</file>
|
||||||
<file>textmask.c</file>
|
<file>textmask.c</file>
|
||||||
@@ -271,14 +220,14 @@
|
|||||||
<gresource prefix="/textview">
|
<gresource prefix="/textview">
|
||||||
<file>floppybuddy.gif</file>
|
<file>floppybuddy.gif</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/tagged_entry">
|
|
||||||
<file>tagstyle.css</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/listbox">
|
<gresource prefix="/listbox">
|
||||||
<file>listbox.ui</file>
|
<file>listbox.ui</file>
|
||||||
<file>messages.txt</file>
|
<file>messages.txt</file>
|
||||||
<file>apple-red.png</file>
|
<file>apple-red.png</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
|
<gresource prefix="/popover">
|
||||||
|
<file>popover.ui</file>
|
||||||
|
</gresource>
|
||||||
<gresource prefix="/glarea">
|
<gresource prefix="/glarea">
|
||||||
<file>glarea-gl.fs.glsl</file>
|
<file>glarea-gl.fs.glsl</file>
|
||||||
<file>glarea-gl.vs.glsl</file>
|
<file>glarea-gl.vs.glsl</file>
|
||||||
@@ -301,8 +250,6 @@
|
|||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/transparent">
|
<gresource prefix="/transparent">
|
||||||
<file>portland-rose.jpg</file>
|
<file>portland-rose.jpg</file>
|
||||||
<file>bluroverlay.h</file>
|
|
||||||
<file>bluroverlay.c</file>
|
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/markup">
|
<gresource prefix="/markup">
|
||||||
<file>markup.txt</file>
|
<file>markup.txt</file>
|
||||||
@@ -313,36 +260,10 @@
|
|||||||
<gresource prefix="/modelbutton">
|
<gresource prefix="/modelbutton">
|
||||||
<file>modelbutton.ui</file>
|
<file>modelbutton.ui</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/tagged_entry">
|
<gresource prefix="/dnd">
|
||||||
<file>demotaggedentry.c</file>
|
<file>dnd.css</file>
|
||||||
<file>demotaggedentry.h</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/fixed">
|
|
||||||
<file>fixed.css</file>
|
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/fontrendering">
|
<gresource prefix="/fontrendering">
|
||||||
<file>fontrendering.ui</file>
|
<file>fontrendering.ui</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
<gresource prefix="/org/gtk/Demo4">
|
|
||||||
<file>icons/16x16/actions/application-exit.png</file>
|
|
||||||
<file>icons/16x16/actions/document-new.png</file>
|
|
||||||
<file>icons/16x16/actions/document-open.png</file>
|
|
||||||
<file>icons/16x16/actions/document-save.png</file>
|
|
||||||
<file>icons/16x16/actions/edit-copy.png</file>
|
|
||||||
<file>icons/16x16/actions/edit-cut.png</file>
|
|
||||||
<file>icons/16x16/actions/edit-paste.png</file>
|
|
||||||
<file>icons/16x16/actions/process-stop.png</file>
|
|
||||||
<file>icons/16x16/actions/go-home.png</file>
|
|
||||||
<file>icons/16x16/actions/go-up.png</file>
|
|
||||||
<file>icons/16x16/actions/mail-send-receive-symbolic.symbolic.png</file>
|
|
||||||
<file>icons/16x16/actions/view-fullscreen-symbolic.symbolic.png</file>
|
|
||||||
<file>icons/16x16/actions/document-edit-symbolic.symbolic.png</file>
|
|
||||||
<file>icons/16x16/emotes/face-cool.png</file>
|
|
||||||
<file>icons/16x16/emotes/face-laugh-symbolic.symbolic.png</file>
|
|
||||||
<file>icons/16x16/status/battery-caution-charging-symbolic.symbolic.png</file>
|
|
||||||
<file>icons/16x16/categories/applications-other.png</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/org/gtk/Demo4/gtk">
|
|
||||||
<file preprocess="xml-stripblanks">help-overlay.ui</file>
|
|
||||||
</gresource>
|
|
||||||
</gresources>
|
</gresources>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!--*- mode: xml -*-->
|
||||||
<interface>
|
<interface>
|
||||||
<object class="GtkListStore" id="liststore1">
|
<object class="GtkListStore" id="liststore1">
|
||||||
<columns>
|
<columns>
|
||||||
@@ -22,79 +23,9 @@
|
|||||||
</row>
|
</row>
|
||||||
</data>
|
</data>
|
||||||
</object>
|
</object>
|
||||||
<menu id="menubar">
|
|
||||||
<submenu>
|
|
||||||
<attribute name="label" translatable="yes">_File</attribute>
|
|
||||||
<section>
|
|
||||||
<item>
|
|
||||||
<attribute name="label" translatable="yes">_New</attribute>
|
|
||||||
<attribute name="action">win.new</attribute>
|
|
||||||
<attribute name="accel"><Control>n</attribute>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<attribute name="label" translatable="yes">_Open</attribute>
|
|
||||||
<attribute name="action">win.open</attribute>
|
|
||||||
<attribute name="accel"><Control>o</attribute>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<attribute name="label" translatable="yes">_Save</attribute>
|
|
||||||
<attribute name="action">win.save</attribute>
|
|
||||||
<attribute name="accel"><Control>s</attribute>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<attribute name="label" translatable="yes">Save _As</attribute>
|
|
||||||
<attribute name="action">win.save-as</attribute>
|
|
||||||
<attribute name="accel"><Control>q</attribute>
|
|
||||||
</item>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<item>
|
|
||||||
<attribute name="label" translatable="yes">_Quit</attribute>
|
|
||||||
<attribute name="action">win.quit</attribute>
|
|
||||||
<attribute name="accel"><Control><Shift>s</attribute>
|
|
||||||
</item>
|
|
||||||
</section>
|
|
||||||
</submenu>
|
|
||||||
<submenu>
|
|
||||||
<attribute name="label" translatable="yes">_Edit</attribute>
|
|
||||||
<section>
|
|
||||||
<item>
|
|
||||||
<attribute name="label" translatable="yes">_Copy</attribute>
|
|
||||||
<attribute name="action">win.copy</attribute>
|
|
||||||
<attribute name="accel"><Control>c</attribute>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<attribute name="label" translatable="yes">_Cut</attribute>
|
|
||||||
<attribute name="action">win.cut</attribute>
|
|
||||||
<attribute name="accel"><Control>x</attribute>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<attribute name="label" translatable="yes">_Paste</attribute>
|
|
||||||
<attribute name="action">win.paste</attribute>
|
|
||||||
<attribute name="accel"><Control>v</attribute>
|
|
||||||
</item>
|
|
||||||
</section>
|
|
||||||
</submenu>
|
|
||||||
<submenu>
|
|
||||||
<attribute name="label" translatable="yes">_Help</attribute>
|
|
||||||
<section>
|
|
||||||
<item>
|
|
||||||
<attribute name="label" translatable="yes">_Help</attribute>
|
|
||||||
<attribute name="action">win.help</attribute>
|
|
||||||
<attribute name="accel">F1</attribute>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<attribute name="label" translatable="yes">_About</attribute>
|
|
||||||
<attribute name="action">win.about</attribute>
|
|
||||||
<attribute name="accel">F7</attribute>
|
|
||||||
</item>
|
|
||||||
</section>
|
|
||||||
</submenu>
|
|
||||||
</menu>
|
|
||||||
<object class="GtkAboutDialog" id="aboutdialog1">
|
<object class="GtkAboutDialog" id="aboutdialog1">
|
||||||
<property name="program-name" translatable="yes">Builder demo</property>
|
<property name="program-name" translatable="yes">Builder demo</property>
|
||||||
<property name="logo-icon-name" translatable="yes">gtk3-demo</property>
|
<property name="logo-icon-name" translatable="yes">gtk3-demo</property>
|
||||||
<property name="modal">True</property>
|
|
||||||
<accessibility>
|
<accessibility>
|
||||||
<relation target="window1" type="subwindow-of"/>
|
<relation target="window1" type="subwindow-of"/>
|
||||||
</accessibility>
|
</accessibility>
|
||||||
@@ -107,69 +38,175 @@
|
|||||||
<object class="GtkBox" id="vbox1">
|
<object class="GtkBox" id="vbox1">
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkPopoverMenuBar" id="menubar1">
|
<object class="GtkMenuBar" id="menubar1">
|
||||||
<property name="menu-model">menubar</property>
|
<child internal-child="accessible">
|
||||||
|
<object class="AtkObject" id="a11y-menubar">
|
||||||
|
<property name="AtkObject::accessible-name">The menubar</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="label" translatable="yes">_File</property>
|
||||||
|
<property name="use-underline">1</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu">
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="new_item">
|
||||||
|
<property name="label" translatable="yes">_New</property>
|
||||||
|
<property name="use-underline">1</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="open_item">
|
||||||
|
<property name="label" translatable="yes">_Open</property>
|
||||||
|
<property name="use-underline">1</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="save_item">
|
||||||
|
<property name="label" translatable="yes">_Save</property>
|
||||||
|
<property name="use-underline">1</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="save_as_item">
|
||||||
|
<property name="label" translatable="yes">Save _As</property>
|
||||||
|
<property name="use-underline">1</property>
|
||||||
|
<accelerator key="s" modifiers="primary | shift-mask" signal="activate"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem">
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="quit_item">
|
||||||
|
<property name="label" translatable="yes">_Quit</property>
|
||||||
|
<property name="use-underline">1</property>
|
||||||
|
<property name="action-name">win.quit</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="label" translatable="yes">_Edit</property>
|
||||||
|
<property name="use-underline">1</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu">
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="copy_item">
|
||||||
|
<property name="label" translatable="yes">_Copy</property>
|
||||||
|
<property name="use-underline">1</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="cut_item">
|
||||||
|
<property name="label" translatable="yes">_Cut</property>
|
||||||
|
<property name="use-underline">1</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="paste_item">
|
||||||
|
<property name="label" translatable="yes">_Paste</property>
|
||||||
|
<property name="use-underline">1</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem">
|
||||||
|
<property name="label" translatable="yes">_Help</property>
|
||||||
|
<property name="use-underline">1</property>
|
||||||
|
<child type="submenu">
|
||||||
|
<object class="GtkMenu">
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="help_item">
|
||||||
|
<property name="label" translatable="yes">_Help</property>
|
||||||
|
<property name="use-underline">1</property>
|
||||||
|
<property name="action-name">win.help</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuItem" id="about_item">
|
||||||
|
<property name="label" translatable="yes">_About</property>
|
||||||
|
<property name="use-underline">1</property>
|
||||||
|
<property name="action-name">win.about</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="toolbar1">
|
<object class="GtkToolbar" id="toolbar1">
|
||||||
<child internal-child="accessible">
|
<child internal-child="accessible">
|
||||||
<object class="AtkObject" id="a11y-toolbar">
|
<object class="AtkObject" id="a11y-toolbar">
|
||||||
<property name="AtkObject::accessible-name">The toolbar</property>
|
<property name="AtkObject::accessible-name">The toolbar</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton">
|
<object class="GtkToolButton">
|
||||||
<property name="label" translatable="yes">New</property>
|
<property name="label" translatable="yes">New</property>
|
||||||
<property name="tooltip-text" translatable="yes">Create a new file</property>
|
<property name="tooltip-text" translatable="yes">Create a new file</property>
|
||||||
<property name="icon-name">document-new</property>
|
<property name="icon-name">document-new</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton">
|
<object class="GtkToolButton">
|
||||||
<property name="label" translatable="yes">Open</property>
|
<property name="label" translatable="yes">Open</property>
|
||||||
<property name="tooltip-text" translatable="yes">Open a file</property>
|
<property name="tooltip-text" translatable="yes">Open a file</property>
|
||||||
<property name="icon-name">document-open</property>
|
<property name="icon-name">document-open</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton">
|
<object class="GtkToolButton">
|
||||||
<property name="label" translatable="yes">Save</property>
|
<property name="label" translatable="yes">Save</property>
|
||||||
<property name="tooltip-text" translatable="yes">Save a file</property>
|
<property name="tooltip-text" translatable="yes">Save a file</property>
|
||||||
<property name="icon-name">document-save</property>
|
<property name="icon-name">document-save</property>
|
||||||
|
<property name="is-important">1</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparator"/>
|
<object class="GtkSeparatorToolItem">
|
||||||
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton">
|
<object class="GtkToolButton">
|
||||||
<property name="label" translatable="yes">Copy</property>
|
<property name="label" translatable="yes">Copy</property>
|
||||||
<property name="tooltip-text" translatable="yes">Copy selected object into the clipboard</property>
|
<property name="tooltip-text" translatable="yes">Copy selected object into the clipboard</property>
|
||||||
<property name="icon-name">edit-copy</property>
|
<property name="icon-name">edit-copy</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton">
|
<object class="GtkToolButton">
|
||||||
<property name="label" translatable="yes">Cut</property>
|
<property name="label" translatable="yes">Cut</property>
|
||||||
<property name="tooltip-text" translatable="yes">Cut selected object into the clipboard</property>
|
<property name="tooltip-text" translatable="yes">Cut selected object into the clipboard</property>
|
||||||
<property name="icon-name">edit-cut</property>
|
<property name="icon-name">edit-cut</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton">
|
<object class="GtkToolButton">
|
||||||
<property name="label" translatable="yes">Paste</property>
|
<property name="label" translatable="yes">Paste</property>
|
||||||
<property name="tooltip-text" translatable="yes">Paste object from the clipboard</property>
|
<property name="tooltip-text" translatable="yes">Paste object from the clipboard</property>
|
||||||
<property name="icon-name">edit-paste</property>
|
<property name="icon-name">edit-paste</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||||
<property name="has-frame">1</property>
|
<property name="shadow-type">in</property>
|
||||||
<property name="hexpand">1</property>
|
<property name="expand">1</property>
|
||||||
<property name="vexpand">1</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeView" id="treeview1">
|
<object class="GtkTreeView" id="treeview1">
|
||||||
<property name="model">liststore1</property>
|
<property name="model">liststore1</property>
|
||||||
@@ -218,9 +255,16 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkStatusbar" id="statusbar1"/>
|
<object class="GtkStatusbar" id="statusbar1">
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
|||||||
@@ -1,259 +0,0 @@
|
|||||||
#include "demoimage.h"
|
|
||||||
#include <glib/gi18n.h>
|
|
||||||
|
|
||||||
struct _DemoImage {
|
|
||||||
GtkWidget parent_instance;
|
|
||||||
|
|
||||||
GtkWidget *image;
|
|
||||||
GtkWidget *popover;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PROP_ICON_NAME = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE(DemoImage, demo_image, GTK_TYPE_WIDGET)
|
|
||||||
|
|
||||||
static GdkPaintable *
|
|
||||||
get_image_paintable (GtkImage *image)
|
|
||||||
{
|
|
||||||
const char *icon_name;
|
|
||||||
GtkIconTheme *icon_theme;
|
|
||||||
GtkIconPaintable *icon;
|
|
||||||
|
|
||||||
switch (gtk_image_get_storage_type (image))
|
|
||||||
{
|
|
||||||
case GTK_IMAGE_PAINTABLE:
|
|
||||||
return g_object_ref (gtk_image_get_paintable (image));
|
|
||||||
case GTK_IMAGE_ICON_NAME:
|
|
||||||
icon_name = gtk_image_get_icon_name (image);
|
|
||||||
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image)));
|
|
||||||
icon = gtk_icon_theme_lookup_icon (icon_theme,
|
|
||||||
icon_name,
|
|
||||||
NULL,
|
|
||||||
48, 1,
|
|
||||||
gtk_widget_get_direction (GTK_WIDGET (image)),
|
|
||||||
0);
|
|
||||||
if (icon == NULL)
|
|
||||||
return NULL;
|
|
||||||
return GDK_PAINTABLE (icon);
|
|
||||||
|
|
||||||
case GTK_IMAGE_EMPTY:
|
|
||||||
case GTK_IMAGE_GICON:
|
|
||||||
default:
|
|
||||||
g_warning ("Image storage type %d not handled",
|
|
||||||
gtk_image_get_storage_type (image));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
drag_begin (GtkDragSource *source,
|
|
||||||
GdkDrag *drag,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
|
||||||
DemoImage *demo = DEMO_IMAGE (widget);
|
|
||||||
GdkPaintable *paintable;
|
|
||||||
|
|
||||||
paintable = get_image_paintable (GTK_IMAGE (demo->image));
|
|
||||||
if (paintable)
|
|
||||||
{
|
|
||||||
gtk_drag_icon_set_from_paintable (drag, paintable, -2, -2);
|
|
||||||
g_object_unref (paintable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static GdkContentProvider *
|
|
||||||
prepare_drag (GtkDragSource *source,
|
|
||||||
double x,
|
|
||||||
double y,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
|
||||||
DemoImage *demo = DEMO_IMAGE (widget);
|
|
||||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (demo->image));
|
|
||||||
|
|
||||||
return gdk_content_provider_new_typed (GDK_TYPE_PAINTABLE, paintable);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
drag_drop (GtkDropTarget *dest,
|
|
||||||
const GValue *value,
|
|
||||||
double x,
|
|
||||||
double y,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
|
|
||||||
DemoImage *demo = DEMO_IMAGE (widget);
|
|
||||||
GdkPaintable *paintable = g_value_get_object (value);
|
|
||||||
|
|
||||||
gtk_image_set_from_paintable (GTK_IMAGE (demo->image), paintable);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
copy_image (GtkWidget *widget,
|
|
||||||
const char *action_name,
|
|
||||||
GVariant *parameter)
|
|
||||||
{
|
|
||||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
|
|
||||||
DemoImage *demo = DEMO_IMAGE (widget);
|
|
||||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (demo->image));
|
|
||||||
GValue value = G_VALUE_INIT;
|
|
||||||
|
|
||||||
g_value_init (&value, GDK_TYPE_PAINTABLE);
|
|
||||||
g_value_set_object (&value, paintable);
|
|
||||||
gdk_clipboard_set_value (clipboard, &value);
|
|
||||||
g_value_unset (&value);
|
|
||||||
|
|
||||||
if (paintable)
|
|
||||||
g_object_unref (paintable);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
paste_image (GtkWidget *widget,
|
|
||||||
const char *action_name,
|
|
||||||
GVariant *parameter)
|
|
||||||
{
|
|
||||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
|
|
||||||
DemoImage *demo = DEMO_IMAGE (widget);
|
|
||||||
GdkContentProvider *content = gdk_clipboard_get_content (clipboard);
|
|
||||||
GValue value = G_VALUE_INIT;
|
|
||||||
GdkPaintable *paintable;
|
|
||||||
|
|
||||||
g_value_init (&value, GDK_TYPE_PAINTABLE);
|
|
||||||
if (!gdk_content_provider_get_value (content, &value, NULL))
|
|
||||||
return;
|
|
||||||
|
|
||||||
paintable = GDK_PAINTABLE (g_value_get_object (&value));
|
|
||||||
gtk_image_set_from_paintable (GTK_IMAGE (demo->image), paintable);
|
|
||||||
g_value_unset (&value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pressed_cb (GtkGesture *gesture,
|
|
||||||
int n_press,
|
|
||||||
double x,
|
|
||||||
double y,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
DemoImage *demo = DEMO_IMAGE (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture)));
|
|
||||||
|
|
||||||
gtk_popover_popup (GTK_POPOVER (demo->popover));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_image_init (DemoImage *demo)
|
|
||||||
{
|
|
||||||
GMenu *menu;
|
|
||||||
GMenuItem *item;
|
|
||||||
GtkDragSource *source;
|
|
||||||
GtkDropTarget *dest;
|
|
||||||
GtkGesture *gesture;
|
|
||||||
|
|
||||||
demo->image = gtk_image_new ();
|
|
||||||
gtk_image_set_pixel_size (GTK_IMAGE (demo->image), 48);
|
|
||||||
gtk_widget_set_parent (demo->image, GTK_WIDGET (demo));
|
|
||||||
|
|
||||||
menu = g_menu_new ();
|
|
||||||
item = g_menu_item_new (_("_Copy"), "clipboard.copy");
|
|
||||||
g_menu_append_item (menu, item);
|
|
||||||
|
|
||||||
item = g_menu_item_new (_("_Paste"), "clipboard.paste");
|
|
||||||
g_menu_append_item (menu, item);
|
|
||||||
|
|
||||||
demo->popover = gtk_popover_menu_new_from_model (G_MENU_MODEL (menu));
|
|
||||||
gtk_widget_set_parent (demo->popover, GTK_WIDGET (demo));
|
|
||||||
|
|
||||||
source = gtk_drag_source_new ();
|
|
||||||
g_signal_connect (source, "prepare", G_CALLBACK (prepare_drag), NULL);
|
|
||||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), NULL);
|
|
||||||
gtk_widget_add_controller (GTK_WIDGET (demo), GTK_EVENT_CONTROLLER (source));
|
|
||||||
|
|
||||||
dest = gtk_drop_target_new (GDK_TYPE_PAINTABLE, GDK_ACTION_COPY);
|
|
||||||
g_signal_connect (dest, "drop", G_CALLBACK (drag_drop), NULL);
|
|
||||||
gtk_widget_add_controller (GTK_WIDGET (demo), GTK_EVENT_CONTROLLER (dest));
|
|
||||||
|
|
||||||
gesture = gtk_gesture_click_new ();
|
|
||||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
|
||||||
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), NULL);
|
|
||||||
gtk_widget_add_controller (GTK_WIDGET (demo), GTK_EVENT_CONTROLLER (gesture));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_image_dispose (GObject *object)
|
|
||||||
{
|
|
||||||
DemoImage *demo = DEMO_IMAGE (object);
|
|
||||||
|
|
||||||
g_clear_pointer (&demo->image, gtk_widget_unparent);
|
|
||||||
g_clear_pointer (&demo->popover, gtk_widget_unparent);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (demo_image_parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_image_get_property (GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
DemoImage *demo = DEMO_IMAGE (object);
|
|
||||||
|
|
||||||
switch (prop_id)
|
|
||||||
{
|
|
||||||
case PROP_ICON_NAME:
|
|
||||||
g_value_set_string (value, gtk_image_get_icon_name (GTK_IMAGE (demo->image)));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_image_set_property (GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
const GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
DemoImage *demo = DEMO_IMAGE (object);
|
|
||||||
|
|
||||||
switch (prop_id)
|
|
||||||
{
|
|
||||||
case PROP_ICON_NAME:
|
|
||||||
gtk_image_set_from_icon_name (GTK_IMAGE (demo->image),
|
|
||||||
g_value_get_string (value));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_image_class_init (DemoImageClass *class)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
|
||||||
|
|
||||||
object_class->dispose = demo_image_dispose;
|
|
||||||
object_class->get_property = demo_image_get_property;
|
|
||||||
object_class->set_property = demo_image_set_property;
|
|
||||||
|
|
||||||
g_object_class_install_property (object_class, PROP_ICON_NAME,
|
|
||||||
g_param_spec_string ("icon-name", "Icon name", "Icon name",
|
|
||||||
NULL, G_PARAM_READWRITE));
|
|
||||||
|
|
||||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
|
||||||
|
|
||||||
gtk_widget_class_install_action (widget_class, "clipboard.copy", NULL, copy_image);
|
|
||||||
gtk_widget_class_install_action (widget_class, "clipboard.paste", NULL, paste_image);
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget *
|
|
||||||
demo_image_new (const char *icon_name)
|
|
||||||
{
|
|
||||||
return g_object_new (DEMO_TYPE_IMAGE, "icon-name", icon_name, NULL);
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define DEMO_TYPE_IMAGE (demo_image_get_type ())
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE(DemoImage, demo_image, DEMO, IMAGE, GtkWidget)
|
|
||||||
|
|
||||||
GtkWidget * demo_image_new (const char *icon_name);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
@@ -1,445 +0,0 @@
|
|||||||
/* GTK - The GIMP Toolkit
|
|
||||||
* Copyright (C) 2019 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* - Matthias Clasen <mclasen@redhat.com>
|
|
||||||
*
|
|
||||||
* 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 "config.h"
|
|
||||||
|
|
||||||
#include "demotaggedentry.h"
|
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
#include <gtk/gtk-a11y.h>
|
|
||||||
|
|
||||||
struct _DemoTaggedEntry
|
|
||||||
{
|
|
||||||
GtkWidget parent_instance;
|
|
||||||
|
|
||||||
GtkWidget *box;
|
|
||||||
GtkWidget *entry;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _DemoTaggedEntryClass
|
|
||||||
{
|
|
||||||
GtkWidgetClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void demo_tagged_entry_editable_init (GtkEditableInterface *iface);
|
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (DemoTaggedEntry, demo_tagged_entry, GTK_TYPE_WIDGET,
|
|
||||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE, demo_tagged_entry_editable_init))
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_tagged_entry_init (DemoTaggedEntry *entry)
|
|
||||||
{
|
|
||||||
entry->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
||||||
gtk_widget_set_parent (entry->box, GTK_WIDGET (entry));
|
|
||||||
|
|
||||||
entry->entry = gtk_text_new ();
|
|
||||||
gtk_widget_set_hexpand (entry->entry, TRUE);
|
|
||||||
gtk_widget_set_vexpand (entry->entry, TRUE);
|
|
||||||
gtk_widget_set_hexpand (entry->box, FALSE);
|
|
||||||
gtk_widget_set_vexpand (entry->box, FALSE);
|
|
||||||
gtk_box_append (GTK_BOX (entry->box), entry->entry);
|
|
||||||
gtk_editable_init_delegate (GTK_EDITABLE (entry));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_tagged_entry_dispose (GObject *object)
|
|
||||||
{
|
|
||||||
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (object);
|
|
||||||
|
|
||||||
if (entry->entry)
|
|
||||||
gtk_editable_finish_delegate (GTK_EDITABLE (entry));
|
|
||||||
|
|
||||||
g_clear_pointer (&entry->entry, gtk_widget_unparent);
|
|
||||||
g_clear_pointer (&entry->box, gtk_widget_unparent);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (demo_tagged_entry_parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_tagged_entry_set_property (GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
const GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
if (gtk_editable_delegate_set_property (object, prop_id, value, pspec))
|
|
||||||
return;
|
|
||||||
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_tagged_entry_get_property (GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
if (gtk_editable_delegate_get_property (object, prop_id, value, pspec))
|
|
||||||
return;
|
|
||||||
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
demo_tagged_entry_grab_focus (GtkWidget *widget)
|
|
||||||
{
|
|
||||||
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
|
|
||||||
|
|
||||||
return gtk_widget_grab_focus (entry->entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_tagged_entry_class_init (DemoTaggedEntryClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
||||||
|
|
||||||
object_class->dispose = demo_tagged_entry_dispose;
|
|
||||||
object_class->get_property = demo_tagged_entry_get_property;
|
|
||||||
object_class->set_property = demo_tagged_entry_set_property;
|
|
||||||
|
|
||||||
widget_class->grab_focus = demo_tagged_entry_grab_focus;
|
|
||||||
|
|
||||||
gtk_editable_install_properties (object_class, 1);
|
|
||||||
|
|
||||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
|
||||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_ENTRY_ACCESSIBLE);
|
|
||||||
gtk_widget_class_set_css_name (widget_class, "entry");
|
|
||||||
}
|
|
||||||
|
|
||||||
static GtkEditable *
|
|
||||||
demo_tagged_entry_get_delegate (GtkEditable *editable)
|
|
||||||
{
|
|
||||||
return GTK_EDITABLE (DEMO_TAGGED_ENTRY (editable)->entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_tagged_entry_editable_init (GtkEditableInterface *iface)
|
|
||||||
{
|
|
||||||
iface->get_delegate = demo_tagged_entry_get_delegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget *
|
|
||||||
demo_tagged_entry_new (void)
|
|
||||||
{
|
|
||||||
return GTK_WIDGET (g_object_new (DEMO_TYPE_TAGGED_ENTRY, NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
demo_tagged_entry_add_tag (DemoTaggedEntry *entry,
|
|
||||||
GtkWidget *tag)
|
|
||||||
{
|
|
||||||
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
|
|
||||||
|
|
||||||
gtk_box_append (GTK_BOX (entry->box), tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
demo_tagged_entry_insert_tag_after (DemoTaggedEntry *entry,
|
|
||||||
GtkWidget *tag,
|
|
||||||
GtkWidget *sibling)
|
|
||||||
{
|
|
||||||
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
|
|
||||||
|
|
||||||
if (sibling == NULL)
|
|
||||||
gtk_box_append (GTK_BOX (entry->box), tag);
|
|
||||||
else
|
|
||||||
gtk_box_insert_child_after (GTK_BOX (entry->box), tag, sibling);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
demo_tagged_entry_remove_tag (DemoTaggedEntry *entry,
|
|
||||||
GtkWidget *tag)
|
|
||||||
{
|
|
||||||
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
|
|
||||||
|
|
||||||
gtk_box_remove (GTK_BOX (entry->box), tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct _DemoTaggedEntryTag
|
|
||||||
{
|
|
||||||
GtkWidget parent;
|
|
||||||
|
|
||||||
GtkWidget *box;
|
|
||||||
GtkWidget *label;
|
|
||||||
GtkWidget *button;
|
|
||||||
|
|
||||||
gboolean has_close_button;
|
|
||||||
char *style;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _DemoTaggedEntryTagClass
|
|
||||||
{
|
|
||||||
GtkWidgetClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PROP_0,
|
|
||||||
PROP_LABEL,
|
|
||||||
PROP_HAS_CLOSE_BUTTON,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
SIGNAL_CLICKED,
|
|
||||||
SIGNAL_BUTTON_CLICKED,
|
|
||||||
LAST_SIGNAL
|
|
||||||
};
|
|
||||||
|
|
||||||
static guint signals[LAST_SIGNAL] = { 0, };
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (DemoTaggedEntryTag, demo_tagged_entry_tag, GTK_TYPE_WIDGET)
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_released (GtkGestureClick *gesture,
|
|
||||||
int n_press,
|
|
||||||
double x,
|
|
||||||
double y,
|
|
||||||
DemoTaggedEntryTag *tag)
|
|
||||||
{
|
|
||||||
g_signal_emit (tag, signals[SIGNAL_CLICKED], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_tagged_entry_tag_init (DemoTaggedEntryTag *tag)
|
|
||||||
{
|
|
||||||
GtkGesture *gesture;
|
|
||||||
GtkCssProvider *provider;
|
|
||||||
|
|
||||||
tag->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
||||||
gtk_widget_set_parent (tag->box, GTK_WIDGET (tag));
|
|
||||||
tag->label = gtk_label_new ("");
|
|
||||||
gtk_box_append (GTK_BOX (tag->box), tag->label);
|
|
||||||
|
|
||||||
gesture = gtk_gesture_click_new ();
|
|
||||||
g_signal_connect (gesture, "released", G_CALLBACK (on_released), tag);
|
|
||||||
gtk_widget_add_controller (GTK_WIDGET (tag), GTK_EVENT_CONTROLLER (gesture));
|
|
||||||
|
|
||||||
provider = gtk_css_provider_new ();
|
|
||||||
gtk_css_provider_load_from_resource (provider, "/tagged_entry/tagstyle.css");
|
|
||||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
|
||||||
GTK_STYLE_PROVIDER (provider),
|
|
||||||
800);
|
|
||||||
g_object_unref (provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_tagged_entry_tag_dispose (GObject *object)
|
|
||||||
{
|
|
||||||
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (object);
|
|
||||||
|
|
||||||
g_clear_pointer (&tag->box, gtk_widget_unparent);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (demo_tagged_entry_tag_parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_tagged_entry_tag_finalize (GObject *object)
|
|
||||||
{
|
|
||||||
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (object);
|
|
||||||
|
|
||||||
g_clear_pointer (&tag->box, gtk_widget_unparent);
|
|
||||||
g_clear_pointer (&tag->style, g_free);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (demo_tagged_entry_tag_parent_class)->finalize (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_tagged_entry_tag_set_property (GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
const GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (object);
|
|
||||||
|
|
||||||
switch (prop_id)
|
|
||||||
{
|
|
||||||
case PROP_LABEL:
|
|
||||||
demo_tagged_entry_tag_set_label (tag, g_value_get_string (value));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_HAS_CLOSE_BUTTON:
|
|
||||||
demo_tagged_entry_tag_set_has_close_button (tag, g_value_get_boolean (value));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_tagged_entry_tag_get_property (GObject *object,
|
|
||||||
guint prop_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (object);
|
|
||||||
|
|
||||||
switch (prop_id)
|
|
||||||
{
|
|
||||||
case PROP_LABEL:
|
|
||||||
g_value_set_string (value, demo_tagged_entry_tag_get_label (tag));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PROP_HAS_CLOSE_BUTTON:
|
|
||||||
g_value_set_boolean (value, demo_tagged_entry_tag_get_has_close_button (tag));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_tagged_entry_tag_measure (GtkWidget *widget,
|
|
||||||
GtkOrientation orientation,
|
|
||||||
int for_size,
|
|
||||||
int *minimum,
|
|
||||||
int *natural,
|
|
||||||
int *minimum_baseline,
|
|
||||||
int *natural_baseline)
|
|
||||||
{
|
|
||||||
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (widget);
|
|
||||||
|
|
||||||
gtk_widget_measure (tag->box, orientation, for_size,
|
|
||||||
minimum, natural,
|
|
||||||
minimum_baseline, natural_baseline);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_tagged_entry_tag_size_allocate (GtkWidget *widget,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int baseline)
|
|
||||||
{
|
|
||||||
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (widget);
|
|
||||||
|
|
||||||
gtk_widget_size_allocate (tag->box,
|
|
||||||
&(GtkAllocation) { 0, 0, width, height },
|
|
||||||
baseline);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
demo_tagged_entry_tag_class_init (DemoTaggedEntryTagClass *class)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
|
||||||
|
|
||||||
object_class->dispose = demo_tagged_entry_tag_dispose;
|
|
||||||
object_class->finalize = demo_tagged_entry_tag_finalize;
|
|
||||||
object_class->set_property = demo_tagged_entry_tag_set_property;
|
|
||||||
object_class->get_property = demo_tagged_entry_tag_get_property;
|
|
||||||
|
|
||||||
widget_class->measure = demo_tagged_entry_tag_measure;
|
|
||||||
widget_class->size_allocate = demo_tagged_entry_tag_size_allocate;
|
|
||||||
|
|
||||||
signals[SIGNAL_CLICKED] =
|
|
||||||
g_signal_new ("clicked",
|
|
||||||
DEMO_TYPE_TAGGED_ENTRY_TAG,
|
|
||||||
G_SIGNAL_RUN_FIRST,
|
|
||||||
0, NULL, NULL, NULL,
|
|
||||||
G_TYPE_NONE, 0);
|
|
||||||
signals[SIGNAL_BUTTON_CLICKED] =
|
|
||||||
g_signal_new ("button-clicked",
|
|
||||||
DEMO_TYPE_TAGGED_ENTRY_TAG,
|
|
||||||
G_SIGNAL_RUN_FIRST,
|
|
||||||
0, NULL, NULL, NULL,
|
|
||||||
G_TYPE_NONE, 0);
|
|
||||||
|
|
||||||
g_object_class_install_property (object_class, PROP_LABEL,
|
|
||||||
g_param_spec_string ("label", "Label", "Label",
|
|
||||||
NULL, G_PARAM_READWRITE));
|
|
||||||
g_object_class_install_property (object_class, PROP_HAS_CLOSE_BUTTON,
|
|
||||||
g_param_spec_boolean ("has-close-button", "Has close button", "Whether this tag has a close button",
|
|
||||||
FALSE, G_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
|
||||||
|
|
||||||
gtk_widget_class_set_css_name (widget_class, "tag");
|
|
||||||
}
|
|
||||||
|
|
||||||
DemoTaggedEntryTag *
|
|
||||||
demo_tagged_entry_tag_new (const char *label)
|
|
||||||
{
|
|
||||||
return DEMO_TAGGED_ENTRY_TAG (g_object_new (DEMO_TYPE_TAGGED_ENTRY_TAG,
|
|
||||||
"label", label,
|
|
||||||
NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
demo_tagged_entry_tag_get_label (DemoTaggedEntryTag *tag)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (DEMO_IS_TAGGED_ENTRY_TAG (tag), NULL);
|
|
||||||
|
|
||||||
return gtk_label_get_label (GTK_LABEL (tag->label));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
demo_tagged_entry_tag_set_label (DemoTaggedEntryTag *tag,
|
|
||||||
const char *label)
|
|
||||||
{
|
|
||||||
g_return_if_fail (DEMO_IS_TAGGED_ENTRY_TAG (tag));
|
|
||||||
|
|
||||||
gtk_label_set_label (GTK_LABEL (tag->label), label);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_button_clicked (GtkButton *button,
|
|
||||||
DemoTaggedEntryTag *tag)
|
|
||||||
{
|
|
||||||
g_signal_emit (tag, signals[SIGNAL_BUTTON_CLICKED], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
demo_tagged_entry_tag_set_has_close_button (DemoTaggedEntryTag *tag,
|
|
||||||
gboolean has_close_button)
|
|
||||||
{
|
|
||||||
g_return_if_fail (DEMO_IS_TAGGED_ENTRY_TAG (tag));
|
|
||||||
|
|
||||||
if ((tag->button != NULL) == has_close_button)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!has_close_button && tag->button)
|
|
||||||
{
|
|
||||||
gtk_box_remove (GTK_BOX (tag->box), tag->button);
|
|
||||||
tag->button = NULL;
|
|
||||||
}
|
|
||||||
else if (has_close_button && tag->button == NULL)
|
|
||||||
{
|
|
||||||
GtkWidget *image;
|
|
||||||
|
|
||||||
image = gtk_image_new_from_icon_name ("window-close-symbolic");
|
|
||||||
tag->button = gtk_button_new ();
|
|
||||||
gtk_button_set_child (GTK_BUTTON (tag->button), image);
|
|
||||||
gtk_widget_set_halign (tag->button, GTK_ALIGN_CENTER);
|
|
||||||
gtk_widget_set_valign (tag->button, GTK_ALIGN_CENTER);
|
|
||||||
gtk_button_set_has_frame (GTK_BUTTON (tag->button), FALSE);
|
|
||||||
gtk_box_append (GTK_BOX (tag->box), tag->button);
|
|
||||||
g_signal_connect (tag->button, "clicked", G_CALLBACK (on_button_clicked), tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (tag), "has-close-button");
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
demo_tagged_entry_tag_get_has_close_button (DemoTaggedEntryTag *tag)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (DEMO_IS_TAGGED_ENTRY_TAG (tag), FALSE);
|
|
||||||
|
|
||||||
return tag->button != NULL;
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/* GTK - The GIMP Toolkit
|
|
||||||
* Copyright (C) 2019 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* - Matthias Clasen <mclasen@redhat.com>
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __DEMO_TAGGED_ENTRY_H__
|
|
||||||
#define __DEMO_TAGGED_ENTRY_H__
|
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define DEMO_TYPE_TAGGED_ENTRY (demo_tagged_entry_get_type ())
|
|
||||||
G_DECLARE_FINAL_TYPE (DemoTaggedEntry, demo_tagged_entry, DEMO, TAGGED_ENTRY, GtkWidget)
|
|
||||||
|
|
||||||
#define DEMO_TYPE_TAGGED_ENTRY_TAG (demo_tagged_entry_tag_get_type ())
|
|
||||||
G_DECLARE_FINAL_TYPE (DemoTaggedEntryTag, demo_tagged_entry_tag, DEMO, TAGGED_ENTRY_TAG, GtkWidget)
|
|
||||||
|
|
||||||
GtkWidget * demo_tagged_entry_new (void);
|
|
||||||
|
|
||||||
void demo_tagged_entry_add_tag (DemoTaggedEntry *entry,
|
|
||||||
GtkWidget *tag);
|
|
||||||
|
|
||||||
void demo_tagged_entry_insert_tag_after (DemoTaggedEntry *entry,
|
|
||||||
GtkWidget *tag,
|
|
||||||
GtkWidget *sibling);
|
|
||||||
|
|
||||||
void demo_tagged_entry_remove_tag (DemoTaggedEntry *entry,
|
|
||||||
GtkWidget *tag);
|
|
||||||
|
|
||||||
DemoTaggedEntryTag *
|
|
||||||
demo_tagged_entry_tag_new (const char *label);
|
|
||||||
|
|
||||||
const char * demo_tagged_entry_tag_get_label (DemoTaggedEntryTag *tag);
|
|
||||||
|
|
||||||
void demo_tagged_entry_tag_set_label (DemoTaggedEntryTag *tag,
|
|
||||||
const char *label);
|
|
||||||
|
|
||||||
gboolean demo_tagged_entry_tag_get_has_close_button (DemoTaggedEntryTag *tag);
|
|
||||||
|
|
||||||
void demo_tagged_entry_tag_set_has_close_button (DemoTaggedEntryTag *tag,
|
|
||||||
gboolean has_close_button);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __DEMO_TAGGED_ENTRY_H__ */
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
/* Dialogs
|
/* Dialogs and Message Boxes
|
||||||
*
|
*
|
||||||
* Dialogs are used to pop up transient windows for information
|
* Dialog widgets are used to pop up a transient window for user feedback.
|
||||||
* and user feedback.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
@@ -16,81 +15,61 @@ message_dialog_clicked (GtkButton *button,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
static int i = 1;
|
static gint i = 1;
|
||||||
|
|
||||||
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
||||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
GTK_MESSAGE_INFO,
|
GTK_MESSAGE_INFO,
|
||||||
GTK_BUTTONS_OK_CANCEL,
|
GTK_BUTTONS_OK_CANCEL,
|
||||||
"Test message");
|
"This message box has been popped up the following\n"
|
||||||
|
"number of times:");
|
||||||
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);
|
"%d", i);
|
||||||
g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
|
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||||
gtk_widget_show (dialog);
|
gtk_widget_destroy (dialog);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
GtkWidget *local_entry1;
|
|
||||||
GtkWidget *local_entry2;
|
|
||||||
GtkWidget *global_entry1;
|
|
||||||
GtkWidget *global_entry2;
|
|
||||||
} ResponseData;
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_dialog_response (GtkDialog *dialog,
|
|
||||||
int response,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
ResponseData *data = user_data;
|
|
||||||
|
|
||||||
if (response == GTK_RESPONSE_OK)
|
|
||||||
{
|
|
||||||
gtk_editable_set_text (GTK_EDITABLE (data->global_entry1),
|
|
||||||
gtk_editable_get_text (GTK_EDITABLE (data->local_entry1)));
|
|
||||||
gtk_editable_set_text (GTK_EDITABLE (data->global_entry2),
|
|
||||||
gtk_editable_get_text (GTK_EDITABLE (data->local_entry2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_window_destroy (GTK_WINDOW (dialog));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
interactive_dialog_clicked (GtkButton *button,
|
interactive_dialog_clicked (GtkButton *button,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GtkWidget *content_area;
|
GtkWidget *content_area;
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
|
GtkWidget *hbox;
|
||||||
|
GtkWidget *image;
|
||||||
GtkWidget *table;
|
GtkWidget *table;
|
||||||
GtkWidget *local_entry1;
|
GtkWidget *local_entry1;
|
||||||
GtkWidget *local_entry2;
|
GtkWidget *local_entry2;
|
||||||
GtkWidget *label;
|
GtkWidget *label;
|
||||||
ResponseData *data;
|
gint response;
|
||||||
|
|
||||||
dialog = gtk_dialog_new_with_buttons ("Interactive Dialog",
|
dialog = gtk_dialog_new_with_buttons ("Interactive Dialog",
|
||||||
GTK_WINDOW (window),
|
GTK_WINDOW (window),
|
||||||
GTK_DIALOG_MODAL| GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_USE_HEADER_BAR,
|
GTK_DIALOG_MODAL| GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
_("_OK"), GTK_RESPONSE_OK,
|
_("_OK"),
|
||||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
GTK_RESPONSE_OK,
|
||||||
|
"_Cancel",
|
||||||
|
GTK_RESPONSE_CANCEL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
|
|
||||||
|
|
||||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||||
|
|
||||||
table = gtk_grid_new ();
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||||
gtk_widget_set_hexpand (table, TRUE);
|
gtk_box_pack_start (GTK_BOX (content_area), hbox);
|
||||||
gtk_widget_set_vexpand (table, TRUE);
|
|
||||||
gtk_widget_set_halign (table, GTK_ALIGN_CENTER);
|
|
||||||
gtk_widget_set_valign (table, GTK_ALIGN_CENTER);
|
|
||||||
gtk_box_append (GTK_BOX (content_area), table);
|
|
||||||
gtk_grid_set_row_spacing (GTK_GRID (table), 6);
|
|
||||||
gtk_grid_set_column_spacing (GTK_GRID (table), 6);
|
|
||||||
|
|
||||||
|
image = gtk_image_new_from_icon_name ("dialog-question");
|
||||||
|
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
|
||||||
|
gtk_box_pack_start (GTK_BOX (hbox), image);
|
||||||
|
|
||||||
|
table = gtk_grid_new ();
|
||||||
|
gtk_grid_set_row_spacing (GTK_GRID (table), 4);
|
||||||
|
gtk_grid_set_column_spacing (GTK_GRID (table), 4);
|
||||||
|
gtk_box_pack_start (GTK_BOX (hbox), table);
|
||||||
label = gtk_label_new_with_mnemonic ("_Entry 1");
|
label = gtk_label_new_with_mnemonic ("_Entry 1");
|
||||||
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
|
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
|
||||||
local_entry1 = gtk_entry_new ();
|
local_entry1 = gtk_entry_new ();
|
||||||
gtk_editable_set_text (GTK_EDITABLE (local_entry1), gtk_editable_get_text (GTK_EDITABLE (entry1)));
|
gtk_entry_set_text (GTK_ENTRY (local_entry1), gtk_entry_get_text (GTK_ENTRY (entry1)));
|
||||||
gtk_grid_attach (GTK_GRID (table), local_entry1, 1, 0, 1, 1);
|
gtk_grid_attach (GTK_GRID (table), local_entry1, 1, 0, 1, 1);
|
||||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), local_entry1);
|
gtk_label_set_mnemonic_widget (GTK_LABEL (label), local_entry1);
|
||||||
|
|
||||||
@@ -98,27 +77,25 @@ interactive_dialog_clicked (GtkButton *button,
|
|||||||
gtk_grid_attach (GTK_GRID (table), label, 0, 1, 1, 1);
|
gtk_grid_attach (GTK_GRID (table), label, 0, 1, 1, 1);
|
||||||
|
|
||||||
local_entry2 = gtk_entry_new ();
|
local_entry2 = gtk_entry_new ();
|
||||||
gtk_editable_set_text (GTK_EDITABLE (local_entry2), gtk_editable_get_text (GTK_EDITABLE (entry2)));
|
gtk_entry_set_text (GTK_ENTRY (local_entry2), gtk_entry_get_text (GTK_ENTRY (entry2)));
|
||||||
gtk_grid_attach (GTK_GRID (table), local_entry2, 1, 1, 1, 1);
|
gtk_grid_attach (GTK_GRID (table), local_entry2, 1, 1, 1, 1);
|
||||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), local_entry2);
|
gtk_label_set_mnemonic_widget (GTK_LABEL (label), local_entry2);
|
||||||
|
|
||||||
data = g_new (ResponseData, 1);
|
response = gtk_dialog_run (GTK_DIALOG (dialog));
|
||||||
data->local_entry1 = local_entry1;
|
|
||||||
data->local_entry2 = local_entry2;
|
|
||||||
data->global_entry1 = entry1;
|
|
||||||
data->global_entry2 = entry2;
|
|
||||||
|
|
||||||
g_signal_connect_data (dialog, "response",
|
if (response == GTK_RESPONSE_OK)
|
||||||
G_CALLBACK (on_dialog_response),
|
{
|
||||||
data, (GClosureNotify) g_free,
|
gtk_entry_set_text (GTK_ENTRY (entry1), gtk_entry_get_text (GTK_ENTRY (local_entry1)));
|
||||||
0);
|
gtk_entry_set_text (GTK_ENTRY (entry2), gtk_entry_get_text (GTK_ENTRY (local_entry2)));
|
||||||
|
}
|
||||||
|
|
||||||
gtk_widget_show (dialog);
|
gtk_widget_destroy (dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
do_dialog (GtkWidget *do_widget)
|
do_dialog (GtkWidget *do_widget)
|
||||||
{
|
{
|
||||||
|
GtkWidget *frame;
|
||||||
GtkWidget *vbox;
|
GtkWidget *vbox;
|
||||||
GtkWidget *vbox2;
|
GtkWidget *vbox2;
|
||||||
GtkWidget *hbox;
|
GtkWidget *hbox;
|
||||||
@@ -128,45 +105,47 @@ do_dialog (GtkWidget *do_widget)
|
|||||||
|
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
window = gtk_window_new ();
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
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));
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Dialogs");
|
gtk_window_set_title (GTK_WINDOW (window), "Dialogs and Message Boxes");
|
||||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
|
frame = gtk_frame_new ("Dialogs");
|
||||||
|
g_object_set (frame, "margin", 8, NULL);
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), frame);
|
||||||
|
|
||||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
|
||||||
gtk_widget_set_margin_start (vbox, 8);
|
g_object_set (vbox, "margin", 8, NULL);
|
||||||
gtk_widget_set_margin_end (vbox, 8);
|
gtk_container_add (GTK_CONTAINER (frame), vbox);
|
||||||
gtk_widget_set_margin_top (vbox, 8);
|
|
||||||
gtk_widget_set_margin_bottom (vbox, 8);
|
|
||||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
|
||||||
|
|
||||||
/* Standard message dialog */
|
/* Standard message dialog */
|
||||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||||
gtk_box_append (GTK_BOX (vbox), hbox);
|
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||||
button = gtk_button_new_with_mnemonic ("_Message Dialog");
|
button = gtk_button_new_with_mnemonic ("_Message Dialog");
|
||||||
g_signal_connect (button, "clicked",
|
g_signal_connect (button, "clicked",
|
||||||
G_CALLBACK (message_dialog_clicked), NULL);
|
G_CALLBACK (message_dialog_clicked), NULL);
|
||||||
gtk_box_append (GTK_BOX (hbox), button);
|
gtk_box_pack_start (GTK_BOX (hbox), button);
|
||||||
|
|
||||||
gtk_box_append (GTK_BOX (vbox), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
|
gtk_box_pack_start (GTK_BOX (vbox), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
|
||||||
|
|
||||||
/* Interactive dialog*/
|
/* Interactive dialog*/
|
||||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||||
gtk_box_append (GTK_BOX (vbox), hbox);
|
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||||
vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||||
|
|
||||||
button = gtk_button_new_with_mnemonic ("_Interactive Dialog");
|
button = gtk_button_new_with_mnemonic ("_Interactive Dialog");
|
||||||
g_signal_connect (button, "clicked",
|
g_signal_connect (button, "clicked",
|
||||||
G_CALLBACK (interactive_dialog_clicked), NULL);
|
G_CALLBACK (interactive_dialog_clicked), NULL);
|
||||||
gtk_box_append (GTK_BOX (hbox), vbox2);
|
gtk_box_pack_start (GTK_BOX (hbox), vbox2);
|
||||||
gtk_box_append (GTK_BOX (vbox2), button);
|
gtk_box_pack_start (GTK_BOX (vbox2), button);
|
||||||
|
|
||||||
table = gtk_grid_new ();
|
table = gtk_grid_new ();
|
||||||
gtk_grid_set_row_spacing (GTK_GRID (table), 4);
|
gtk_grid_set_row_spacing (GTK_GRID (table), 4);
|
||||||
gtk_grid_set_column_spacing (GTK_GRID (table), 4);
|
gtk_grid_set_column_spacing (GTK_GRID (table), 4);
|
||||||
gtk_box_append (GTK_BOX (hbox), table);
|
gtk_box_pack_start (GTK_BOX (hbox), table);
|
||||||
|
|
||||||
label = gtk_label_new_with_mnemonic ("_Entry 1");
|
label = gtk_label_new_with_mnemonic ("_Entry 1");
|
||||||
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
|
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
|
||||||
@@ -185,7 +164,7 @@ do_dialog (GtkWidget *do_widget)
|
|||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,450 +1,235 @@
|
|||||||
/* Drag-and-Drop
|
/* Drag-and-Drop
|
||||||
*
|
*
|
||||||
* This demo shows dragging colors and widgets.
|
* I can't believe its not glade!
|
||||||
* The items in this demo can be moved, recolored
|
|
||||||
* and rotated.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <glib/gi18n.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (CanvasItem, canvas_item, CANVAS, ITEM, GtkWidget)
|
typedef struct _GtkDemoWidget GtkDemoWidget;
|
||||||
|
struct _GtkDemoWidget
|
||||||
struct _CanvasItem {
|
{
|
||||||
GtkWidget parent;
|
GType type;
|
||||||
|
union {
|
||||||
GtkWidget *fixed;
|
char *text;
|
||||||
GtkWidget *label;
|
gboolean active;
|
||||||
|
};
|
||||||
double r;
|
|
||||||
double angle;
|
|
||||||
double delta;
|
|
||||||
|
|
||||||
GtkWidget *editor;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _CanvasItemClass {
|
static gpointer
|
||||||
GtkWidgetClass parent_class;
|
copy_demo_widget (gpointer data)
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (CanvasItem, canvas_item, GTK_TYPE_WIDGET)
|
|
||||||
|
|
||||||
static int n_items = 0;
|
|
||||||
|
|
||||||
static void
|
|
||||||
set_color (CanvasItem *item,
|
|
||||||
GdkRGBA *color)
|
|
||||||
{
|
{
|
||||||
char *css;
|
GtkDemoWidget *demo = g_memdup (data, sizeof (GtkDemoWidget));
|
||||||
char *str;
|
|
||||||
GtkStyleContext *context;
|
|
||||||
GtkCssProvider *provider;
|
|
||||||
const char *old_class;
|
|
||||||
|
|
||||||
str = gdk_rgba_to_string (color);
|
if (demo->type == GTK_TYPE_LABEL)
|
||||||
css = g_strdup_printf ("* { background: %s; }", str);
|
demo->text = g_strdup (demo->text);
|
||||||
|
|
||||||
context = gtk_widget_get_style_context (item->label);
|
return demo;
|
||||||
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 ();
|
|
||||||
gtk_css_provider_load_from_data (provider, css, -1);
|
|
||||||
gtk_style_context_add_provider (gtk_widget_get_style_context (item->label), GTK_STYLE_PROVIDER (provider), 800);
|
|
||||||
g_object_set_data_full (G_OBJECT (context), "style-provider", provider, g_object_unref);
|
|
||||||
|
|
||||||
g_free (str);
|
|
||||||
g_free (css);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_css (CanvasItem *item,
|
free_demo_widget (gpointer data)
|
||||||
const char *class)
|
|
||||||
{
|
{
|
||||||
GtkStyleContext *context;
|
GtkDemoWidget *demo = data;
|
||||||
GtkCssProvider *provider;
|
|
||||||
const char *old_class;
|
|
||||||
|
|
||||||
context = gtk_widget_get_style_context (item->label);
|
if (demo->type == GTK_TYPE_LABEL)
|
||||||
provider = g_object_get_data (G_OBJECT (context), "style-provider");
|
g_free (demo->text);
|
||||||
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");
|
g_free (demo);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
#define GTK_TYPE_DEMO_WIDGET (gtk_demo_widget_get_type ())
|
||||||
item_drag_drop (GtkDropTarget *dest,
|
|
||||||
const GValue *value,
|
G_DEFINE_BOXED_TYPE (GtkDemoWidget, gtk_demo_widget, copy_demo_widget, free_demo_widget)
|
||||||
double x,
|
|
||||||
double y)
|
static GtkDemoWidget *
|
||||||
|
serialize_widget (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
GtkWidget *label = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
|
GtkDemoWidget *demo;
|
||||||
CanvasItem *item = CANVAS_ITEM (gtk_widget_get_parent (gtk_widget_get_parent (label)));
|
|
||||||
|
|
||||||
if (G_VALUE_TYPE (value) == GDK_TYPE_RGBA)
|
demo = g_new0 (GtkDemoWidget, 1);
|
||||||
set_color (item, g_value_get_boxed (value));
|
demo->type = G_OBJECT_TYPE (widget);
|
||||||
else if (G_VALUE_TYPE (value) == G_TYPE_STRING)
|
|
||||||
set_css (item, g_value_get_string (value));
|
|
||||||
|
|
||||||
return TRUE;
|
if (GTK_IS_LABEL (widget))
|
||||||
}
|
{
|
||||||
|
demo->text = g_strdup (gtk_label_get_text (GTK_LABEL (widget)));
|
||||||
|
}
|
||||||
|
else if (GTK_IS_SPINNER (widget))
|
||||||
|
{
|
||||||
|
g_object_get (widget, "active", &demo->active, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_print ("Type %s not supported\n", g_type_name (demo->type));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
return demo;
|
||||||
apply_transform (CanvasItem *item)
|
|
||||||
{
|
|
||||||
GskTransform *transform;
|
|
||||||
double x, y;
|
|
||||||
|
|
||||||
x = gtk_widget_get_allocated_width (item->label) / 2.0;
|
|
||||||
y = gtk_widget_get_allocated_height (item->label) / 2.0;
|
|
||||||
item->r = sqrt (x*x + y*y);
|
|
||||||
|
|
||||||
transform = gsk_transform_translate (
|
|
||||||
gsk_transform_rotate (
|
|
||||||
gsk_transform_translate (NULL,
|
|
||||||
&(graphene_point_t) { item->r, item->r }),
|
|
||||||
item->angle + item->delta),
|
|
||||||
&(graphene_point_t) { - x, - y });
|
|
||||||
|
|
||||||
gtk_fixed_set_child_transform (GTK_FIXED (item->fixed), item->label, transform);
|
|
||||||
gsk_transform_unref (transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
angle_changed (GtkGestureRotate *gesture,
|
|
||||||
double angle,
|
|
||||||
double delta)
|
|
||||||
{
|
|
||||||
CanvasItem *item = CANVAS_ITEM (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture)));
|
|
||||||
|
|
||||||
item->delta = angle / M_PI * 180.0;
|
|
||||||
|
|
||||||
apply_transform (item);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
rotate_done (GtkGesture *gesture)
|
|
||||||
{
|
|
||||||
CanvasItem *item = CANVAS_ITEM (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture)));
|
|
||||||
|
|
||||||
item->angle = item->angle + item->delta;
|
|
||||||
item->delta = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
click_done (GtkGesture *gesture)
|
|
||||||
{
|
|
||||||
GtkWidget *item = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
|
||||||
GtkWidget *canvas = gtk_widget_get_parent (item);
|
|
||||||
GtkWidget *last_child;
|
|
||||||
|
|
||||||
last_child = gtk_widget_get_last_child (canvas);
|
|
||||||
if (item != last_child)
|
|
||||||
gtk_widget_insert_after (item, canvas, last_child);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
canvas_item_init (CanvasItem *item)
|
|
||||||
{
|
|
||||||
char *text;
|
|
||||||
char *id;
|
|
||||||
GdkRGBA rgba;
|
|
||||||
GtkDropTarget *dest;
|
|
||||||
GtkGesture *gesture;
|
|
||||||
GType types[2] = { GDK_TYPE_RGBA, G_TYPE_STRING };
|
|
||||||
|
|
||||||
n_items++;
|
|
||||||
|
|
||||||
text = g_strdup_printf ("Item %d", n_items);
|
|
||||||
item->label = gtk_label_new (text);
|
|
||||||
gtk_widget_add_css_class (item->label, "canvasitem");
|
|
||||||
g_free (text);
|
|
||||||
|
|
||||||
item->fixed = gtk_fixed_new ();
|
|
||||||
gtk_widget_set_parent (item->fixed, GTK_WIDGET (item));
|
|
||||||
gtk_fixed_put (GTK_FIXED (item->fixed), item->label, 0, 0);
|
|
||||||
|
|
||||||
gtk_widget_add_css_class (item->label, "frame");
|
|
||||||
|
|
||||||
id = g_strdup_printf ("item%d", n_items);
|
|
||||||
gtk_widget_set_name (item->label, id);
|
|
||||||
g_free (id);
|
|
||||||
|
|
||||||
gdk_rgba_parse (&rgba, "yellow");
|
|
||||||
set_color (item, &rgba);
|
|
||||||
|
|
||||||
item->angle = 0;
|
|
||||||
|
|
||||||
dest = gtk_drop_target_new (G_TYPE_INVALID, GDK_ACTION_COPY);
|
|
||||||
gtk_drop_target_set_gtypes (dest, types, G_N_ELEMENTS (types));
|
|
||||||
g_signal_connect (dest, "drop", G_CALLBACK (item_drag_drop), NULL);
|
|
||||||
gtk_widget_add_controller (GTK_WIDGET (item->label), GTK_EVENT_CONTROLLER (dest));
|
|
||||||
|
|
||||||
gesture = gtk_gesture_rotate_new ();
|
|
||||||
g_signal_connect (gesture, "angle-changed", G_CALLBACK (angle_changed), NULL);
|
|
||||||
g_signal_connect (gesture, "end", G_CALLBACK (rotate_done), NULL);
|
|
||||||
gtk_widget_add_controller (GTK_WIDGET (item), GTK_EVENT_CONTROLLER (gesture));
|
|
||||||
|
|
||||||
gesture = gtk_gesture_click_new ();
|
|
||||||
g_signal_connect (gesture, "released", G_CALLBACK (click_done), NULL);
|
|
||||||
gtk_widget_add_controller (GTK_WIDGET (item), GTK_EVENT_CONTROLLER (gesture));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
canvas_item_dispose (GObject *object)
|
|
||||||
{
|
|
||||||
CanvasItem *item = CANVAS_ITEM (object);
|
|
||||||
|
|
||||||
g_clear_pointer (&item->fixed, gtk_widget_unparent);
|
|
||||||
g_clear_pointer (&item->editor, gtk_widget_unparent);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (canvas_item_parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
canvas_item_map (GtkWidget *widget)
|
|
||||||
{
|
|
||||||
CanvasItem *item = CANVAS_ITEM (widget);
|
|
||||||
|
|
||||||
GTK_WIDGET_CLASS (canvas_item_parent_class)->map (widget);
|
|
||||||
|
|
||||||
apply_transform (item);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
canvas_item_class_init (CanvasItemClass *class)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
|
||||||
|
|
||||||
object_class->dispose = canvas_item_dispose;
|
|
||||||
|
|
||||||
widget_class->map = canvas_item_map;
|
|
||||||
|
|
||||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
|
||||||
gtk_widget_class_set_css_name (widget_class, "item");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkWidget *
|
static GtkWidget *
|
||||||
canvas_item_new (void)
|
deserialize_widget (GtkDemoWidget *demo)
|
||||||
{
|
{
|
||||||
CanvasItem *item = g_object_new (canvas_item_get_type (), NULL);
|
GtkWidget *widget = NULL;
|
||||||
|
|
||||||
return GTK_WIDGET (item);
|
if (demo->type == GTK_TYPE_LABEL)
|
||||||
|
{
|
||||||
|
widget = gtk_label_new (demo->text);
|
||||||
|
}
|
||||||
|
else if (demo->type == GTK_TYPE_SPINNER)
|
||||||
|
{
|
||||||
|
widget = g_object_new (demo->type, "active", demo->active, NULL);
|
||||||
|
gtk_style_context_add_class (gtk_widget_get_style_context (widget), "demo");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_print ("Type %s not supported\n", g_type_name (demo->type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkPaintable *
|
static double pos_x, pos_y;
|
||||||
canvas_item_get_drag_icon (CanvasItem *item)
|
|
||||||
{
|
|
||||||
return gtk_widget_paintable_new (item->fixed);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
canvas_item_is_editing (CanvasItem *item)
|
new_label_cb (GtkMenuItem *item,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
return item->editor != NULL;
|
GtkFixed *fixed = data;
|
||||||
|
GtkWidget *widget;
|
||||||
|
|
||||||
|
widget = gtk_label_new ("Label");
|
||||||
|
gtk_fixed_put (fixed, widget, pos_x, pos_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
scale_changed (GtkRange *range,
|
new_spinner_cb (GtkMenuItem *item,
|
||||||
CanvasItem *item)
|
gpointer data)
|
||||||
{
|
{
|
||||||
item->angle = gtk_range_get_value (range);
|
GtkFixed *fixed = data;
|
||||||
apply_transform (item);
|
GtkWidget *widget;
|
||||||
|
|
||||||
|
widget = gtk_spinner_new ();
|
||||||
|
gtk_style_context_add_class (gtk_widget_get_style_context (widget), "demo");
|
||||||
|
gtk_spinner_start (GTK_SPINNER (widget));
|
||||||
|
gtk_fixed_put (fixed, widget, pos_x, pos_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
text_changed (GtkEditable *editable,
|
copy_cb (GtkWidget *child)
|
||||||
GParamSpec *pspec,
|
|
||||||
CanvasItem *item)
|
|
||||||
{
|
{
|
||||||
gtk_label_set_text (GTK_LABEL (item->label), gtk_editable_get_text (editable));
|
GdkClipboard *clipboard;
|
||||||
apply_transform (item);
|
GtkDemoWidget *demo;
|
||||||
|
|
||||||
|
g_print ("Copy %s\n", G_OBJECT_TYPE_NAME (child));
|
||||||
|
|
||||||
|
demo = serialize_widget (child);
|
||||||
|
|
||||||
|
clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
|
||||||
|
gdk_clipboard_set (clipboard, GTK_TYPE_DEMO_WIDGET, demo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
canvas_item_stop_editing (CanvasItem *item)
|
delete_cb (GtkWidget *child)
|
||||||
{
|
{
|
||||||
GtkWidget *scale;
|
gtk_widget_destroy (child);
|
||||||
|
|
||||||
if (!item->editor)
|
|
||||||
return;
|
|
||||||
|
|
||||||
scale = gtk_widget_get_last_child (item->editor);
|
|
||||||
g_signal_handlers_disconnect_by_func (scale, scale_changed, item);
|
|
||||||
|
|
||||||
gtk_fixed_remove (GTK_FIXED (gtk_widget_get_parent (item->editor)), item->editor);
|
|
||||||
item->editor = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
canvas_item_start_editing (CanvasItem *item)
|
cut_cb (GtkWidget *child)
|
||||||
{
|
{
|
||||||
GtkWidget *canvas = gtk_widget_get_parent (GTK_WIDGET (item));
|
copy_cb (child);
|
||||||
GtkWidget *entry;
|
delete_cb (child);
|
||||||
GtkWidget *scale;
|
|
||||||
double x, y;
|
|
||||||
|
|
||||||
if (item->editor)
|
|
||||||
return;
|
|
||||||
|
|
||||||
item->editor = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
|
||||||
|
|
||||||
entry = gtk_entry_new ();
|
|
||||||
|
|
||||||
gtk_editable_set_text (GTK_EDITABLE (entry),
|
|
||||||
gtk_label_get_text (GTK_LABEL (item->label)));
|
|
||||||
|
|
||||||
gtk_editable_set_width_chars (GTK_EDITABLE (entry), 12);
|
|
||||||
g_signal_connect (entry, "notify::text", G_CALLBACK (text_changed), item);
|
|
||||||
g_signal_connect_swapped (entry, "activate", G_CALLBACK (canvas_item_stop_editing), item);
|
|
||||||
|
|
||||||
gtk_box_append (GTK_BOX (item->editor), entry);
|
|
||||||
|
|
||||||
scale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0, 360, 1);
|
|
||||||
gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
|
|
||||||
gtk_range_set_value (GTK_RANGE (scale), fmod (item->angle, 360));
|
|
||||||
|
|
||||||
g_signal_connect (scale, "value-changed", G_CALLBACK (scale_changed), item);
|
|
||||||
|
|
||||||
gtk_box_append (GTK_BOX (item->editor), scale);
|
|
||||||
|
|
||||||
gtk_widget_translate_coordinates (GTK_WIDGET (item), canvas, 0, 0, &x, &y);
|
|
||||||
gtk_fixed_put (GTK_FIXED (canvas), item->editor, x, y + 2 * item->r);
|
|
||||||
gtk_widget_grab_focus (entry);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static GdkContentProvider *
|
|
||||||
prepare (GtkDragSource *source,
|
|
||||||
double x,
|
|
||||||
double y)
|
|
||||||
{
|
|
||||||
GtkWidget *canvas;
|
|
||||||
GtkWidget *item;
|
|
||||||
|
|
||||||
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
|
||||||
item = gtk_widget_pick (canvas, x, y, GTK_PICK_DEFAULT);
|
|
||||||
|
|
||||||
item = gtk_widget_get_ancestor (item, canvas_item_get_type ());
|
|
||||||
if (!item)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
g_object_set_data (G_OBJECT (canvas), "dragged-item", item);
|
|
||||||
|
|
||||||
return gdk_content_provider_new_typed (GTK_TYPE_WIDGET, item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
drag_begin (GtkDragSource *source,
|
value_read (GObject *source,
|
||||||
GdkDrag *drag)
|
GAsyncResult *res,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
GtkWidget *canvas;
|
GdkClipboard *clipboard = GDK_CLIPBOARD (source);
|
||||||
CanvasItem *item;
|
GError *error = NULL;
|
||||||
GdkPaintable *paintable;
|
const GValue *value;
|
||||||
|
GtkDemoWidget *demo;
|
||||||
|
GtkWidget *widget = NULL;
|
||||||
|
|
||||||
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
value = gdk_clipboard_read_value_finish (clipboard, res, &error);
|
||||||
item = CANVAS_ITEM (g_object_get_data (G_OBJECT (canvas), "dragged-item"));
|
|
||||||
|
|
||||||
paintable = canvas_item_get_drag_icon (item);
|
if (value == NULL)
|
||||||
gtk_drag_source_set_icon (source, paintable, item->r, item->r);
|
{
|
||||||
g_object_unref (paintable);
|
g_print ("error: %s\n", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gtk_widget_set_opacity (GTK_WIDGET (item), 0.3);
|
if (!G_VALUE_HOLDS (value, GTK_TYPE_DEMO_WIDGET))
|
||||||
|
{
|
||||||
|
g_print ("can't handle clipboard contents\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
demo = g_value_get_boxed (value);
|
||||||
|
widget = deserialize_widget (demo);
|
||||||
|
|
||||||
|
gtk_fixed_put (GTK_FIXED (data), widget, pos_x, pos_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
drag_end (GtkDragSource *source,
|
paste_cb (GtkWidget *fixed)
|
||||||
GdkDrag *drag)
|
|
||||||
{
|
{
|
||||||
GtkWidget *canvas;
|
GdkClipboard *clipboard;
|
||||||
GtkWidget *item;
|
|
||||||
|
|
||||||
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
|
||||||
item = g_object_get_data (G_OBJECT (canvas), "dragged-item");
|
if (gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), GTK_TYPE_DEMO_WIDGET))
|
||||||
g_object_set_data (G_OBJECT (canvas), "dragged-item", NULL);
|
{
|
||||||
|
g_print ("Paste %s\n", g_type_name (GTK_TYPE_DEMO_WIDGET));
|
||||||
gtk_widget_set_opacity (item, 1.0);
|
gdk_clipboard_read_value_async (clipboard, GTK_TYPE_DEMO_WIDGET, 0, NULL, value_read, fixed);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
static gboolean
|
g_print ("Don't know how to handle clipboard contents\n");
|
||||||
drag_cancel (GtkDragSource *source,
|
|
||||||
GdkDrag *drag,
|
|
||||||
GdkDragCancelReason reason)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
drag_drop (GtkDropTarget *target,
|
|
||||||
const GValue *value,
|
|
||||||
double x,
|
|
||||||
double y)
|
|
||||||
{
|
|
||||||
CanvasItem *item;
|
|
||||||
GtkWidget *canvas;
|
|
||||||
GtkWidget *last_child;
|
|
||||||
|
|
||||||
item = g_value_get_object (value);
|
|
||||||
|
|
||||||
canvas = gtk_widget_get_parent (GTK_WIDGET (item));
|
|
||||||
last_child = gtk_widget_get_last_child (canvas);
|
|
||||||
if (GTK_WIDGET (item) != last_child)
|
|
||||||
gtk_widget_insert_after (GTK_WIDGET (item), canvas, last_child);
|
|
||||||
|
|
||||||
gtk_fixed_move (GTK_FIXED (canvas), GTK_WIDGET (item), x - item->r, y - item->r);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
new_item_cb (GtkWidget *button, gpointer data)
|
edit_label_done (GtkWidget *entry, gpointer data)
|
||||||
{
|
{
|
||||||
GtkWidget *canvas = data;
|
GtkWidget *fixed = gtk_widget_get_parent (entry);
|
||||||
GtkWidget *popover;
|
GtkWidget *label;
|
||||||
GtkWidget *item;
|
int x, y;
|
||||||
GdkRectangle rect;
|
|
||||||
|
|
||||||
popover = gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER);
|
gtk_container_child_get (GTK_CONTAINER (fixed), entry, "x", &x, "y", &y, NULL);
|
||||||
gtk_popover_get_pointing_to (GTK_POPOVER (popover), &rect);
|
|
||||||
|
|
||||||
item = canvas_item_new ();
|
label = GTK_WIDGET (g_object_get_data (G_OBJECT (entry), "label"));
|
||||||
gtk_fixed_put (GTK_FIXED (canvas), item, rect.x, rect.y);
|
gtk_label_set_text (GTK_LABEL (label), gtk_entry_get_text (GTK_ENTRY (entry)));
|
||||||
apply_transform (CANVAS_ITEM (item));
|
|
||||||
|
|
||||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
gtk_widget_destroy (entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
edit_cb (GtkWidget *button, GtkWidget *child)
|
edit_cb (GtkWidget *child)
|
||||||
{
|
{
|
||||||
CanvasItem *item = CANVAS_ITEM (child);
|
GtkWidget *fixed = gtk_widget_get_parent (child);
|
||||||
|
int x, y;
|
||||||
|
|
||||||
if (button)
|
gtk_container_child_get (GTK_CONTAINER (fixed), child, "x", &x, "y", &y, NULL);
|
||||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
|
||||||
|
|
||||||
if (!canvas_item_is_editing (item))
|
if (GTK_IS_LABEL (child))
|
||||||
canvas_item_start_editing (item);
|
{
|
||||||
}
|
GtkWidget *entry = gtk_entry_new ();
|
||||||
|
|
||||||
static void
|
g_object_set_data (G_OBJECT (entry), "label", child);
|
||||||
delete_cb (GtkWidget *button, GtkWidget *child)
|
|
||||||
{
|
|
||||||
GtkWidget *canvas = gtk_widget_get_parent (child);
|
|
||||||
|
|
||||||
gtk_fixed_remove (GTK_FIXED (canvas), child);
|
gtk_entry_set_text (GTK_ENTRY (entry), gtk_label_get_text (GTK_LABEL (child)));
|
||||||
|
g_signal_connect (entry, "activate", G_CALLBACK (edit_label_done), NULL);
|
||||||
|
gtk_fixed_put (GTK_FIXED (fixed), entry, x, y);
|
||||||
|
gtk_widget_grab_focus (entry);
|
||||||
|
}
|
||||||
|
else if (GTK_IS_SPINNER (child))
|
||||||
|
{
|
||||||
|
gboolean active;
|
||||||
|
|
||||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
g_object_get (child, "active", &active, NULL);
|
||||||
|
g_object_set (child, "active", !active, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -458,46 +243,69 @@ pressed_cb (GtkGesture *gesture,
|
|||||||
GtkWidget *child;
|
GtkWidget *child;
|
||||||
|
|
||||||
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||||
child = gtk_widget_pick (widget, x, y, GTK_PICK_DEFAULT);
|
child = gtk_widget_pick (widget, x, y);
|
||||||
child = gtk_widget_get_ancestor (child, canvas_item_get_type ());
|
|
||||||
|
|
||||||
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_SECONDARY)
|
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_SECONDARY)
|
||||||
{
|
{
|
||||||
|
GdkRectangle rect;
|
||||||
GtkWidget *menu;
|
GtkWidget *menu;
|
||||||
GtkWidget *box;
|
|
||||||
GtkWidget *item;
|
GtkWidget *item;
|
||||||
|
GdkClipboard *clipboard;
|
||||||
|
|
||||||
menu = gtk_popover_new ();
|
pos_x = x;
|
||||||
gtk_widget_set_parent (menu, widget);
|
pos_y = y;
|
||||||
gtk_popover_set_has_arrow (GTK_POPOVER (menu), FALSE);
|
|
||||||
gtk_popover_set_pointing_to (GTK_POPOVER (menu), &(GdkRectangle){ x, y, 1, 1});
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
|
||||||
gtk_popover_set_child (GTK_POPOVER (menu), box);
|
|
||||||
|
|
||||||
item = gtk_button_new_with_label ("New");
|
menu = gtk_menu_new ();
|
||||||
gtk_button_set_has_frame (GTK_BUTTON (item), FALSE);
|
item = gtk_menu_item_new_with_label ("New Label");
|
||||||
g_signal_connect (item, "clicked", G_CALLBACK (new_item_cb), widget);
|
g_signal_connect (item, "activate", G_CALLBACK (new_label_cb), widget);
|
||||||
gtk_box_append (GTK_BOX (box), item);
|
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||||
|
item = gtk_menu_item_new_with_label ("New Spinner");
|
||||||
|
g_signal_connect (item, "activate", G_CALLBACK (new_spinner_cb), widget);
|
||||||
|
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||||
|
|
||||||
item = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
|
item = gtk_separator_menu_item_new ();
|
||||||
gtk_box_append (GTK_BOX (box), item);
|
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||||
|
|
||||||
item = gtk_button_new_with_label ("Edit");
|
item = gtk_menu_item_new_with_label ("Edit");
|
||||||
gtk_button_set_has_frame (GTK_BUTTON (item), FALSE);
|
|
||||||
gtk_widget_set_sensitive (item, child != NULL && child != widget);
|
gtk_widget_set_sensitive (item, child != NULL && child != widget);
|
||||||
g_signal_connect (item, "clicked", G_CALLBACK (edit_cb), child);
|
g_signal_connect_swapped (item, "activate", G_CALLBACK (edit_cb), child);
|
||||||
gtk_box_append (GTK_BOX (box), item);
|
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||||
|
|
||||||
item = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
|
item = gtk_separator_menu_item_new ();
|
||||||
gtk_box_append (GTK_BOX (box), item);
|
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||||
|
|
||||||
item = gtk_button_new_with_label ("Delete");
|
item = gtk_menu_item_new_with_label ("Cut");
|
||||||
gtk_button_set_has_frame (GTK_BUTTON (item), FALSE);
|
|
||||||
gtk_widget_set_sensitive (item, child != NULL && child != widget);
|
gtk_widget_set_sensitive (item, child != NULL && child != widget);
|
||||||
g_signal_connect (item, "clicked", G_CALLBACK (delete_cb), child);
|
g_signal_connect_swapped (item, "activate", G_CALLBACK (cut_cb), child);
|
||||||
gtk_box_append (GTK_BOX (box), item);
|
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||||
|
item = gtk_menu_item_new_with_label ("Copy");
|
||||||
|
gtk_widget_set_sensitive (item, child != NULL && child != widget);
|
||||||
|
g_signal_connect_swapped (item, "activate", G_CALLBACK (copy_cb), child);
|
||||||
|
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||||
|
item = gtk_menu_item_new_with_label ("Paste");
|
||||||
|
clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
|
||||||
|
gtk_widget_set_sensitive (item,
|
||||||
|
gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), GTK_TYPE_DEMO_WIDGET));
|
||||||
|
g_signal_connect_swapped (item, "activate", G_CALLBACK (paste_cb), widget);
|
||||||
|
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||||
|
item = gtk_menu_item_new_with_label ("Delete");
|
||||||
|
gtk_widget_set_sensitive (item, child != NULL && child != widget);
|
||||||
|
g_signal_connect_swapped (item, "activate", G_CALLBACK (delete_cb), child);
|
||||||
|
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||||
|
|
||||||
gtk_popover_popup (GTK_POPOVER (menu));
|
rect.x = x;
|
||||||
|
rect.y = y;
|
||||||
|
rect.width = 0;
|
||||||
|
rect.height = 0;
|
||||||
|
|
||||||
|
gtk_menu_popup_at_rect (GTK_MENU (menu),
|
||||||
|
gtk_widget_get_surface (widget),
|
||||||
|
&rect,
|
||||||
|
GDK_GRAVITY_NORTH_WEST,
|
||||||
|
GDK_GRAVITY_NORTH_WEST,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,170 +318,17 @@ released_cb (GtkGesture *gesture,
|
|||||||
{
|
{
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
GtkWidget *child;
|
GtkWidget *child;
|
||||||
CanvasItem *item;
|
|
||||||
|
|
||||||
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||||
child = gtk_widget_pick (widget, x, y, 0);
|
child = gtk_widget_pick (widget, x, y);
|
||||||
item = (CanvasItem *)gtk_widget_get_ancestor (child, canvas_item_get_type ());
|
|
||||||
if (!item)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_PRIMARY)
|
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_PRIMARY)
|
||||||
{
|
{
|
||||||
if (canvas_item_is_editing (item))
|
if (child != NULL && child != widget)
|
||||||
canvas_item_stop_editing (item);
|
edit_cb (child);
|
||||||
else
|
|
||||||
canvas_item_start_editing (item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkWidget *
|
|
||||||
canvas_new (void)
|
|
||||||
{
|
|
||||||
GtkWidget *canvas;
|
|
||||||
GtkDragSource *source;
|
|
||||||
GtkDropTarget *dest;
|
|
||||||
GtkGesture *gesture;
|
|
||||||
|
|
||||||
canvas = gtk_fixed_new ();
|
|
||||||
gtk_widget_set_hexpand (canvas, TRUE);
|
|
||||||
gtk_widget_set_vexpand (canvas, TRUE);
|
|
||||||
gtk_widget_add_css_class (canvas, "frame");
|
|
||||||
|
|
||||||
source = gtk_drag_source_new ();
|
|
||||||
gtk_drag_source_set_actions (source, GDK_ACTION_MOVE);
|
|
||||||
g_signal_connect (source, "prepare", G_CALLBACK (prepare), NULL);
|
|
||||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), NULL);
|
|
||||||
g_signal_connect (source, "drag-end", G_CALLBACK (drag_end), NULL);
|
|
||||||
g_signal_connect (source, "drag-cancel", G_CALLBACK (drag_cancel), NULL);
|
|
||||||
gtk_widget_add_controller (canvas, GTK_EVENT_CONTROLLER (source));
|
|
||||||
|
|
||||||
dest = gtk_drop_target_new (GTK_TYPE_WIDGET, GDK_ACTION_MOVE);
|
|
||||||
g_signal_connect (dest, "drop", G_CALLBACK (drag_drop), NULL);
|
|
||||||
gtk_widget_add_controller (canvas, GTK_EVENT_CONTROLLER (dest));
|
|
||||||
|
|
||||||
gesture = gtk_gesture_click_new ();
|
|
||||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), 0);
|
|
||||||
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), NULL);
|
|
||||||
g_signal_connect (gesture, "released", G_CALLBACK (released_cb), NULL);
|
|
||||||
gtk_widget_add_controller (canvas, GTK_EVENT_CONTROLLER (gesture));
|
|
||||||
|
|
||||||
return canvas;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GdkContentProvider *
|
|
||||||
css_drag_prepare (GtkDragSource *source,
|
|
||||||
double x,
|
|
||||||
double y,
|
|
||||||
GtkWidget *button)
|
|
||||||
{
|
|
||||||
const char *class;
|
|
||||||
GdkPaintable *paintable;
|
|
||||||
|
|
||||||
class = (const char *)g_object_get_data (G_OBJECT (button), "css-class");
|
|
||||||
|
|
||||||
paintable = gtk_widget_paintable_new (button);
|
|
||||||
gtk_drag_source_set_icon (source, paintable, 0, 0);
|
|
||||||
g_object_unref (paintable);
|
|
||||||
|
|
||||||
return gdk_content_provider_new_typed (G_TYPE_STRING, class);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GtkWidget *
|
|
||||||
css_button_new (const char *class)
|
|
||||||
{
|
|
||||||
GtkWidget *button;
|
|
||||||
GtkDragSource *source;
|
|
||||||
|
|
||||||
button = gtk_image_new ();
|
|
||||||
gtk_widget_set_size_request (button, 48, 32);
|
|
||||||
gtk_widget_add_css_class (button, class);
|
|
||||||
g_object_set_data (G_OBJECT (button), "css-class", (gpointer)class);
|
|
||||||
|
|
||||||
source = gtk_drag_source_new ();
|
|
||||||
g_signal_connect (source, "prepare", G_CALLBACK (css_drag_prepare), button);
|
|
||||||
gtk_widget_add_controller (button, GTK_EVENT_CONTROLLER (source));
|
|
||||||
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GtkWidget parent_instance;
|
|
||||||
GdkRGBA color;
|
|
||||||
} ColorSwatch;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GtkWidgetClass parent_class;
|
|
||||||
} ColorSwatchClass;
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (ColorSwatch, color_swatch, GTK_TYPE_WIDGET)
|
|
||||||
|
|
||||||
static GdkContentProvider *
|
|
||||||
color_swatch_drag_prepare (GtkDragSource *source,
|
|
||||||
double x,
|
|
||||||
double y,
|
|
||||||
ColorSwatch *swatch)
|
|
||||||
{
|
|
||||||
return gdk_content_provider_new_typed (GDK_TYPE_RGBA, &swatch->color);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
color_swatch_init (ColorSwatch *swatch)
|
|
||||||
{
|
|
||||||
GtkDragSource *source = gtk_drag_source_new ();
|
|
||||||
g_signal_connect (source, "prepare", G_CALLBACK (color_swatch_drag_prepare), swatch);
|
|
||||||
gtk_widget_add_controller (GTK_WIDGET (swatch), GTK_EVENT_CONTROLLER (source));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
color_swatch_snapshot (GtkWidget *widget,
|
|
||||||
GtkSnapshot *snapshot)
|
|
||||||
{
|
|
||||||
ColorSwatch *swatch = (ColorSwatch *)widget;
|
|
||||||
float w = gtk_widget_get_width (widget);
|
|
||||||
float h = gtk_widget_get_height (widget);
|
|
||||||
|
|
||||||
gtk_snapshot_append_color (snapshot, &swatch->color,
|
|
||||||
&GRAPHENE_RECT_INIT(0, 0, w, h));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
color_swatch_measure (GtkWidget *widget,
|
|
||||||
GtkOrientation orientation,
|
|
||||||
int for_size,
|
|
||||||
int *minimum_size,
|
|
||||||
int *natural_size,
|
|
||||||
int *minimum_baseline,
|
|
||||||
int *natural_baseline)
|
|
||||||
{
|
|
||||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
|
||||||
*minimum_size = *natural_size = 48;
|
|
||||||
else
|
|
||||||
*minimum_size = *natural_size = 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
color_swatch_class_init (ColorSwatchClass *class)
|
|
||||||
{
|
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
|
||||||
|
|
||||||
widget_class->snapshot = color_swatch_snapshot;
|
|
||||||
widget_class->measure = color_swatch_measure;
|
|
||||||
gtk_widget_class_set_css_name (widget_class, "colorswatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
static GtkWidget *
|
|
||||||
color_swatch_new (const char *color)
|
|
||||||
{
|
|
||||||
ColorSwatch *swatch = g_object_new (color_swatch_get_type (), NULL);
|
|
||||||
|
|
||||||
gdk_rgba_parse (&swatch->color, color);
|
|
||||||
|
|
||||||
return GTK_WIDGET (swatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GtkWidget *window = NULL;
|
static GtkWidget *window = NULL;
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
@@ -681,83 +336,43 @@ do_dnd (GtkWidget *do_widget)
|
|||||||
{
|
{
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
GtkWidget *button;
|
GtkWidget *vbox, *fixed;
|
||||||
GtkWidget *sw;
|
GtkGesture *multipress;
|
||||||
GtkWidget *canvas;
|
|
||||||
GtkWidget *box, *box2, *box3;
|
|
||||||
const char *colors[] = {
|
|
||||||
"red", "green", "blue", "magenta", "orange", "gray", "black", "yellow",
|
|
||||||
"white", "gray", "brown", "pink", "cyan", "bisque", "gold", "maroon",
|
|
||||||
"navy", "orchid", "olive", "peru", "salmon", "silver", "wheat",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
int i;
|
|
||||||
int x, y;
|
|
||||||
GtkCssProvider *provider;
|
GtkCssProvider *provider;
|
||||||
|
|
||||||
button = gtk_color_button_new ();
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
g_object_unref (g_object_ref_sink (button));
|
gtk_window_set_display (GTK_WINDOW (window),
|
||||||
|
gtk_widget_get_display (do_widget));
|
||||||
|
gtk_window_set_title (GTK_WINDOW (window), "Drag-and-drop");
|
||||||
|
|
||||||
|
g_signal_connect (window, "destroy",
|
||||||
|
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||||
|
|
||||||
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||||
|
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||||
|
|
||||||
|
fixed = gtk_fixed_new ();
|
||||||
|
gtk_box_pack_start (GTK_BOX (vbox), fixed);
|
||||||
|
gtk_widget_set_hexpand (fixed, TRUE);
|
||||||
|
gtk_widget_set_vexpand (fixed, TRUE);
|
||||||
|
|
||||||
|
multipress = gtk_gesture_multi_press_new ();
|
||||||
|
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (multipress), 0);
|
||||||
|
g_signal_connect (multipress, "pressed", G_CALLBACK (pressed_cb), NULL);
|
||||||
|
g_signal_connect (multipress, "released", G_CALLBACK (released_cb), NULL);
|
||||||
|
gtk_widget_add_controller (fixed, GTK_EVENT_CONTROLLER (multipress));
|
||||||
|
|
||||||
provider = gtk_css_provider_new ();
|
provider = gtk_css_provider_new ();
|
||||||
gtk_css_provider_load_from_resource (provider, "/dnd/dnd.css");
|
gtk_css_provider_load_from_resource (provider, "/dnd/dnd.css");
|
||||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||||
GTK_STYLE_PROVIDER (provider),
|
GTK_STYLE_PROVIDER (provider),
|
||||||
800);
|
800);
|
||||||
g_object_unref (provider);
|
|
||||||
|
|
||||||
window = gtk_window_new ();
|
|
||||||
gtk_window_set_display (GTK_WINDOW (window),
|
|
||||||
gtk_widget_get_display (do_widget));
|
|
||||||
gtk_window_set_title (GTK_WINDOW (window), "Drag-and-Drop");
|
|
||||||
gtk_window_set_default_size (GTK_WINDOW (window), 640, 480);
|
|
||||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
|
||||||
|
|
||||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
|
||||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
|
||||||
|
|
||||||
box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
||||||
gtk_box_append (GTK_BOX (box), box2);
|
|
||||||
|
|
||||||
canvas = canvas_new ();
|
|
||||||
gtk_box_append (GTK_BOX (box2), canvas);
|
|
||||||
|
|
||||||
n_items = 0;
|
|
||||||
|
|
||||||
x = y = 40;
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
GtkWidget *item;
|
|
||||||
|
|
||||||
item = canvas_item_new ();
|
|
||||||
gtk_fixed_put (GTK_FIXED (canvas), item, x, y);
|
|
||||||
apply_transform (CANVAS_ITEM (item));
|
|
||||||
|
|
||||||
x += 150;
|
|
||||||
y += 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
sw = gtk_scrolled_window_new ();
|
|
||||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
|
||||||
GTK_POLICY_AUTOMATIC,
|
|
||||||
GTK_POLICY_NEVER);
|
|
||||||
gtk_box_append (GTK_BOX (box), sw);
|
|
||||||
|
|
||||||
box3 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
|
||||||
gtk_widget_add_css_class (box3, "linked");
|
|
||||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), box3);
|
|
||||||
|
|
||||||
for (i = 0; colors[i]; i++)
|
|
||||||
gtk_box_append (GTK_BOX (box3), color_swatch_new (colors[i]));
|
|
||||||
|
|
||||||
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow1"));
|
|
||||||
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow2"));
|
|
||||||
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow3"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gtk_widget_get_visible (window))
|
if (!gtk_widget_get_visible (window))
|
||||||
gtk_widget_show (window);
|
gtk_widget_show (window);
|
||||||
else
|
else
|
||||||
gtk_window_destroy (GTK_WINDOW (window));
|
gtk_widget_destroy (window);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,3 @@
|
|||||||
label.canvasitem {
|
spinner.demo {
|
||||||
padding: 10px;
|
opacity: 1;
|
||||||
margin: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasitem.rainbow1,
|
|
||||||
image.rainbow1 {
|
|
||||||
background: linear-gradient(140deg,red,orange,yellow,green,blue,purple);
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasitem.rainbow2,
|
|
||||||
image.rainbow2 {
|
|
||||||
animation: rainbow2 1s infinite linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rainbow2 {
|
|
||||||
0% { background: linear-gradient(0deg,red,orange,yellow,green,blue,purple); }
|
|
||||||
25% { background: linear-gradient(90deg,red,orange,yellow,green,blue,purple); }
|
|
||||||
50% { background: linear-gradient(180deg,red,orange,yellow,green,blue,purple); }
|
|
||||||
75% { background: linear-gradient(270deg,red,orange,yellow,green,blue,purple); }
|
|
||||||
100% { background: linear-gradient(360deg,red,orange,yellow,green,blue,purple); }
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasitem.rainbow3,
|
|
||||||
image.rainbow3 {
|
|
||||||
animation: rainbow3 1s infinite linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rainbow3 {
|
|
||||||
0% { background: linear-gradient(140deg,red,orange,yellow,green,blue,purple); }
|
|
||||||
16.6% { background: linear-gradient(140deg,purple,red,orange,yellow,green,blue); }
|
|
||||||
33.2% { background: linear-gradient(140deg,blue,purple,red,orange,yellow,green); }
|
|
||||||
50% { background: linear-gradient(140deg,green,blue,purple,red,orange,yellow); }
|
|
||||||
66.6% { background: linear-gradient(140deg,yellow,green,blue,purple,red,orange); }
|
|
||||||
83.2% { background: linear-gradient(140deg,orange,yellow,green,blue,purple,red); }
|
|
||||||
100% { background: linear-gradient(140deg,red,orange,yellow,green,blue,purple); }
|
|
||||||
}
|
}
|
||||||
|
|||||||