Compare commits

..

8 Commits

Author SHA1 Message Date
Matthias Clasen
abcf2e3bf7 node-editor: Don't use the ::query-tooltip signal
Use the vfunc, the signal is going away.
2020-05-09 23:24:59 -04:00
Matthias Clasen
a123d99fcd inspector: Don't use the ::query-tooltip signal
Use the vfunc, the signal is going away.
2020-05-09 22:49:55 -04:00
Matthias Clasen
4f760a9a2a volumebutton: Don't use the ::query-tooltip signal
Use the vfunc, the signal is going away.
2020-05-09 22:31:00 -04:00
Matthias Clasen
7e6be71d38 volumebutton: Enable the tooltips
Little point in having a query-tooltip handler if
we don't make sure ::query-tooltip is emitted.
2020-05-09 22:31:00 -04:00
Matthias Clasen
ed46982cc5 volumebutton: Remove broken a11y code
The accessible of a button is not an AtkImage,
so whatever this code was trying to do isn't
working. Remove it.
2020-05-09 22:30:59 -04:00
Matthias Clasen
e92270f928 iconview: Stop using the ::query-tooltip signal
Use the vfunc instead. The signal is going away.
2020-05-09 22:30:59 -04:00
Matthias Clasen
79a96b9bef treeview: Don't use the ::query-tooltip signal
Use the vfunc instead.
2020-05-09 22:30:59 -04:00
Matthias Clasen
ff55264e60 linkbutton: Don't use the ::query-tooltip signal
As a subclass, GtkLinkButton should override the
vfunc. The signal will be going away.
2020-05-09 22:30:59 -04:00
1886 changed files with 113172 additions and 255517 deletions

View File

@@ -17,12 +17,7 @@ stages:
# Common variables # Common variables
variables: variables:
COMMON_MESON_FLAGS: "--fatal-meson-warnings --werror" COMMON_MESON_FLAGS: "--fatal-meson-warnings --werror"
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true -Dvulkan=yes" MESON_TEST_TIMEOUT_MULTIPLIER: 2
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-default:
only: only:
@@ -32,65 +27,76 @@ variables:
style-check-diff: style-check-diff:
extends: .only-default extends: .only-default
image: $FEDORA_IMAGE image: registry.gitlab.gnome.org/gnome/gtk/fedora:v16
stage: .pre stage: .pre
allow_failure: true allow_failure: true
script: script:
- .gitlab-ci/run-style-check-diff.sh - .gitlab-ci/run-style-check-diff.sh
.build-fedora-default:
image: $FEDORA_IMAGE
artifacts:
when: always
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}"
paths:
- "${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:
key: "$CI_JOB_NAME"
paths:
- _ccache/
- subprojects/gdk-pixbuf/
- subprojects/glib/
- subprojects/graphene/
- subprojects/libepoxy/
- subprojects/pango/
fedora-x86_64: fedora-x86_64:
extends: .build-fedora-default image: registry.gitlab.gnome.org/gnome/gtk/fedora:v16
stage: build stage: build
variables: variables:
EXTRA_MESON_FLAGS: "--buildtype=debug --default-library=both" EXTRA_MESON_FLAGS: "--buildtype=debug --default-library=both"
script: script:
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS} - meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS}
-Dx11-backend=true
-Dwayland-backend=true
-Dbroadway-backend=true
-Dvulkan=yes
-Dprofiler=true -Dprofiler=true
_build _build
- ninja -C _build - ninja -C _build
- .gitlab-ci/run-tests.sh _build x11 - .gitlab-ci/run-tests.sh _build
- .gitlab-ci/run-tests.sh _build wayland artifacts:
- .gitlab-ci/run-tests.sh _build broadway when: always
reports:
junit:
- "${CI_PROJECT_DIR}/_build/report.xml"
name: "gtk-${CI_COMMIT_REF_NAME}"
paths:
- "${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:
key: "$CI_JOB_NAME"
<<: *cache-paths
release-build: release-build:
extends: .build-fedora-default image: registry.gitlab.gnome.org/gnome/gtk/fedora:v16
stage: build stage: build
variables: variables:
EXTRA_MESON_FLAGS: "--buildtype=release" EXTRA_MESON_FLAGS: "--buildtype=release"
script: script:
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS} - meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS}
-Dx11-backend=true
-Dwayland-backend=true
-Dbroadway-backend=true
-Dvulkan=yes
_build _build
- ninja -C _build - ninja -C _build
- .gitlab-ci/run-tests.sh _build x11 - .gitlab-ci/run-tests.sh _build
artifacts:
when: always
reports:
junit:
- "${CI_PROJECT_DIR}/_build/report.xml"
name: "gtk-${CI_COMMIT_REF_NAME}"
paths:
- "${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:
key: "$CI_JOB_NAME"
<<: *cache-paths
.mingw-defaults: .mingw-defaults: &mingw-defaults
stage: build stage: build
tags: tags:
- win32-ps - win32-ps
@@ -99,22 +105,16 @@ release-build:
- 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 allow_failure: true
tags: tags:
@@ -127,48 +127,48 @@ msys2-mingw64:
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}" - bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
# Manual jobs, for branches and MRs # Manual jobs, for branches and MRs
.flatpak-manual: .flatpak-manual: &flatpak-manual
extends: .flatpak-defaults <<: *flatpak-defaults
when: manual when: manual
# Only build Flatpak bundles automatically on master # Only build Flatpak bundles automatically on master
.flatpak-master: .flatpak-master: &flatpak-master
extends: .flatpak-defaults <<: *flatpak-defaults
only: only:
- master - master
flatpak-manual:demo: flatpak-manual:demo:
extends: .flatpak-manual
variables: variables:
APPID: org.gtk.Demo4 APPID: org.gtk.Demo4
<<: *flatpak-manual
flatpak-master:demo: flatpak-master:demo:
extends: .flatpak-master
variables: variables:
APPID: org.gtk.Demo4 APPID: org.gtk.Demo4
<<: *flatpak-master
flatpak-manual:widget-factory: flatpak-manual:widget-factory:
extends: .flatpak-manual
variables: variables:
APPID: org.gtk.WidgetFactory4 APPID: org.gtk.WidgetFactory4
<<: *flatpak-manual
flatpak-master:widget-factory: flatpak-master:widget-factory:
extends: .flatpak-master
variables: variables:
APPID: org.gtk.WidgetFactory4 APPID: org.gtk.WidgetFactory4
<<: *flatpak-master
flatpak-manual:icon-browser: flatpak-manual:icon-browser:
extends: .flatpak-manual
variables: variables:
APPID: org.gtk.IconBrowser4 APPID: org.gtk.IconBrowser4
<<: *flatpak-manual
flatpak-master:icon-browser: flatpak-master:icon-browser:
extends: .flatpak-master
variables: variables:
APPID: org.gtk.IconBrowser4 APPID: org.gtk.IconBrowser4
<<: *flatpak-master
static-scan: static-scan:
image: $FEDORA_IMAGE image: registry.gitlab.gnome.org/gnome/gtk/fedora:v16
stage: analysis stage: analysis
variables: variables:
EXTRA_MESON_FLAGS: "--buildtype=debug" EXTRA_MESON_FLAGS: "--buildtype=debug"
@@ -180,24 +180,8 @@ static-scan:
- _scan_build/meson-logs - _scan_build/meson-logs
allow_failure: true allow_failure: true
# Run tests with the address sanitizer. We need to turn off introspection,
# 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: reference:
image: $DOCS_IMAGE image: registry.gitlab.gnome.org/gnome/gtk/fedora:v16
stage: docs stage: docs
variables: variables:
EXTRA_MESON_FLAGS: "--buildtype=release" EXTRA_MESON_FLAGS: "--buildtype=release"

View File

View File

@@ -35,13 +35,4 @@ branch, as well as their available versions.
- [ ] Add the new job to `.gitlab-ci.yml` referencing the image - [ ] Add the new job to `.gitlab-ci.yml` referencing the image
- [ ] Open a merge request with your changes and let it run - [ ] 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 [registry]: https://gitlab.gnome.org/GNOME/gtk/container_registry

View File

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

View File

@@ -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

View File

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

View File

@@ -138,13 +138,12 @@ ul.images li {
</head> </head>
<body> <body>
<header> <header>
<h1>{{ report.project_name }}/{{ report.backend }}/{{ report.branch_name }} :: Test Reports</h1> <h1>{{ report.project_name }}/{{ report.branch_name }} :: Test Reports</h1>
</header> </header>
<article> <article>
<section> <section>
<div class="report-meta"> <div class="report-meta">
<p><strong>Backend:</strong> {{ report.backend }}</p>
<p><strong>Branch:</strong> {{ report.branch_name }}</p> <p><strong>Branch:</strong> {{ report.branch_name }}</p>
<p><strong>Date:</strong> <time datetime="{{ report.date.isoformat() }}">{{ report.locale_date }}</time></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 %} {% if report.job_id %}<p><strong>Job ID:</strong> {{ report.job_id }}</p>{% endif %}
@@ -260,9 +259,6 @@ aparser = argparse.ArgumentParser(description='Turns a Meson test log into an HT
aparser.add_argument('--project-name', metavar='NAME', aparser.add_argument('--project-name', metavar='NAME',
help='The project name', help='The project name',
default='Unknown') default='Unknown')
aparser.add_argument('--backend', metavar='NAME',
help='The used backend',
default='unknown')
aparser.add_argument('--job-id', metavar='ID', aparser.add_argument('--job-id', metavar='ID',
help='The job ID for the report', help='The job ID for the report',
default=None) default=None)
@@ -323,7 +319,6 @@ report = {}
report['date'] = datetime.datetime.utcnow() report['date'] = datetime.datetime.utcnow()
report['locale_date'] = report['date'].strftime("%c") report['locale_date'] = report['date'].strftime("%c")
report['project_name'] = args.project_name report['project_name'] = args.project_name
report['backend'] = args.backend
report['job_id'] = args.job_id report['job_id'] = args.job_id
report['branch_name'] = args.branch report['branch_name'] = args.branch
report['total_successes'] = 0 report['total_successes'] = 0

View File

@@ -19,9 +19,6 @@ aparser = argparse.ArgumentParser(description='Turns a Meson test log into a JUn
aparser.add_argument('--project-name', metavar='NAME', aparser.add_argument('--project-name', metavar='NAME',
help='The project name', help='The project name',
default='unknown') default='unknown')
aparser.add_argument('--backend', metavar='NAME',
help='The used backend',
default='unknown')
aparser.add_argument('--job-id', metavar='ID', aparser.add_argument('--job-id', metavar='ID',
help='The job ID for the report', help='The job ID for the report',
default='Unknown') default='Unknown')
@@ -95,18 +92,18 @@ for name, units in suites.items():
for unit in successes: for unit in successes:
testcase = ET.SubElement(testsuite, 'testcase') testcase = ET.SubElement(testsuite, 'testcase')
testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite'])) testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
testcase.set('name', '{}/{}'.format(args.backend, unit['name'])) testcase.set('name', unit['name'])
testcase.set('time', str(unit['duration'])) testcase.set('time', str(unit['duration']))
for unit in failures: for unit in failures:
testcase = ET.SubElement(testsuite, 'testcase') testcase = ET.SubElement(testsuite, 'testcase')
testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite'])) testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
testcase.set('name', '{}/{}'.format(args.backend, unit['name'])) testcase.set('name', unit['name'])
testcase.set('time', str(unit['duration'])) testcase.set('time', str(unit['duration']))
failure = ET.SubElement(testcase, 'failure') failure = ET.SubElement(testcase, 'failure')
failure.set('classname', '{}/{}'.format(args.project_name, unit['suite'])) failure.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
testcase.set('name', '{}/{}'.format(args.backend, unit['name'])) failure.set('name', unit['name'])
failure.set('type', 'error') failure.set('type', 'error')
failure.text = unit['stdout'] failure.text = unit['stdout']

View File

@@ -81,7 +81,7 @@ fi
if [ -z $base_version ]; then if [ -z $base_version ]; then
base_version="latest" base_version="latest"
elif [ $base_version != "latest" ]; then else
base_version="v$base_version" base_version="v$base_version"
fi fi
@@ -95,7 +95,7 @@ if [ ! -x "$(command -v docker)" ] || [ docker --help |& grep -q podman ]; then
else else
echo "Using: Docker" echo "Using: Docker"
format="" format=""
CMD="sudo docker" CMD="sudo socker"
fi fi
REGISTRY="registry.gitlab.gnome.org" REGISTRY="registry.gitlab.gnome.org"

View File

@@ -4,15 +4,8 @@ set -e
# We need to add a new remote for the upstream master, since this script could # 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. # be running in a personal fork of the repository which has out of date branches.
if [ "${CI_PROJECT_NAMESPACE}" != "GNOME" ]; then git remote add upstream https://gitlab.gnome.org/GNOME/gtk.git
echo "Retrieving the current upstream repository from ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}..." git fetch upstream
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 # 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 # has checked out, and the upstream target branch (which will typically be
@@ -20,7 +13,7 @@ fi
# #
# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` is only defined if were running in # `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` is only defined if were running in
# a merge request pipeline; fall back to `${CI_DEFAULT_BRANCH}` otherwise. # 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) newest_common_ancestor_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "upstream/${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 git diff -U0 --no-color "${newest_common_ancestor_sha}" | .gitlab-ci/clang-format-diff.py -binary "clang-format" -p1
exit_status=$? exit_status=$?

View File

@@ -5,81 +5,30 @@ set +e
srcdir=$( pwd ) srcdir=$( pwd )
builddir=$1 builddir=$1
backend=$2
# Ignore memory leaks lower in dependencies export GDK_BACKEND=x11
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp xvfb-run -a -s "-screen 0 1024x768x24" \
meson test -C ${builddir} \
case "${backend}" in
x11)
xvfb-run -a -s "-screen 0 1024x768x24" \
meson test -C ${builddir} \
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
--print-errorlogs \ --print-errorlogs \
--setup=${backend} \
--suite=gtk \ --suite=gtk \
--no-suite=gtk:a11y \ --no-suite=gtk:a11y
--no-suite=gsk-compare-broadway
# Store the exit code for the CI run, but always # Store the exit code for the CI run, but always
# generate the reports # generate the reports
exit_code=$? 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} cd ${builddir}
$srcdir/.gitlab-ci/meson-junit-report.py \ $srcdir/.gitlab-ci/meson-junit-report.py \
--project-name=gtk \ --project-name=gtk \
--backend=${backend} \
--job-id="${CI_JOB_NAME}" \ --job-id="${CI_JOB_NAME}" \
--output=report-${backend}.xml \ --output=report.xml \
meson-logs/testlog-${backend}.json meson-logs/testlog.json
$srcdir/.gitlab-ci/meson-html-report.py \ $srcdir/.gitlab-ci/meson-html-report.py \
--project-name=gtk \ --project-name=gtk \
--backend=${backend} \
--job-id="${CI_JOB_NAME}" \ --job-id="${CI_JOB_NAME}" \
--reftest-output-dir="testsuite/reftests/output/${backend}" \ --reftest-output-dir="testsuite/reftests/output" \
--output=report-${backend}.html \ --output=report.html \
meson-logs/testlog-${backend}.json meson-logs/testlog.json
exit $exit_code exit $exit_code

View File

@@ -34,11 +34,8 @@ pacman --noconfirm -S --needed \
mingw-w64-$MSYS2_ARCH-shared-mime-info mingw-w64-$MSYS2_ARCH-shared-mime-info
# https://gitlab.gnome.org/GNOME/gtk/issues/2243 # 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" wget "https://gitlab.gnome.org/creiter/gitlab-ci-win32-runner-v2/raw/master/pango/mingw-w64-$MSYS2_ARCH-pango-1.44.7-1-any.pkg.tar.xz"
pacman --noconfirm -U "mingw-w64-$MSYS2_ARCH-pango-git-1.44.7.90.ge48ae523-1-any.pkg.tar.zst" pacman --noconfirm -U "mingw-w64-$MSYS2_ARCH-pango-1.44.7-1-any.pkg.tar.xz"
# 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)"

264
NEWS
View File

@@ -1,267 +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 Overview of Changes in GTK 3.98.3
================================= =================================

View File

@@ -1,38 +1,29 @@
{ {
"app-id" : "org.gtk.WidgetFactory4", "app-id": "org.gtk.WidgetFactory4",
"runtime" : "org.gnome.Platform", "runtime": "org.gnome.Platform",
"runtime-version" : "master", "runtime-version": "master",
"sdk" : "org.gnome.Sdk", "sdk": "org.gnome.Sdk",
"command" : "gtk4-widget-factory", "command": "gtk4-widget-factory",
"tags" : [ "tags": ["devel", "development", "nightly"],
"devel", "desktop-file-name-prefix": "(Development) ",
"development", "finish-args": [
"nightly"
],
"desktop-file-name-prefix" : "(Development) ",
"finish-args" : [
"--device=dri", "--device=dri",
"--share=ipc", "--share=ipc",
"--socket=fallback-x11", "--socket=fallback-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.*"
], ],
"cleanup" : [ "cleanup": [
"/include", "/include",
"/lib/pkgconfig", "/lib/pkgconfig", "/share/pkgconfig",
"/share/pkgconfig",
"/share/aclocal", "/share/aclocal",
"/man", "/man", "/share/man", "/share/gtk-doc",
"/share/man", "*.la", ".a",
"/share/gtk-doc",
"*.la",
".a",
"/lib/girepository-1.0", "/lib/girepository-1.0",
"/share/gir-1.0", "/share/gir-1.0",
"/share/doc" "/share/doc"
], ],
"modules" : [ "modules": [
{ {
"name" : "wayland", "name" : "wayland",
"buildsystem" : "autotools", "buildsystem" : "autotools",
@@ -48,18 +39,18 @@
] ]
}, },
{ {
"name" : "graphene", "name": "graphene",
"buildsystem" : "meson", "buildsystem": "meson",
"builddir" : true, "builddir": true,
"config-opts" : [ "config-opts": [
"--libdir=/app/lib", "--libdir=/app/lib",
"-Dtests=false", "-Dtests=false",
"-Dbenchmarks=false" "-Dbenchmarks=false"
], ],
"sources" : [ "sources": [
{ {
"type" : "git", "type": "git",
"url" : "https://github.com/ebassi/graphene.git" "url": "https://github.com/ebassi/graphene.git"
} }
] ]
}, },
@@ -67,7 +58,7 @@
"name" : "libsass", "name" : "libsass",
"buildsystem" : "meson", "buildsystem" : "meson",
"builddir" : true, "builddir" : true,
"config-opts" : [ "config-opts": [
"--libdir=/app/lib" "--libdir=/app/lib"
], ],
"sources" : [ "sources" : [
@@ -82,7 +73,7 @@
"name" : "sassc", "name" : "sassc",
"buildsystem" : "meson", "buildsystem" : "meson",
"builddir" : true, "builddir" : true,
"config-opts" : [ "config-opts": [
"--libdir=/app/lib" "--libdir=/app/lib"
], ],
"sources" : [ "sources" : [
@@ -94,23 +85,18 @@
] ]
}, },
{ {
"name" : "gtk", "name": "gtk",
"buildsystem" : "meson", "buildsystem": "meson",
"builddir" : true, "builddir": true,
"config-opts" : [ "config-opts": [
"--libdir=/app/lib" "--libdir=/app/lib"
], ],
"sources" : [ "sources": [
{ {
"type" : "git", "type": "git",
"url" : "https://gitlab.gnome.org/GNOME/gtk.git" "url": "https://gitlab.gnome.org/GNOME/gtk.git"
} }
] ]
} }
], ]
"build-options" : {
"env" : {
"DBUS_SESSION_BUS_ADDRESS" : "''"
}
}
} }

View File

@@ -15,13 +15,7 @@ if 'DESTDIR' not in os.environ:
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules') gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
print('Compiling GSettings schemas...') print('Compiling GSettings schemas...')
glib_compile_schemas = subprocess.check_output(['pkg-config', subprocess.call(['glib-compile-schemas',
'--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')]) os.path.join(gtk_datadir, 'glib-2.0', 'schemas')])
print('Updating icon cache...') print('Updating icon cache...')
@@ -30,14 +24,8 @@ if 'DESTDIR' not in os.environ:
print('Updating module cache for print backends...') print('Updating module cache for print backends...')
os.makedirs(gtk_printmodule_dir, exist_ok=True) os.makedirs(gtk_printmodule_dir, exist_ok=True)
gio_querymodules = subprocess.check_output(['pkg-config', subprocess.call(['gio-querymodules', gtk_printmodule_dir])
'--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...') print('Updating module cache for input methods...')
os.makedirs(gtk_immodule_dir, exist_ok=True) os.makedirs(gtk_immodule_dir, exist_ok=True)
subprocess.call([gio_querymodules, gtk_immodule_dir]) subprocess.call(['gio-querymodules', gtk_immodule_dir])

View File

@@ -27,6 +27,14 @@
/* 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
@@ -72,6 +80,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 +92,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
@@ -272,6 +295,3 @@
#mesondefine HAVE_PANGOFT #mesondefine HAVE_PANGOFT
#mesondefine ISO_CODES_PREFIX #mesondefine ISO_CODES_PREFIX
/* Define if tracker3 is available */
#mesondefine HAVE_TRACKER3

View File

@@ -81,11 +81,11 @@ constraint_editor_application_activate (GApplication *app)
static void static void
constraint_editor_application_open (GApplication *app, constraint_editor_application_open (GApplication *app,
GFile **files, GFile **files,
int n_files, gint n_files,
const char *hint) const gchar *hint)
{ {
ConstraintEditorWindow *win; ConstraintEditorWindow *win;
int i; gint i;
for (i = 0; i < n_files; i++) for (i = 0; i < n_files; i++)
{ {

View File

@@ -193,7 +193,7 @@ constraint_editor_window_load (ConstraintEditorWindow *self,
static void static void
open_response_cb (GtkNativeDialog *dialog, open_response_cb (GtkNativeDialog *dialog,
int response, gint response,
ConstraintEditorWindow *self) ConstraintEditorWindow *self)
{ {
gtk_native_dialog_hide (dialog); gtk_native_dialog_hide (dialog);
@@ -285,7 +285,7 @@ serialize_model (GListModel *list)
static void static void
save_response_cb (GtkNativeDialog *dialog, save_response_cb (GtkNativeDialog *dialog,
int response, gint response,
ConstraintEditorWindow *self) ConstraintEditorWindow *self)
{ {
gtk_native_dialog_hide (dialog); gtk_native_dialog_hide (dialog);
@@ -317,7 +317,7 @@ save_response_cb (GtkNativeDialog *dialog,
"Saving failed"); "Saving failed");
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog), gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog),
"%s", error->message); "%s", error->message);
g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL); g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (message_dialog); gtk_widget_show (message_dialog);
g_error_free (error); g_error_free (error);
} }
@@ -403,7 +403,7 @@ constraint_editor_done (ConstraintEditor *editor,
g_clear_object (&old_constraint); g_clear_object (&old_constraint);
gtk_window_destroy (GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW))); gtk_widget_destroy (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW));
} }
static void static void
@@ -444,7 +444,7 @@ guide_editor_done (GuideEditor *editor,
GtkConstraintGuide *guide, GtkConstraintGuide *guide,
ConstraintEditorWindow *win) ConstraintEditorWindow *win)
{ {
gtk_window_destroy (GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW))); gtk_widget_destroy (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW));
} }
static void static void
@@ -487,6 +487,8 @@ constraint_editor_window_class_init (ConstraintEditorWindowClass *class)
GObjectClass *object_class = G_OBJECT_CLASS (class); GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
g_type_ensure (CONSTRAINT_VIEW_TYPE);
object_class->finalize = constraint_editor_window_finalize; object_class->finalize = constraint_editor_window_finalize;
gtk_widget_class_set_template_from_resource (widget_class, gtk_widget_class_set_template_from_resource (widget_class,
@@ -605,8 +607,8 @@ create_widget_func (gpointer item,
gtk_widget_set_margin_bottom (label, 10); gtk_widget_set_margin_bottom (label, 10);
gtk_label_set_xalign (GTK_LABEL (label), 0.0); gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_widget_set_hexpand (label, TRUE); gtk_widget_set_hexpand (label, TRUE);
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), box); gtk_container_add (GTK_CONTAINER (row), box);
gtk_box_append (GTK_BOX (box), label); gtk_container_add (GTK_CONTAINER (box), label);
if (GTK_IS_CONSTRAINT (item) || GTK_IS_CONSTRAINT_GUIDE (item)) if (GTK_IS_CONSTRAINT (item) || GTK_IS_CONSTRAINT_GUIDE (item))
{ {
@@ -614,18 +616,18 @@ create_widget_func (gpointer item,
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE); gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
g_signal_connect (button, "clicked", G_CALLBACK (row_edit), win); g_signal_connect (button, "clicked", G_CALLBACK (row_edit), win);
g_object_set_data (G_OBJECT (row), "edit", button); g_object_set_data (G_OBJECT (row), "edit", button);
gtk_box_append (GTK_BOX (box), button); gtk_container_add (GTK_CONTAINER (box), button);
button = gtk_button_new_from_icon_name ("edit-delete-symbolic"); button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE); gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win); g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
gtk_box_append (GTK_BOX (box), button); gtk_container_add (GTK_CONTAINER (box), button);
} }
else if (GTK_IS_WIDGET (item)) else if (GTK_IS_WIDGET (item))
{ {
button = gtk_button_new_from_icon_name ("edit-delete-symbolic"); button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE); gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win); g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
gtk_box_append (GTK_BOX (box), button); gtk_container_add (GTK_CONTAINER (box), button);
} }
g_free (freeme); g_free (freeme);

View File

@@ -9,6 +9,7 @@
<property name="default-height">768</property> <property name="default-height">768</property>
<child type="titlebar"> <child type="titlebar">
<object class="GtkHeaderBar" id="header"> <object class="GtkHeaderBar" id="header">
<property name="show-title-buttons">1</property>
<child type="start"> <child type="start">
<object class="GtkButton"> <object class="GtkButton">
<property name="icon-name">document-open-symbolic</property> <property name="icon-name">document-open-symbolic</property>

View File

@@ -169,34 +169,28 @@ constraint_view_init (ConstraintView *self)
GListModel *guides; GListModel *guides;
GListModel *children; GListModel *children;
GListModel *constraints; GListModel *constraints;
GtkFilter *filter;
manager = gtk_constraint_layout_new (); manager = gtk_constraint_layout_new ();
gtk_widget_set_layout_manager (GTK_WIDGET (self), manager); 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);
g_object_unref (filter);
g_object_unref (all_constraints);
all_children = gtk_widget_observe_children (GTK_WIDGET (self)); all_children = gtk_widget_observe_children (GTK_WIDGET (self));
filter = gtk_custom_filter_new (omit_internal, NULL, NULL); all_constraints = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (manager));
children = (GListModel *)gtk_filter_list_model_new (all_children, filter); guides = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (manager));
g_object_unref (filter); constraints = (GListModel *)gtk_filter_list_model_new (all_constraints, omit_internal, NULL, NULL);
g_object_unref (all_children); children = (GListModel *)gtk_filter_list_model_new (all_children, omit_internal, NULL, NULL);
list = g_list_store_new (G_TYPE_LIST_MODEL); list = g_list_store_new (G_TYPE_LIST_MODEL);
g_list_store_append (list, children); g_list_store_append (list, children);
g_list_store_append (list, guides); g_list_store_append (list, guides);
g_list_store_append (list, constraints); g_list_store_append (list, constraints);
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list)));
g_object_unref (children); g_object_unref (children);
g_object_unref (guides); g_object_unref (guides);
g_object_unref (constraints); g_object_unref (constraints);
g_object_unref (all_children);
g_object_unref (all_constraints);
g_object_unref (list);
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (list)));
controller = (GtkEventController *)gtk_gesture_drag_new (); controller = (GtkEventController *)gtk_gesture_drag_new ();
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self); g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);

View File

@@ -23,7 +23,6 @@
#define CONSTRAINT_VIEW_TYPE (constraint_view_get_type ()) #define CONSTRAINT_VIEW_TYPE (constraint_view_get_type ())
G_MODULE_EXPORT
G_DECLARE_FINAL_TYPE (ConstraintView, constraint_view, CONSTRAINT, VIEW, GtkWidget) G_DECLARE_FINAL_TYPE (ConstraintView, constraint_view, CONSTRAINT, VIEW, GtkWidget)
ConstraintView * constraint_view_new (void); ConstraintView * constraint_view_new (void);

View File

@@ -184,6 +184,58 @@ max_input (GtkSpinButton *spin_button,
return FALSE; return FALSE;
} }
static gboolean
min_output (GtkSpinButton *spin_button)
{
GtkAdjustment *adjustment;
double value;
GtkWidget *box, *text;
adjustment = gtk_spin_button_get_adjustment (spin_button);
value = gtk_adjustment_get_value (adjustment);
box = gtk_widget_get_first_child (GTK_WIDGET (spin_button));
text = gtk_widget_get_first_child (box);
if (value == 0.0)
{
gtk_editable_set_text (GTK_EDITABLE (spin_button), "");
gtk_text_set_placeholder_text (GTK_TEXT (text), "unset");
return TRUE;
}
else
{
gtk_text_set_placeholder_text (GTK_TEXT (text), "");
return FALSE;
}
}
static gboolean
max_output (GtkSpinButton *spin_button)
{
GtkAdjustment *adjustment;
double value;
GtkWidget *box, *text;
adjustment = gtk_spin_button_get_adjustment (spin_button);
value = gtk_adjustment_get_value (adjustment);
box = gtk_widget_get_first_child (GTK_WIDGET (spin_button));
text = gtk_widget_get_first_child (box);
if (value == (double)G_MAXINT)
{
gtk_editable_set_text (GTK_EDITABLE (spin_button), "");
gtk_text_set_placeholder_text (GTK_TEXT (text), "unset");
return TRUE;
}
else
{
gtk_text_set_placeholder_text (GTK_TEXT (text), "");
return FALSE;
}
}
static void static void
guide_editor_constructed (GObject *object) guide_editor_constructed (GObject *object)
{ {
@@ -192,12 +244,16 @@ guide_editor_constructed (GObject *object)
guide_strength_combo (editor->strength); guide_strength_combo (editor->strength);
g_signal_connect (editor->min_width, "input", G_CALLBACK (min_input), NULL); g_signal_connect (editor->min_width, "input", G_CALLBACK (min_input), NULL);
g_signal_connect (editor->min_width, "output", G_CALLBACK (min_output), NULL);
g_signal_connect (editor->min_height, "input", G_CALLBACK (min_input), NULL); g_signal_connect (editor->min_height, "input", G_CALLBACK (min_input), NULL);
g_signal_connect (editor->min_height, "output", G_CALLBACK (min_output), NULL);
g_signal_connect (editor->max_width, "input", G_CALLBACK (max_input), NULL); g_signal_connect (editor->max_width, "input", G_CALLBACK (max_input), NULL);
g_signal_connect (editor->max_width, "output", G_CALLBACK (max_output), NULL);
g_signal_connect (editor->max_height, "input", G_CALLBACK (max_input), NULL); g_signal_connect (editor->max_height, "input", G_CALLBACK (max_input), NULL);
g_signal_connect (editor->max_height, "output", G_CALLBACK (max_output), NULL);
if (editor->guide) if (editor->guide)
{ {

View File

@@ -34,7 +34,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 +47,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 +58,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 +92,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 +120,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 +185,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 +193,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>",
@@ -234,7 +234,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 +244,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 +328,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 +353,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);

View File

@@ -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
@@ -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))

18
demos/gtk-demo/appmenu.ui Normal file
View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<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">&lt;Control&gt;q</attribute>
</item>
</section>
</menu>
</interface>

View File

@@ -12,7 +12,7 @@ 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 +26,7 @@ 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 (data);
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
} }
@@ -41,14 +41,14 @@ on_assistant_apply (GtkWidget *widget, gpointer data)
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)); gtk_widget_destroy (widget);
} }
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,8 +70,8 @@ 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);
@@ -95,12 +95,12 @@ create_page1 (GtkWidget *assistant)
gtk_widget_set_margin_bottom (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_container_add (GTK_CONTAINER (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_container_add (GTK_CONTAINER (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);
@@ -123,7 +123,7 @@ create_page2 (GtkWidget *assistant)
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_widget_set_valign (checkbutton, GTK_ALIGN_CENTER);
gtk_box_append (GTK_BOX (box), checkbutton); gtk_container_add (GTK_CONTAINER (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);
@@ -178,7 +178,8 @@ 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); g_signal_connect (assistant, "destroy",
G_CALLBACK (gtk_widget_destroyed), &assistant);
create_page1 (assistant); create_page1 (assistant);
create_page2 (assistant); create_page2 (assistant);
@@ -198,7 +199,7 @@ 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);
return assistant; return assistant;
} }

View File

@@ -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
@@ -76,20 +74,21 @@ do_builder (GtkWidget *do_widget)
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);
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);
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;
} }

View File

@@ -69,7 +69,7 @@ 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);
@@ -108,7 +108,9 @@ do_clipboard (GtkWidget *do_widget)
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); gtk_widget_set_margin_start (vbox, 8);
@@ -120,72 +122,72 @@ do_clipboard (GtkWidget *do_widget)
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_container_add (GTK_CONTAINER (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); gtk_widget_set_margin_start (hbox, 8);
gtk_widget_set_margin_end (hbox, 8); gtk_widget_set_margin_end (hbox, 8);
gtk_widget_set_margin_top (hbox, 8); gtk_widget_set_margin_top (hbox, 8);
gtk_widget_set_margin_bottom (hbox, 8); gtk_widget_set_margin_bottom (hbox, 8);
gtk_box_append (GTK_BOX (vbox), hbox); gtk_container_add (GTK_CONTAINER (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_container_add (GTK_CONTAINER (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_container_add (GTK_CONTAINER (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_container_add (GTK_CONTAINER (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); gtk_widget_set_margin_start (hbox, 8);
gtk_widget_set_margin_end (hbox, 8); gtk_widget_set_margin_end (hbox, 8);
gtk_widget_set_margin_top (hbox, 8); gtk_widget_set_margin_top (hbox, 8);
gtk_widget_set_margin_bottom (hbox, 8); gtk_widget_set_margin_bottom (hbox, 8);
gtk_box_append (GTK_BOX (vbox), hbox); gtk_container_add (GTK_CONTAINER (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_container_add (GTK_CONTAINER (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_container_add (GTK_CONTAINER (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_container_add (GTK_CONTAINER (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); gtk_widget_set_margin_start (hbox, 8);
gtk_widget_set_margin_end (hbox, 8); gtk_widget_set_margin_end (hbox, 8);
gtk_widget_set_margin_top (hbox, 8); gtk_widget_set_margin_top (hbox, 8);
gtk_widget_set_margin_bottom (hbox, 8); gtk_widget_set_margin_bottom (hbox, 8);
gtk_box_append (GTK_BOX (vbox), hbox); gtk_container_add (GTK_CONTAINER (vbox), hbox);
/* Create the first image */ /* Create the first image */
image = demo_image_new ("dialog-warning"); image = demo_image_new ("dialog-warning");
gtk_box_append (GTK_BOX (hbox), image); gtk_container_add (GTK_CONTAINER (hbox), image);
/* Create the second image */ /* Create the second image */
image = demo_image_new ("process-stop"); image = demo_image_new ("process-stop");
gtk_box_append (GTK_BOX (hbox), image); gtk_container_add (GTK_CONTAINER (hbox), image);
/* Create the third image */ /* Create the third image */
image = demo_image_new ("weather-clear"); image = demo_image_new ("weather-clear");
gtk_box_append (GTK_BOX (hbox), image); gtk_container_add (GTK_CONTAINER (hbox), image);
} }
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;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -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);
@@ -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);
@@ -315,7 +315,9 @@ do_combobox (GtkWidget *do_widget)
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); gtk_widget_set_margin_start (vbox, 10);
@@ -328,7 +330,7 @@ do_combobox (GtkWidget *do_widget)
* 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_container_add (GTK_CONTAINER (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); gtk_widget_set_margin_start (box, 5);
@@ -340,7 +342,7 @@ do_combobox (GtkWidget *do_widget)
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,7 +374,7 @@ 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_container_add (GTK_CONTAINER (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); gtk_widget_set_margin_start (box, 5);
@@ -384,7 +386,7 @@ do_combobox (GtkWidget *do_widget)
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,7 +405,7 @@ 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_container_add (GTK_CONTAINER (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); gtk_widget_set_margin_start (box, 5);
@@ -414,7 +416,7 @@ do_combobox (GtkWidget *do_widget)
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)$";
@@ -423,7 +425,7 @@ do_combobox (GtkWidget *do_widget)
/* 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_container_add (GTK_CONTAINER (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); gtk_widget_set_margin_start (box, 5);
@@ -436,19 +438,19 @@ do_combobox (GtkWidget *do_widget)
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;
} }

View File

@@ -25,9 +25,9 @@ simple_grid_dispose (GObject *object)
{ {
SimpleGrid *self = SIMPLE_GRID (object); SimpleGrid *self = SIMPLE_GRID (object);
g_clear_pointer (&self->button1, gtk_widget_unparent); g_clear_pointer (&self->button1, gtk_widget_destroy);
g_clear_pointer (&self->button2, gtk_widget_unparent); g_clear_pointer (&self->button2, gtk_widget_destroy);
g_clear_pointer (&self->button3, gtk_widget_unparent); g_clear_pointer (&self->button3, gtk_widget_destroy);
G_OBJECT_CLASS (simple_grid_parent_class)->dispose (object); G_OBJECT_CLASS (simple_grid_parent_class)->dispose (object);
} }
@@ -263,7 +263,8 @@ do_constraints (GtkWidget *do_widget)
header = gtk_header_bar_new (); header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE); gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header); gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window); g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_window_set_child (GTK_WINDOW (window), box); gtk_window_set_child (GTK_WINDOW (window), box);
@@ -271,19 +272,19 @@ do_constraints (GtkWidget *do_widget)
grid = g_object_new (simple_grid_get_type (), NULL); grid = g_object_new (simple_grid_get_type (), NULL);
gtk_widget_set_hexpand (grid, TRUE); gtk_widget_set_hexpand (grid, TRUE);
gtk_widget_set_vexpand (grid, TRUE); gtk_widget_set_vexpand (grid, TRUE);
gtk_box_append (GTK_BOX (box), grid); gtk_container_add (GTK_CONTAINER (box), grid);
button = gtk_button_new_with_label ("Close"); button = gtk_button_new_with_label ("Close");
gtk_box_append (GTK_BOX (box), button); gtk_container_add (GTK_CONTAINER (box), button);
gtk_widget_set_hexpand (grid, TRUE); gtk_widget_set_hexpand (grid, TRUE);
g_signal_connect_swapped (button, "clicked", g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_window_destroy), window); G_CALLBACK (gtk_widget_destroy), window);
} }
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;
} }

View File

@@ -1,7 +1,7 @@
/* Constraints/Interactive /* Constraints/Interactive
* *
* Demonstrate how constraints can be updates during user interaction. * Demonstrate how constraints can be updates during
* The vertical edge between the buttons can be dragged with the mouse. * user interaction.
*/ */
#include <glib/gi18n.h> #include <glib/gi18n.h>
@@ -26,9 +26,9 @@ interactive_grid_dispose (GObject *object)
{ {
InteractiveGrid *self = INTERACTIVE_GRID (object); InteractiveGrid *self = INTERACTIVE_GRID (object);
g_clear_pointer (&self->button1, gtk_widget_unparent); g_clear_pointer (&self->button1, gtk_widget_destroy);
g_clear_pointer (&self->button2, gtk_widget_unparent); g_clear_pointer (&self->button2, gtk_widget_destroy);
g_clear_pointer (&self->button3, gtk_widget_unparent); g_clear_pointer (&self->button3, gtk_widget_destroy);
G_OBJECT_CLASS (interactive_grid_parent_class)->dispose (object); G_OBJECT_CLASS (interactive_grid_parent_class)->dispose (object);
} }
@@ -219,7 +219,8 @@ do_constraints2 (GtkWidget *do_widget)
header = gtk_header_bar_new (); header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE); gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header); gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window); g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_window_set_child (GTK_WINDOW (window), box); gtk_window_set_child (GTK_WINDOW (window), box);
@@ -227,19 +228,19 @@ do_constraints2 (GtkWidget *do_widget)
grid = g_object_new (interactive_grid_get_type (), NULL); grid = g_object_new (interactive_grid_get_type (), NULL);
gtk_widget_set_hexpand (grid, TRUE); gtk_widget_set_hexpand (grid, TRUE);
gtk_widget_set_vexpand (grid, TRUE); gtk_widget_set_vexpand (grid, TRUE);
gtk_box_append (GTK_BOX (box), grid); gtk_container_add (GTK_CONTAINER (box), grid);
button = gtk_button_new_with_label ("Close"); button = gtk_button_new_with_label ("Close");
gtk_box_append (GTK_BOX (box), button); gtk_container_add (GTK_CONTAINER (box), button);
gtk_widget_set_hexpand (grid, TRUE); gtk_widget_set_hexpand (grid, TRUE);
g_signal_connect_swapped (button, "clicked", g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_window_destroy), window); G_CALLBACK (gtk_widget_destroy), window);
} }
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;
} }

View File

@@ -24,9 +24,9 @@ vfl_grid_dispose (GObject *object)
{ {
VflGrid *self = VFL_GRID (object); VflGrid *self = VFL_GRID (object);
g_clear_pointer (&self->button1, gtk_widget_unparent); g_clear_pointer (&self->button1, gtk_widget_destroy);
g_clear_pointer (&self->button2, gtk_widget_unparent); g_clear_pointer (&self->button2, gtk_widget_destroy);
g_clear_pointer (&self->button3, gtk_widget_unparent); g_clear_pointer (&self->button3, gtk_widget_destroy);
G_OBJECT_CLASS (vfl_grid_parent_class)->dispose (object); G_OBJECT_CLASS (vfl_grid_parent_class)->dispose (object);
} }
@@ -139,7 +139,8 @@ do_constraints3 (GtkWidget *do_widget)
header = gtk_header_bar_new (); header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE); gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header); gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window); g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_window_set_child (GTK_WINDOW (window), box); gtk_window_set_child (GTK_WINDOW (window), box);
@@ -147,19 +148,19 @@ do_constraints3 (GtkWidget *do_widget)
grid = g_object_new (vfl_grid_get_type (), NULL); grid = g_object_new (vfl_grid_get_type (), NULL);
gtk_widget_set_hexpand (grid, TRUE); gtk_widget_set_hexpand (grid, TRUE);
gtk_widget_set_vexpand (grid, TRUE); gtk_widget_set_vexpand (grid, TRUE);
gtk_box_append (GTK_BOX (box), grid); gtk_container_add (GTK_CONTAINER (box), grid);
button = gtk_button_new_with_label ("Close"); button = gtk_button_new_with_label ("Close");
gtk_box_append (GTK_BOX (box), button); gtk_container_add (GTK_CONTAINER (box), button);
gtk_widget_set_hexpand (grid, TRUE); gtk_widget_set_hexpand (grid, TRUE);
g_signal_connect_swapped (button, "clicked", g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_window_destroy), window); G_CALLBACK (gtk_widget_destroy), window);
} }
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;
} }

View File

@@ -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 *
@@ -32,7 +28,8 @@ do_css_accordion (GtkWidget *do_widget)
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);
@@ -40,22 +37,22 @@ do_css_accordion (GtkWidget *do_widget)
gtk_window_set_child (GTK_WINDOW (window), container); gtk_window_set_child (GTK_WINDOW (window), container);
child = gtk_button_new_with_label ("This"); child = gtk_button_new_with_label ("This");
gtk_box_append (GTK_BOX (container), child); gtk_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;
} }

View File

@@ -55,13 +55,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 *
@@ -80,7 +76,8 @@ do_css_basics (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "CSS Basics"); gtk_window_set_title (GTK_WINDOW (window), "CSS Basics");
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget)); gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300); gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
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 +91,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_window_set_child (GTK_WINDOW (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 +113,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;
} }

View File

@@ -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;
} }

View File

@@ -69,13 +69,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,7 +81,7 @@ 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;
@@ -94,31 +90,32 @@ do_css_multiplebgs (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Multiple Backgrounds"); gtk_window_set_title (GTK_WINDOW (window), "Multiple Backgrounds");
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget)); gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300); gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
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_window_set_child (GTK_WINDOW (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 +129,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 +153,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;
} }

View File

@@ -55,13 +55,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 *
@@ -80,14 +76,15 @@ do_css_pixbufs (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Animated Backgrounds"); gtk_window_set_title (GTK_WINDOW (window), "Animated Backgrounds");
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget)); gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300); gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
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_window_set_child (GTK_WINDOW (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 +98,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 +120,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;
} }

View File

@@ -53,13 +53,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);
} }
static GtkWidget * static GtkWidget *
@@ -72,13 +68,13 @@ create_toolbar (void)
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_button_new_from_icon_name ("go-next");
gtk_box_append (GTK_BOX (toolbar), item); gtk_container_add (GTK_CONTAINER (toolbar), item);
item = gtk_button_new_from_icon_name ("go-previous"); item = gtk_button_new_from_icon_name ("go-previous");
gtk_box_append (GTK_BOX (toolbar), item); gtk_container_add (GTK_CONTAINER (toolbar), item);
item = gtk_button_new_with_label ("Hello World"); item = gtk_button_new_with_label ("Hello World");
gtk_box_append (GTK_BOX (toolbar), item); gtk_container_add (GTK_CONTAINER (toolbar), item);
return toolbar; return toolbar;
} }
@@ -99,13 +95,14 @@ do_css_shadows (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Shadows"); gtk_window_set_title (GTK_WINDOW (window), "Shadows");
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget)); gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300); gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
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_window_set_child (GTK_WINDOW (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;
} }

View File

@@ -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>
@@ -28,14 +29,14 @@ do_cursors (GtkWidget *do_widget)
gtk_widget_get_display (do_widget)); gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy", g_signal_connect (window, "destroy",
G_CALLBACK (on_destroy), NULL); G_CALLBACK (on_destroy), NULL);
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;

View File

@@ -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>
@@ -105,9 +103,6 @@
<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>
@@ -124,24 +119,6 @@
<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>
@@ -194,7 +171,6 @@
<file>cursors.c</file> <file>cursors.c</file>
<file>dialog.c</file> <file>dialog.c</file>
<file>drawingarea.c</file> <file>drawingarea.c</file>
<file>dropdown.c</file>
<file>dnd.c</file> <file>dnd.c</file>
<file>editable_cells.c</file> <file>editable_cells.c</file>
<file>entry_completion.c</file> <file>entry_completion.c</file>
@@ -219,14 +195,6 @@
<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>modelbutton.c</file> <file>modelbutton.c</file>
@@ -301,7 +269,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> <file>bluroverlay.c</file>
</gresource> </gresource>
<gresource prefix="/markup"> <gresource prefix="/markup">

View File

@@ -94,7 +94,6 @@
<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>

View File

@@ -17,7 +17,7 @@ G_DEFINE_TYPE(DemoImage, demo_image, GTK_TYPE_WIDGET)
static GdkPaintable * static GdkPaintable *
get_image_paintable (GtkImage *image) get_image_paintable (GtkImage *image)
{ {
const char *icon_name; const gchar *icon_name;
GtkIconTheme *icon_theme; GtkIconTheme *icon_theme;
GtkIconPaintable *icon; GtkIconPaintable *icon;

View File

@@ -25,36 +25,31 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gtk/gtk-a11y.h> #include <gtk/gtk-a11y.h>
struct _DemoTaggedEntry typedef struct {
{
GtkWidget parent_instance;
GtkWidget *box; GtkWidget *box;
GtkWidget *entry; GtkWidget *entry;
}; } DemoTaggedEntryPrivate;
struct _DemoTaggedEntryClass
{
GtkWidgetClass parent_class;
};
static void demo_tagged_entry_editable_init (GtkEditableInterface *iface); static void demo_tagged_entry_editable_init (GtkEditableInterface *iface);
G_DEFINE_TYPE_WITH_CODE (DemoTaggedEntry, demo_tagged_entry, GTK_TYPE_WIDGET, G_DEFINE_TYPE_WITH_CODE (DemoTaggedEntry, demo_tagged_entry, GTK_TYPE_WIDGET,
G_ADD_PRIVATE (DemoTaggedEntry)
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE, demo_tagged_entry_editable_init)) G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE, demo_tagged_entry_editable_init))
static void static void
demo_tagged_entry_init (DemoTaggedEntry *entry) demo_tagged_entry_init (DemoTaggedEntry *entry)
{ {
entry->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
gtk_widget_set_parent (entry->box, GTK_WIDGET (entry));
entry->entry = gtk_text_new (); priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_hexpand (entry->entry, TRUE); gtk_widget_set_parent (priv->box, GTK_WIDGET (entry));
gtk_widget_set_vexpand (entry->entry, TRUE);
gtk_widget_set_hexpand (entry->box, FALSE); priv->entry = gtk_text_new ();
gtk_widget_set_vexpand (entry->box, FALSE); gtk_widget_set_hexpand (priv->entry, TRUE);
gtk_box_append (GTK_BOX (entry->box), entry->entry); gtk_widget_set_vexpand (priv->entry, TRUE);
gtk_widget_set_hexpand (priv->box, FALSE);
gtk_widget_set_vexpand (priv->box, FALSE);
gtk_container_add (GTK_CONTAINER (priv->box), priv->entry);
gtk_editable_init_delegate (GTK_EDITABLE (entry)); gtk_editable_init_delegate (GTK_EDITABLE (entry));
} }
@@ -62,16 +57,23 @@ static void
demo_tagged_entry_dispose (GObject *object) demo_tagged_entry_dispose (GObject *object)
{ {
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (object); DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (object);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
if (entry->entry) if (priv->entry)
gtk_editable_finish_delegate (GTK_EDITABLE (entry)); gtk_editable_finish_delegate (GTK_EDITABLE (entry));
g_clear_pointer (&entry->entry, gtk_widget_unparent); g_clear_pointer (&priv->entry, gtk_widget_unparent);
g_clear_pointer (&entry->box, gtk_widget_unparent); g_clear_pointer (&priv->box, gtk_widget_unparent);
G_OBJECT_CLASS (demo_tagged_entry_parent_class)->dispose (object); G_OBJECT_CLASS (demo_tagged_entry_parent_class)->dispose (object);
} }
static void
demo_tagged_entry_finalize (GObject *object)
{
G_OBJECT_CLASS (demo_tagged_entry_parent_class)->finalize (object);
}
static void static void
demo_tagged_entry_set_property (GObject *object, demo_tagged_entry_set_property (GObject *object,
guint prop_id, guint prop_id,
@@ -96,12 +98,44 @@ demo_tagged_entry_get_property (GObject *object,
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
} }
static void
demo_tagged_entry_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
gtk_widget_measure (priv->box, orientation, for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
demo_tagged_entry_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
gtk_widget_size_allocate (priv->box,
&(GtkAllocation) { 0, 0, width, height },
baseline);
}
static gboolean static gboolean
demo_tagged_entry_grab_focus (GtkWidget *widget) demo_tagged_entry_grab_focus (GtkWidget *widget)
{ {
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget); DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
return gtk_widget_grab_focus (entry->entry); return gtk_widget_grab_focus (priv->entry);
} }
static void static void
@@ -111,14 +145,16 @@ demo_tagged_entry_class_init (DemoTaggedEntryClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = demo_tagged_entry_dispose; object_class->dispose = demo_tagged_entry_dispose;
object_class->finalize = demo_tagged_entry_finalize;
object_class->get_property = demo_tagged_entry_get_property; object_class->get_property = demo_tagged_entry_get_property;
object_class->set_property = demo_tagged_entry_set_property; object_class->set_property = demo_tagged_entry_set_property;
widget_class->measure = demo_tagged_entry_measure;
widget_class->size_allocate = demo_tagged_entry_size_allocate;
widget_class->grab_focus = demo_tagged_entry_grab_focus; widget_class->grab_focus = demo_tagged_entry_grab_focus;
gtk_editable_install_properties (object_class, 1); 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_accessible_type (widget_class, GTK_TYPE_ENTRY_ACCESSIBLE);
gtk_widget_class_set_css_name (widget_class, "entry"); gtk_widget_class_set_css_name (widget_class, "entry");
} }
@@ -126,7 +162,10 @@ demo_tagged_entry_class_init (DemoTaggedEntryClass *klass)
static GtkEditable * static GtkEditable *
demo_tagged_entry_get_delegate (GtkEditable *editable) demo_tagged_entry_get_delegate (GtkEditable *editable)
{ {
return GTK_EDITABLE (DEMO_TAGGED_ENTRY (editable)->entry); DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (editable);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
return GTK_EDITABLE (priv->entry);
} }
static void static void
@@ -145,9 +184,11 @@ void
demo_tagged_entry_add_tag (DemoTaggedEntry *entry, demo_tagged_entry_add_tag (DemoTaggedEntry *entry,
GtkWidget *tag) GtkWidget *tag)
{ {
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry)); g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
gtk_box_append (GTK_BOX (entry->box), tag); gtk_container_add (GTK_CONTAINER (priv->box), tag);
} }
void void
@@ -155,27 +196,30 @@ demo_tagged_entry_insert_tag_after (DemoTaggedEntry *entry,
GtkWidget *tag, GtkWidget *tag,
GtkWidget *sibling) GtkWidget *sibling)
{ {
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry)); g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
if (sibling == NULL) if (sibling == NULL)
gtk_box_append (GTK_BOX (entry->box), tag); gtk_container_add (GTK_CONTAINER (priv->box), tag);
else else
gtk_box_insert_child_after (GTK_BOX (entry->box), tag, sibling); gtk_box_insert_child_after (GTK_BOX (priv->box), tag, sibling);
} }
void void
demo_tagged_entry_remove_tag (DemoTaggedEntry *entry, demo_tagged_entry_remove_tag (DemoTaggedEntry *entry,
GtkWidget *tag) GtkWidget *tag)
{ {
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry)); g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
gtk_box_remove (GTK_BOX (entry->box), tag); gtk_container_remove (GTK_CONTAINER (priv->box), tag);
} }
struct _DemoTaggedEntryTag struct _DemoTaggedEntryTag
{ {
GtkWidget parent; GtkWidget parent;
GtkWidget *box; GtkWidget *box;
GtkWidget *label; GtkWidget *label;
GtkWidget *button; GtkWidget *button;
@@ -206,11 +250,11 @@ static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE (DemoTaggedEntryTag, demo_tagged_entry_tag, GTK_TYPE_WIDGET) G_DEFINE_TYPE (DemoTaggedEntryTag, demo_tagged_entry_tag, GTK_TYPE_WIDGET)
static void static void
on_released (GtkGestureClick *gesture, on_released (GtkGestureClick *gesture,
int n_press, int n_press,
double x, double x,
double y, double y,
DemoTaggedEntryTag *tag) DemoTaggedEntryTag *tag)
{ {
g_signal_emit (tag, signals[SIGNAL_CLICKED], 0); g_signal_emit (tag, signals[SIGNAL_CLICKED], 0);
} }
@@ -224,7 +268,7 @@ demo_tagged_entry_tag_init (DemoTaggedEntryTag *tag)
tag->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); tag->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_parent (tag->box, GTK_WIDGET (tag)); gtk_widget_set_parent (tag->box, GTK_WIDGET (tag));
tag->label = gtk_label_new (""); tag->label = gtk_label_new ("");
gtk_box_append (GTK_BOX (tag->box), tag->label); gtk_container_add (GTK_CONTAINER (tag->box), tag->label);
gesture = gtk_gesture_click_new (); gesture = gtk_gesture_click_new ();
g_signal_connect (gesture, "released", G_CALLBACK (on_released), tag); g_signal_connect (gesture, "released", G_CALLBACK (on_released), tag);
@@ -416,7 +460,7 @@ demo_tagged_entry_tag_set_has_close_button (DemoTaggedEntryTag *tag,
if (!has_close_button && tag->button) if (!has_close_button && tag->button)
{ {
gtk_box_remove (GTK_BOX (tag->box), tag->button); gtk_container_remove (GTK_CONTAINER (tag->box), tag->button);
tag->button = NULL; tag->button = NULL;
} }
else if (has_close_button && tag->button == NULL) else if (has_close_button && tag->button == NULL)
@@ -425,11 +469,11 @@ demo_tagged_entry_tag_set_has_close_button (DemoTaggedEntryTag *tag,
image = gtk_image_new_from_icon_name ("window-close-symbolic"); image = gtk_image_new_from_icon_name ("window-close-symbolic");
tag->button = gtk_button_new (); tag->button = gtk_button_new ();
gtk_button_set_child (GTK_BUTTON (tag->button), image); gtk_container_add (GTK_CONTAINER (tag->button), image);
gtk_widget_set_halign (tag->button, GTK_ALIGN_CENTER); gtk_widget_set_halign (tag->button, GTK_ALIGN_CENTER);
gtk_widget_set_valign (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_button_set_has_frame (GTK_BUTTON (tag->button), FALSE);
gtk_box_append (GTK_BOX (tag->box), tag->button); gtk_container_add (GTK_CONTAINER (tag->box), tag->button);
g_signal_connect (tag->button, "clicked", G_CALLBACK (on_button_clicked), tag); g_signal_connect (tag->button, "clicked", G_CALLBACK (on_button_clicked), tag);
} }

View File

@@ -25,11 +25,39 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define DEMO_TYPE_TAGGED_ENTRY (demo_tagged_entry_get_type ()) #define DEMO_TYPE_TAGGED_ENTRY (demo_tagged_entry_get_type ())
G_DECLARE_FINAL_TYPE (DemoTaggedEntry, demo_tagged_entry, DEMO, TAGGED_ENTRY, GtkWidget) #define DEMO_TAGGED_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntry))
#define DEMO_TAGGED_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntryClass))
#define DEMO_IS_TAGGED_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEMO_TYPE_TAGGED_ENTRY))
#define DEMO_IS_TAGGED_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEMO_TYPE_TAGGED_ENTRY))
#define DEMO_TAGGED_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntryClass))
#define DEMO_TYPE_TAGGED_ENTRY_TAG (demo_tagged_entry_tag_get_type ()) typedef struct _DemoTaggedEntry DemoTaggedEntry;
G_DECLARE_FINAL_TYPE (DemoTaggedEntryTag, demo_tagged_entry_tag, DEMO, TAGGED_ENTRY_TAG, GtkWidget) typedef struct _DemoTaggedEntryClass DemoTaggedEntryClass;
struct _DemoTaggedEntry
{
GtkWidget parent;
};
struct _DemoTaggedEntryClass
{
GtkWidgetClass parent_class;
};
#define DEMO_TYPE_TAGGED_ENTRY_TAG (demo_tagged_entry_tag_get_type ())
#define DEMO_TAGGED_ENTRY_TAG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTag))
#define DEMO_TAGGED_ENTRY_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTag))
#define DEMO_IS_TAGGED_ENTRY_TAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG))
#define DEMO_IS_TAGGED_ENTRY_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEMO_TYPE_TAGGED_ENTRY_TAG))
#define DEMO_TAGGED_ENTRY_TAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTagClass))
typedef struct _DemoTaggedEntryTag DemoTaggedEntryTag;
typedef struct _DemoTaggedEntryTagClass DemoTaggedEntryTagClass;
GType demo_tagged_entry_get_type (void) G_GNUC_CONST;
GType demo_tagged_entry_tag_get_type (void) G_GNUC_CONST;
GtkWidget * demo_tagged_entry_new (void); GtkWidget * demo_tagged_entry_new (void);

View File

@@ -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,77 +15,57 @@ 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_container_add (GTK_CONTAINER (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_container_add (GTK_CONTAINER (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_container_add (GTK_CONTAINER (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 ();
@@ -102,23 +81,21 @@ interactive_dialog_clicked (GtkButton *button,
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_editable_set_text (GTK_EDITABLE (entry1), gtk_editable_get_text (GTK_EDITABLE (local_entry1)));
0); gtk_editable_set_text (GTK_EDITABLE (entry2), gtk_editable_get_text (GTK_EDITABLE (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;
@@ -131,42 +108,50 @@ do_dialog (GtkWidget *do_widget)
window = gtk_window_new (); window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget)); gtk_widget_get_display (do_widget));
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");
gtk_widget_set_margin_start (frame, 8);
gtk_widget_set_margin_end (frame, 8);
gtk_widget_set_margin_top (frame, 8);
gtk_widget_set_margin_bottom (frame, 8);
gtk_window_set_child (GTK_WINDOW (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); gtk_widget_set_margin_start (vbox, 8);
gtk_widget_set_margin_end (vbox, 8); gtk_widget_set_margin_end (vbox, 8);
gtk_widget_set_margin_top (vbox, 8); gtk_widget_set_margin_top (vbox, 8);
gtk_widget_set_margin_bottom (vbox, 8); gtk_widget_set_margin_bottom (vbox, 8);
gtk_window_set_child (GTK_WINDOW (window), vbox); gtk_frame_set_child (GTK_FRAME (frame), 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_container_add (GTK_CONTAINER (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_container_add (GTK_CONTAINER (hbox), button);
gtk_box_append (GTK_BOX (vbox), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL)); gtk_container_add (GTK_CONTAINER (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_container_add (GTK_CONTAINER (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_container_add (GTK_CONTAINER (hbox), vbox2);
gtk_box_append (GTK_BOX (vbox2), button); gtk_container_add (GTK_CONTAINER (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_container_add (GTK_CONTAINER (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 +170,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;
} }

View File

@@ -7,324 +7,6 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE (CanvasItem, canvas_item, CANVAS, ITEM, GtkWidget)
struct _CanvasItem {
GtkWidget parent;
GtkWidget *fixed;
GtkWidget *label;
double r;
double angle;
double delta;
GtkWidget *editor;
};
struct _CanvasItemClass {
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (CanvasItem, canvas_item, GTK_TYPE_WIDGET)
static int n_items = 0;
static void
set_color (CanvasItem *item,
GdkRGBA *color)
{
char *css;
char *str;
GtkStyleContext *context;
GtkCssProvider *provider;
const char *old_class;
str = gdk_rgba_to_string (color);
css = g_strdup_printf ("* { background: %s; }", str);
context = gtk_widget_get_style_context (item->label);
provider = g_object_get_data (G_OBJECT (context), "style-provider");
if (provider)
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
old_class = (const char *)g_object_get_data (G_OBJECT (item->label), "css-class");
if (old_class)
gtk_widget_remove_css_class (item->label, old_class);
provider = gtk_css_provider_new ();
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
set_css (CanvasItem *item,
const char *class)
{
GtkStyleContext *context;
GtkCssProvider *provider;
const char *old_class;
context = gtk_widget_get_style_context (item->label);
provider = g_object_get_data (G_OBJECT (context), "style-provider");
if (provider)
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
old_class = (const char *)g_object_get_data (G_OBJECT (item->label), "css-class");
if (old_class)
gtk_widget_remove_css_class (item->label, old_class);
g_object_set_data_full (G_OBJECT (item->label), "css-class", g_strdup (class), g_free);
gtk_widget_add_css_class (item->label, class);
}
static gboolean
item_drag_drop (GtkDropTarget *dest,
const GValue *value,
double x,
double y)
{
GtkWidget *label = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
CanvasItem *item = CANVAS_ITEM (gtk_widget_get_parent (gtk_widget_get_parent (label)));
if (G_VALUE_TYPE (value) == GDK_TYPE_RGBA)
set_color (item, g_value_get_boxed (value));
else if (G_VALUE_TYPE (value) == G_TYPE_STRING)
set_css (item, g_value_get_string (value));
return TRUE;
}
static void
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 *
canvas_item_new (void)
{
CanvasItem *item = g_object_new (canvas_item_get_type (), NULL);
return GTK_WIDGET (item);
}
static GdkPaintable *
canvas_item_get_drag_icon (CanvasItem *item)
{
return gtk_widget_paintable_new (item->fixed);
}
static gboolean
canvas_item_is_editing (CanvasItem *item)
{
return item->editor != NULL;
}
static void
scale_changed (GtkRange *range,
CanvasItem *item)
{
item->angle = gtk_range_get_value (range);
apply_transform (item);
}
static void
text_changed (GtkEditable *editable,
GParamSpec *pspec,
CanvasItem *item)
{
gtk_label_set_text (GTK_LABEL (item->label), gtk_editable_get_text (editable));
apply_transform (item);
}
static void
canvas_item_stop_editing (CanvasItem *item)
{
GtkWidget *scale;
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
canvas_item_start_editing (CanvasItem *item)
{
GtkWidget *canvas = gtk_widget_get_parent (GTK_WIDGET (item));
GtkWidget *entry;
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 * static GdkContentProvider *
prepare (GtkDragSource *source, prepare (GtkDragSource *source,
double x, double x,
@@ -336,8 +18,7 @@ prepare (GtkDragSource *source,
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source)); canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
item = gtk_widget_pick (canvas, x, y, GTK_PICK_DEFAULT); item = gtk_widget_pick (canvas, x, y, GTK_PICK_DEFAULT);
item = gtk_widget_get_ancestor (item, canvas_item_get_type ()); if (!GTK_IS_LABEL (item))
if (!item)
return NULL; return NULL;
g_object_set_data (G_OBJECT (canvas), "dragged-item", item); g_object_set_data (G_OBJECT (canvas), "dragged-item", item);
@@ -350,17 +31,12 @@ drag_begin (GtkDragSource *source,
GdkDrag *drag) GdkDrag *drag)
{ {
GtkWidget *canvas; GtkWidget *canvas;
CanvasItem *item; GtkWidget *item;
GdkPaintable *paintable;
canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source)); canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
item = CANVAS_ITEM (g_object_get_data (G_OBJECT (canvas), "dragged-item")); item = g_object_get_data (G_OBJECT (canvas), "dragged-item");
paintable = canvas_item_get_drag_icon (item); gtk_widget_set_opacity (item, 0.5);
gtk_drag_source_set_icon (source, paintable, item->r, item->r);
g_object_unref (paintable);
gtk_widget_set_opacity (GTK_WIDGET (item), 0.3);
} }
static void static void
@@ -377,12 +53,32 @@ drag_end (GtkDragSource *source,
gtk_widget_set_opacity (item, 1.0); gtk_widget_set_opacity (item, 1.0);
} }
static gboolean static void
drag_cancel (GtkDragSource *source, drag_cancel (GtkDragSource *source,
GdkDrag *drag, GdkDrag *drag,
GdkDragCancelReason reason) GdkDragCancelReason reason)
{ {
return FALSE; drag_end (source, drag);
}
typedef struct {
double x, y;
double angle;
double delta;
} TransformData;
static void
apply_transform (GtkWidget *item)
{
GtkWidget *canvas = gtk_widget_get_parent (item);
TransformData *data;
GskTransform *transform;
data = g_object_get_data (G_OBJECT (item), "transform-data");
transform = gsk_transform_rotate (gsk_transform_translate (NULL, &(graphene_point_t){data->x, data->y}),
data->angle + data->delta);
gtk_fixed_set_child_transform (GTK_FIXED (canvas), item, transform);
gsk_transform_unref (transform);
} }
static gboolean static gboolean
@@ -391,58 +87,90 @@ drag_drop (GtkDropTarget *target,
double x, double x,
double y) double y)
{ {
CanvasItem *item; GtkWidget *item;
TransformData *transform_data;
GtkWidget *canvas; GtkWidget *canvas;
GtkWidget *last_child; GtkWidget *last_child;
item = g_value_get_object (value); item = g_value_get_object (value);
transform_data = g_object_get_data (G_OBJECT (item), "transform-data");
canvas = gtk_widget_get_parent (GTK_WIDGET (item)); transform_data->x = x;
transform_data->y = y;
canvas = gtk_widget_get_parent (item);
last_child = gtk_widget_get_last_child (canvas); last_child = gtk_widget_get_last_child (canvas);
if (GTK_WIDGET (item) != last_child) if (item != last_child)
gtk_widget_insert_after (GTK_WIDGET (item), canvas, last_child); gtk_widget_insert_after (item, canvas, last_child);
gtk_fixed_move (GTK_FIXED (canvas), GTK_WIDGET (item), x - item->r, y - item->r); apply_transform (item);
return TRUE; return TRUE;
} }
static double pos_x, pos_y;
static GtkWidget * canvas_item_new (double x, double y);
static void static void
new_item_cb (GtkWidget *button, gpointer data) new_item_cb (GtkWidget *button, gpointer data)
{ {
GtkWidget *canvas = data; GtkWidget *canvas = data;
GtkWidget *popover;
GtkWidget *item; GtkWidget *item;
GdkRectangle rect;
popover = gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER); item = canvas_item_new (pos_x, pos_y);
gtk_popover_get_pointing_to (GTK_POPOVER (popover), &rect); gtk_container_add (GTK_CONTAINER (canvas), item);
apply_transform (item);
item = canvas_item_new ();
gtk_fixed_put (GTK_FIXED (canvas), item, rect.x, rect.y);
apply_transform (CANVAS_ITEM (item));
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER))); gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
} }
static void
edit_label_done (GtkWidget *entry, gpointer data)
{
GtkWidget *canvas = gtk_widget_get_parent (entry);
GtkWidget *label;
int x, y;
gtk_fixed_get_child_position (GTK_FIXED (canvas), entry, &x, &y);
label = GTK_WIDGET (g_object_get_data (G_OBJECT (entry), "label"));
gtk_label_set_text (GTK_LABEL (label), gtk_editable_get_text (GTK_EDITABLE (entry)));
gtk_widget_show (label);
gtk_widget_destroy (entry);
}
static void static void
edit_cb (GtkWidget *button, GtkWidget *child) edit_cb (GtkWidget *button, GtkWidget *child)
{ {
CanvasItem *item = CANVAS_ITEM (child); GtkWidget *canvas = gtk_widget_get_parent (child);
int x, y;
gtk_fixed_get_child_position (GTK_FIXED (canvas), child, &x, &y);
if (GTK_IS_LABEL (child))
{
GtkWidget *entry = gtk_entry_new ();
g_object_set_data (G_OBJECT (entry), "label", child);
gtk_editable_set_text (GTK_EDITABLE (entry), gtk_label_get_text (GTK_LABEL (child)));
gtk_editable_set_width_chars (GTK_EDITABLE (entry), 12);
g_signal_connect (entry, "activate", G_CALLBACK (edit_label_done), NULL);
gtk_fixed_put (GTK_FIXED (canvas), entry, x, y);
gtk_widget_grab_focus (entry);
gtk_widget_hide (child);
}
if (button) if (button)
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER))); gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
if (!canvas_item_is_editing (item))
canvas_item_start_editing (item);
} }
static void static void
delete_cb (GtkWidget *button, GtkWidget *child) delete_cb (GtkWidget *button, GtkWidget *child)
{ {
GtkWidget *canvas = gtk_widget_get_parent (child); gtk_widget_destroy (child);
gtk_fixed_remove (GTK_FIXED (canvas), child);
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER))); gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
} }
@@ -459,7 +187,6 @@ pressed_cb (GtkGesture *gesture,
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, GTK_PICK_DEFAULT);
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)
{ {
@@ -467,35 +194,38 @@ pressed_cb (GtkGesture *gesture,
GtkWidget *box; GtkWidget *box;
GtkWidget *item; GtkWidget *item;
pos_x = x;
pos_y = y;
menu = gtk_popover_new (); menu = gtk_popover_new ();
gtk_widget_set_parent (menu, widget); gtk_widget_set_parent (menu, widget);
gtk_popover_set_has_arrow (GTK_POPOVER (menu), FALSE); gtk_popover_set_has_arrow (GTK_POPOVER (menu), FALSE);
gtk_popover_set_pointing_to (GTK_POPOVER (menu), &(GdkRectangle){ x, y, 1, 1}); gtk_popover_set_pointing_to (GTK_POPOVER (menu), &(GdkRectangle){ x, y, 1, 1});
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_popover_set_child (GTK_POPOVER (menu), box); gtk_container_add (GTK_CONTAINER (menu), box);
item = gtk_button_new_with_label ("New"); item = gtk_button_new_with_label ("New");
gtk_button_set_has_frame (GTK_BUTTON (item), FALSE); gtk_button_set_has_frame (GTK_BUTTON (item), FALSE);
g_signal_connect (item, "clicked", G_CALLBACK (new_item_cb), widget); g_signal_connect (item, "clicked", G_CALLBACK (new_item_cb), widget);
gtk_box_append (GTK_BOX (box), item); gtk_container_add (GTK_CONTAINER (box), item);
item = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); item = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
gtk_box_append (GTK_BOX (box), item); gtk_container_add (GTK_CONTAINER (box), item);
item = gtk_button_new_with_label ("Edit"); item = gtk_button_new_with_label ("Edit");
gtk_button_set_has_frame (GTK_BUTTON (item), FALSE); 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 (item, "clicked", G_CALLBACK (edit_cb), child);
gtk_box_append (GTK_BOX (box), item); gtk_container_add (GTK_CONTAINER (box), item);
item = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); item = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
gtk_box_append (GTK_BOX (box), item); gtk_container_add (GTK_CONTAINER (box), item);
item = gtk_button_new_with_label ("Delete"); item = gtk_button_new_with_label ("Delete");
gtk_button_set_has_frame (GTK_BUTTON (item), FALSE); 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 (item, "clicked", G_CALLBACK (delete_cb), child);
gtk_box_append (GTK_BOX (box), item); gtk_container_add (GTK_CONTAINER (box), item);
gtk_popover_popup (GTK_POPOVER (menu)); gtk_popover_popup (GTK_POPOVER (menu));
} }
@@ -510,20 +240,14 @@ 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, 0);
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 (NULL, child);
else
canvas_item_start_editing (item);
} }
} }
@@ -561,117 +285,129 @@ canvas_new (void)
return canvas; return canvas;
} }
static GdkContentProvider * static void
css_drag_prepare (GtkDragSource *source, set_color (GtkWidget *item,
double x, GdkRGBA *color)
double y,
GtkWidget *button)
{ {
const char *class; char *css;
GdkPaintable *paintable; char *str;
GtkStyleContext *context;
GtkCssProvider *provider;
class = (const char *)g_object_get_data (G_OBJECT (button), "css-class"); str = gdk_rgba_to_string (color);
css = g_strdup_printf ("* { background: %s; padding: 10px; }", str);
paintable = gtk_widget_paintable_new (button); context = gtk_widget_get_style_context (item);
gtk_drag_source_set_icon (source, paintable, 0, 0); provider = g_object_get_data (G_OBJECT (context), "style-provider");
g_object_unref (paintable); if (provider)
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
return gdk_content_provider_new_typed (G_TYPE_STRING, 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), 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 gboolean
item_drag_drop (GtkDropTarget *dest,
const GValue *value,
double x,
double y)
{
GtkWidget *item = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
set_color (item, g_value_get_boxed (value));
return TRUE;
}
static void
angle_changed (GtkGestureRotate *gesture,
double angle,
double delta)
{
GtkWidget *item = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
TransformData *data = g_object_get_data (G_OBJECT (item), "transform-data");
data->delta = angle / M_PI * 180.0;
apply_transform (item);
}
static void
rotate_done (GtkGesture *gesture)
{
GtkWidget *item = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
TransformData *data = g_object_get_data (G_OBJECT (item), "transform-data");
data->angle = data->angle + data->delta;
data->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 int n_items = 0;
static GtkWidget * static GtkWidget *
css_button_new (const char *class) canvas_item_new (double x,
double y)
{ {
GtkWidget *button; GtkWidget *widget;
GtkDragSource *source; char *label;
char *id;
TransformData *transform_data;
GdkRGBA rgba;
GtkDropTarget *dest;
GtkGesture *gesture;
button = gtk_image_new (); n_items++;
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 (); label = g_strdup_printf ("Item %d", n_items);
g_signal_connect (source, "prepare", G_CALLBACK (css_drag_prepare), button); id = g_strdup_printf ("item%d", n_items);
gtk_widget_add_controller (button, GTK_EVENT_CONTROLLER (source));
return button; gdk_rgba_parse (&rgba, "yellow");
}
typedef struct widget = gtk_label_new (label);
{ gtk_widget_add_css_class (widget, "frame");
GtkWidget parent_instance; gtk_widget_set_name (widget, id);
GdkRGBA color;
} ColorSwatch;
typedef struct set_color (widget, &rgba);
{ transform_data = g_new0 (TransformData, 1);
GtkWidgetClass parent_class; transform_data->x = x;
} ColorSwatchClass; transform_data->y = y;
transform_data->angle = 0.0;
g_object_set_data_full (G_OBJECT (widget), "transform-data", transform_data, g_free);
G_DEFINE_TYPE (ColorSwatch, color_swatch, GTK_TYPE_WIDGET) g_free (label);
g_free (id);
static GdkContentProvider * dest = gtk_drop_target_new (GDK_TYPE_RGBA, GDK_ACTION_COPY);
color_swatch_drag_prepare (GtkDragSource *source, g_signal_connect (dest, "drop", G_CALLBACK (item_drag_drop), NULL);
double x, gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (dest));
double y,
ColorSwatch *swatch)
{
return gdk_content_provider_new_typed (GDK_TYPE_RGBA, &swatch->color);
}
static void gesture = gtk_gesture_rotate_new ();
color_swatch_init (ColorSwatch *swatch) g_signal_connect (gesture, "angle-changed", G_CALLBACK (angle_changed), NULL);
{ g_signal_connect (gesture, "end", G_CALLBACK (rotate_done), NULL);
GtkDragSource *source = gtk_drag_source_new (); gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (gesture));
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 gesture = gtk_gesture_click_new ();
color_swatch_snapshot (GtkWidget *widget, g_signal_connect (gesture, "released", G_CALLBACK (click_done), NULL);
GtkSnapshot *snapshot) gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (gesture));
{
ColorSwatch *swatch = (ColorSwatch *)widget; return 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;
@@ -681,9 +417,9 @@ do_dnd (GtkWidget *do_widget)
{ {
if (!window) if (!window)
{ {
GtkWidget *button;
GtkWidget *sw; GtkWidget *sw;
GtkWidget *canvas; GtkWidget *canvas;
GtkWidget *widget;
GtkWidget *box, *box2, *box3; GtkWidget *box, *box2, *box3;
const char *colors[] = { const char *colors[] = {
"red", "green", "blue", "magenta", "orange", "gray", "black", "yellow", "red", "green", "blue", "magenta", "orange", "gray", "black", "yellow",
@@ -693,33 +429,27 @@ do_dnd (GtkWidget *do_widget)
}; };
int i; int i;
int x, y; int x, y;
GtkCssProvider *provider;
button = gtk_color_button_new ();
g_object_unref (g_object_ref_sink (button));
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/dnd/dnd.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
800);
g_object_unref (provider);
widget = gtk_color_button_new ();
gtk_widget_destroy (widget);
window = gtk_window_new (); window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget)); gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Drag-and-Drop"); gtk_window_set_title (GTK_WINDOW (window), "Drag-and-Drop");
gtk_window_set_default_size (GTK_WINDOW (window), 640, 480); gtk_window_set_default_size (GTK_WINDOW (window), 640, 480);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_window_set_child (GTK_WINDOW (window), box); gtk_window_set_child (GTK_WINDOW (window), box);
box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_append (GTK_BOX (box), box2); gtk_container_add (GTK_CONTAINER (box), box2);
canvas = canvas_new (); canvas = canvas_new ();
gtk_box_append (GTK_BOX (box2), canvas); gtk_container_add (GTK_CONTAINER (box2), canvas);
n_items = 0; n_items = 0;
@@ -728,36 +458,43 @@ do_dnd (GtkWidget *do_widget)
{ {
GtkWidget *item; GtkWidget *item;
item = canvas_item_new (); item = canvas_item_new (x, y);
gtk_fixed_put (GTK_FIXED (canvas), item, x, y); gtk_container_add (GTK_CONTAINER (canvas), item);
apply_transform (CANVAS_ITEM (item)); apply_transform (item);
x += 150; x += 150;
y += 100; y += 100;
} }
sw = gtk_scrolled_window_new (); sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
GTK_POLICY_NEVER); GTK_POLICY_NEVER);
gtk_box_append (GTK_BOX (box), sw); gtk_container_add (GTK_CONTAINER (box), sw);
box3 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); box3 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_add_css_class (box3, "linked"); gtk_widget_add_css_class (box3, "linked");
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), box3); gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), box3);
for (i = 0; colors[i]; i++) for (i = 0; colors[i]; i++)
gtk_box_append (GTK_BOX (box3), color_swatch_new (colors[i])); {
GdkRGBA rgba;
GtkWidget *swatch;
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow1")); gdk_rgba_parse (&rgba, colors[i]);
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow2"));
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow3")); swatch = g_object_new (g_type_from_name ("GtkColorSwatch"),
"rgba", &rgba,
"selectable", FALSE,
NULL);
gtk_container_add (GTK_CONTAINER (box3), swatch);
}
} }
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;
} }

View File

@@ -1,37 +0,0 @@
label.canvasitem {
padding: 10px;
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); }
}

View File

@@ -64,8 +64,8 @@ scribble_draw (GtkDrawingArea *da,
/* Draw a rectangle on the screen */ /* Draw a rectangle on the screen */
static void static void
draw_brush (GtkWidget *widget, draw_brush (GtkWidget *widget,
double x, gdouble x,
double y) gdouble y)
{ {
GdkRectangle update_rect; GdkRectangle update_rect;
cairo_t *cr; cairo_t *cr;
@@ -125,164 +125,49 @@ drag_end (GtkGestureDrag *gesture,
} }
static void static void
oval_path (cairo_t *cr, checkerboard_draw (GtkDrawingArea *da,
double xc, double yc, cairo_t *cr,
double xr, double yr) int width,
int height,
gpointer data)
{ {
cairo_save (cr); gint i, j, xcount, ycount;
cairo_translate (cr, xc, yc); #define CHECK_SIZE 10
cairo_scale (cr, 1.0, yr / xr); #define SPACING 2
cairo_move_to (cr, xr, 0.0);
cairo_arc (cr,
0, 0,
xr,
0, 2 * G_PI);
cairo_close_path (cr);
cairo_restore (cr); /* At the start of a draw handler, a clip region has been set on
} * the Cairo context, and the contents have been cleared to the
* widget's background color. The docs for
* gdk_surface_begin_paint_region() give more details on how this
* works.
*/
/* Fill the given area with checks in the standard style xcount = 0;
* for showing compositing effects. i = SPACING;
* while (i < width)
* It would make sense to do this as a repeating surface,
* but most implementations of RENDER currently have broken
* implementations of repeat + transform, even when the
* transform is a translation.
*/
static void
fill_checks (cairo_t *cr,
int x, int y,
int width, int height)
{
int i, j;
#define CHECK_SIZE 16
cairo_rectangle (cr, x, y, width, height);
cairo_set_source_rgb (cr, 0.4, 0.4, 0.4);
cairo_fill (cr);
/* Only works for CHECK_SIZE a power of 2 */
j = x & (-CHECK_SIZE);
for (; j < height; j += CHECK_SIZE)
{ {
i = y & (-CHECK_SIZE); j = SPACING;
for (; i < width; i += CHECK_SIZE) ycount = xcount % 2; /* start with even/odd depending on row */
if ((i / CHECK_SIZE + j / CHECK_SIZE) % 2 == 0) while (j < height)
{
if (ycount % 2)
cairo_set_source_rgb (cr, 0.45777, 0, 0.45777);
else
cairo_set_source_rgb (cr, 1, 1, 1);
/* If we're outside the clip, this will do nothing.
*/
cairo_rectangle (cr, i, j, CHECK_SIZE, CHECK_SIZE); cairo_rectangle (cr, i, j, CHECK_SIZE, CHECK_SIZE);
cairo_fill (cr);
j += CHECK_SIZE + SPACING;
++ycount;
}
i += CHECK_SIZE + SPACING;
++xcount;
} }
cairo_set_source_rgb (cr, 0.7, 0.7, 0.7);
cairo_fill (cr);
#undef CHECK_SIZE
}
/* Draw a red, green, and blue circle equally spaced inside
* the larger circle of radius r at (xc, yc)
*/
static void
draw_3circles (cairo_t *cr,
double xc, double yc,
double radius,
double alpha)
{
double subradius = radius * (2 / 3. - 0.1);
cairo_set_source_rgba (cr, 1., 0., 0., alpha);
oval_path (cr,
xc + radius / 3. * cos (G_PI * (0.5)),
yc - radius / 3. * sin (G_PI * (0.5)),
subradius, subradius);
cairo_fill (cr);
cairo_set_source_rgba (cr, 0., 1., 0., alpha);
oval_path (cr,
xc + radius / 3. * cos (G_PI * (0.5 + 2/.3)),
yc - radius / 3. * sin (G_PI * (0.5 + 2/.3)),
subradius, subradius);
cairo_fill (cr);
cairo_set_source_rgba (cr, 0., 0., 1., alpha);
oval_path (cr,
xc + radius / 3. * cos (G_PI * (0.5 + 4/.3)),
yc - radius / 3. * sin (G_PI * (0.5 + 4/.3)),
subradius, subradius);
cairo_fill (cr);
}
static void
groups_draw (GtkDrawingArea *darea,
cairo_t *cr,
int width,
int height,
gpointer data)
{
cairo_surface_t *overlay, *punch, *circles;
cairo_t *overlay_cr, *punch_cr, *circles_cr;
/* Fill the background */
double radius = 0.5 * (width < height ? width : height) - 10;
double xc = width / 2.;
double yc = height / 2.;
overlay = cairo_surface_create_similar (cairo_get_target (cr),
CAIRO_CONTENT_COLOR_ALPHA,
width, height);
punch = cairo_surface_create_similar (cairo_get_target (cr),
CAIRO_CONTENT_ALPHA,
width, height);
circles = cairo_surface_create_similar (cairo_get_target (cr),
CAIRO_CONTENT_COLOR_ALPHA,
width, height);
fill_checks (cr, 0, 0, width, height);
/* Draw a black circle on the overlay
*/
overlay_cr = cairo_create (overlay);
cairo_set_source_rgb (overlay_cr, 0., 0., 0.);
oval_path (overlay_cr, xc, yc, radius, radius);
cairo_fill (overlay_cr);
/* Draw 3 circles to the punch surface, then cut
* that out of the main circle in the overlay
*/
punch_cr = cairo_create (punch);
draw_3circles (punch_cr, xc, yc, radius, 1.0);
cairo_destroy (punch_cr);
cairo_set_operator (overlay_cr, CAIRO_OPERATOR_DEST_OUT);
cairo_set_source_surface (overlay_cr, punch, 0, 0);
cairo_paint (overlay_cr);
/* Now draw the 3 circles in a subgroup again
* at half intensity, and use OperatorAdd to join up
* without seams.
*/
circles_cr = cairo_create (circles);
cairo_set_operator (circles_cr, CAIRO_OPERATOR_OVER);
draw_3circles (circles_cr, xc, yc, radius, 0.5);
cairo_destroy (circles_cr);
cairo_set_operator (overlay_cr, CAIRO_OPERATOR_ADD);
cairo_set_source_surface (overlay_cr, circles, 0, 0);
cairo_paint (overlay_cr);
cairo_destroy (overlay_cr);
cairo_set_source_surface (cr, overlay, 0, 0);
cairo_paint (cr);
cairo_surface_destroy (overlay);
cairo_surface_destroy (punch);
cairo_surface_destroy (circles);
} }
static void static void
@@ -322,21 +207,22 @@ do_drawingarea (GtkWidget *do_widget)
gtk_window_set_child (GTK_WINDOW (window), vbox); gtk_window_set_child (GTK_WINDOW (window), vbox);
/* /*
* Create the groups area * Create the checkerboard area
*/ */
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"<u>Knockout groups</u>"); "<u>Checkerboard pattern</u>");
gtk_box_append (GTK_BOX (vbox), label); gtk_container_add (GTK_CONTAINER (vbox), label);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_widget_set_vexpand (frame, TRUE); gtk_widget_set_vexpand (frame, TRUE);
gtk_box_append (GTK_BOX (vbox), frame); gtk_container_add (GTK_CONTAINER (vbox), frame);
da = gtk_drawing_area_new (); da = gtk_drawing_area_new ();
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100); gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 100); gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 100);
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), groups_draw, NULL, NULL); gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), checkerboard_draw, NULL, NULL);
gtk_frame_set_child (GTK_FRAME (frame), da); gtk_frame_set_child (GTK_FRAME (frame), da);
/* /*
@@ -346,11 +232,11 @@ do_drawingarea (GtkWidget *do_widget)
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"<u>Scribble area</u>"); "<u>Scribble area</u>");
gtk_box_append (GTK_BOX (vbox), label); gtk_container_add (GTK_CONTAINER (vbox), label);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_widget_set_vexpand (frame, TRUE); gtk_widget_set_vexpand (frame, TRUE);
gtk_box_append (GTK_BOX (vbox), frame); gtk_container_add (GTK_CONTAINER (vbox), frame);
da = gtk_drawing_area_new (); da = gtk_drawing_area_new ();
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100); gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
@@ -374,7 +260,7 @@ do_drawingarea (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;
} }

View File

@@ -1,305 +0,0 @@
/* Drop Downs
*
* The GtkDropDown widget is a modern alternative to GtkComboBox.
* It uses list models instead of tree models, and the content is
* displayed using widgets instead of cell renderers.
*
* The examples here demonstrate how to use different kinds of
* list models with GtkDropDown, how to use search and how to
* display the selected item differently from the presentation
* in the popup.
*/
#include <gtk/gtk.h>
#define STRING_TYPE_HOLDER (string_holder_get_type ())
G_DECLARE_FINAL_TYPE (StringHolder, string_holder, STRING, HOLDER, GObject)
struct _StringHolder {
GObject parent_instance;
char *title;
char *icon;
char *description;
};
G_DEFINE_TYPE (StringHolder, string_holder, G_TYPE_OBJECT);
static void
string_holder_init (StringHolder *holder)
{
}
static void
string_holder_finalize (GObject *object)
{
StringHolder *holder = STRING_HOLDER (object);
g_free (holder->title);
g_free (holder->icon);
g_free (holder->description);
G_OBJECT_CLASS (string_holder_parent_class)->finalize (object);
}
static void
string_holder_class_init (StringHolderClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = string_holder_finalize;
}
static StringHolder *
string_holder_new (const char *title, const char *icon, const char *description)
{
StringHolder *holder = g_object_new (STRING_TYPE_HOLDER, NULL);
holder->title = g_strdup (title);
holder->icon = g_strdup (icon);
holder->description = g_strdup (description);
return holder;
}
static void
strings_setup_item_single_line (GtkSignalListItemFactory *factory,
GtkListItem *item)
{
GtkWidget *box, *image, *title;
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
image = gtk_image_new ();
title = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (title), 0.0);
gtk_box_append (GTK_BOX (box), image);
gtk_box_append (GTK_BOX (box), title);
g_object_set_data (G_OBJECT (item), "title", title);
g_object_set_data (G_OBJECT (item), "image", image);
gtk_list_item_set_child (item, box);
}
static void
strings_setup_item_full (GtkSignalListItemFactory *factory,
GtkListItem *item)
{
GtkWidget *box, *box2, *image, *title, *description;
image = gtk_image_new ();
title = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (title), 0.0);
description = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (description), 0.0);
gtk_widget_add_css_class (description, "dim-label");
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_box_append (GTK_BOX (box), image);
gtk_box_append (GTK_BOX (box), box2);
gtk_box_append (GTK_BOX (box2), title);
gtk_box_append (GTK_BOX (box2), description);
g_object_set_data (G_OBJECT (item), "title", title);
g_object_set_data (G_OBJECT (item), "image", image);
g_object_set_data (G_OBJECT (item), "description", description);
gtk_list_item_set_child (item, box);
}
static void
strings_bind_item (GtkSignalListItemFactory *factory,
GtkListItem *item)
{
GtkWidget *image, *title, *description;
StringHolder *holder;
holder = gtk_list_item_get_item (item);
title = g_object_get_data (G_OBJECT (item), "title");
image = g_object_get_data (G_OBJECT (item), "image");
description = g_object_get_data (G_OBJECT (item), "description");
gtk_label_set_label (GTK_LABEL (title), holder->title);
if (image)
{
gtk_image_set_from_icon_name (GTK_IMAGE (image), holder->icon);
gtk_widget_set_visible (image, holder->icon != NULL);
}
if (description)
{
gtk_label_set_label (GTK_LABEL (description), holder->description);
gtk_widget_set_visible (description , holder->description != NULL);
}
}
static GtkListItemFactory *
strings_factory_new (gboolean full)
{
GtkListItemFactory *factory;
factory = gtk_signal_list_item_factory_new ();
if (full)
g_signal_connect (factory, "setup", G_CALLBACK (strings_setup_item_full), NULL);
else
g_signal_connect (factory, "setup", G_CALLBACK (strings_setup_item_single_line), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (strings_bind_item), NULL);
return factory;
}
static GListModel *
strings_model_new (const char *const *titles,
const char *const *icons,
const char *const *descriptions)
{
GListStore *store;
int i;
store = g_list_store_new (STRING_TYPE_HOLDER);
for (i = 0; titles[i]; i++)
{
StringHolder *holder = string_holder_new (titles[i],
icons ? icons[i] : NULL,
descriptions ? descriptions[i] : NULL);
g_list_store_append (store, holder);
g_object_unref (holder);
}
return G_LIST_MODEL (store);
}
static GtkWidget *
drop_down_new_from_strings (const char *const *titles,
const char *const *icons,
const char *const *descriptions)
{
GtkWidget *widget;
GListModel *model;
GtkListItemFactory *factory;
GtkListItemFactory *list_factory;
g_return_val_if_fail (titles != NULL, NULL);
g_return_val_if_fail (icons == NULL || g_strv_length ((char **)icons) == g_strv_length ((char **)titles), NULL);
g_return_val_if_fail (descriptions == NULL || g_strv_length ((char **)icons) == g_strv_length ((char **)descriptions), NULL);
model = strings_model_new (titles, icons, descriptions);
factory = strings_factory_new (FALSE);
if (icons != NULL || descriptions != NULL)
list_factory = strings_factory_new (TRUE);
else
list_factory = NULL;
widget = g_object_new (GTK_TYPE_DROP_DOWN,
"model", model,
"factory", factory,
"list-factory", list_factory,
NULL);
g_object_unref (model);
g_object_unref (factory);
if (list_factory)
g_object_unref (list_factory);
return widget;
}
static char *
get_family_name (gpointer item)
{
return g_strdup (pango_font_family_get_name (PANGO_FONT_FAMILY (item)));
}
static char *
get_title (gpointer item)
{
return g_strdup (STRING_HOLDER (item)->title);
}
GtkWidget *
do_dropdown (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
GtkWidget *button, *box, *spin, *check;
GListModel *model;
GtkExpression *expression;
const char * const times[] = { "1 minute", "2 minutes", "5 minutes", "20 minutes", NULL };
const char * const many_times[] = {
"1 minute", "2 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes",
"25 minutes", "30 minutes", "35 minutes", "40 minutes", "45 minutes", "50 minutes",
"55 minutes", "1 hour", "2 hours", "3 hours", "5 hours", "6 hours", "7 hours",
"8 hours", "9 hours", "10 hours", "11 hours", "12 hours", NULL
};
const char * const device_titles[] = { "Digital Output", "Headphones", "Digital Output", "Analog Output", NULL };
const char * const device_icons[] = { "audio-card-symbolic", "audio-headphones-symbolic", "audio-card-symbolic", "audio-card-symbolic", NULL };
const char * const device_descriptions[] = {
"Built-in Audio", "Built-in audio", "Thinkpad Tunderbolt 3 Dock USB Audio", "Thinkpad Tunderbolt 3 Dock USB Audio", NULL
};
if (!window)
{
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Drop Downs");
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
gtk_widget_set_margin_start (box, 10);
gtk_widget_set_margin_end (box, 10);
gtk_widget_set_margin_top (box, 10);
gtk_widget_set_margin_bottom (box, 10);
gtk_window_set_child (GTK_WINDOW (window), box);
button = gtk_drop_down_new ();
model = G_LIST_MODEL (pango_cairo_font_map_get_default ());
gtk_drop_down_set_model (GTK_DROP_DOWN (button), model);
gtk_drop_down_set_selected (GTK_DROP_DOWN (button), 0);
expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
0, NULL,
(GCallback)get_family_name,
NULL, NULL);
gtk_drop_down_set_expression (GTK_DROP_DOWN (button), expression);
gtk_expression_unref (expression);
gtk_box_append (GTK_BOX (box), button);
spin = gtk_spin_button_new_with_range (-1, g_list_model_get_n_items (G_LIST_MODEL (model)), 1);
gtk_widget_set_halign (spin, GTK_ALIGN_START);
g_object_bind_property (button, "selected", spin, "value", G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
gtk_box_append (GTK_BOX (box), spin);
check = gtk_check_button_new_with_label ("Enable search");
g_object_bind_property (button, "enable-search", check, "active", G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
gtk_box_append (GTK_BOX (box), check);
g_object_unref (model);
button = drop_down_new_from_strings (times, NULL, NULL);
gtk_box_append (GTK_BOX (box), button);
button = drop_down_new_from_strings (many_times, NULL, NULL);
gtk_drop_down_set_enable_search (GTK_DROP_DOWN (button), TRUE);
expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
0, NULL,
(GCallback)get_title,
NULL, NULL);
gtk_drop_down_set_expression (GTK_DROP_DOWN (button), expression);
gtk_expression_unref (expression);
gtk_box_append (GTK_BOX (box), button);
button = drop_down_new_from_strings (device_titles, device_icons, device_descriptions);
gtk_box_append (GTK_BOX (box), button);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -16,9 +16,9 @@
typedef struct typedef struct
{ {
int number; gint number;
char *product; gchar *product;
int yummy; gint yummy;
} }
Item; Item;
@@ -74,7 +74,7 @@ add_items (void)
static GtkTreeModel * static GtkTreeModel *
create_items_model (void) create_items_model (void)
{ {
int i = 0; gint i = 0;
GtkListStore *model; GtkListStore *model;
GtkTreeIter iter; GtkTreeIter iter;
@@ -109,7 +109,7 @@ static GtkTreeModel *
create_numbers_model (void) create_numbers_model (void)
{ {
#define N_NUMBERS 10 #define N_NUMBERS 10
int i = 0; gint i = 0;
GtkListStore *model; GtkListStore *model;
GtkTreeIter iter; GtkTreeIter iter;
@@ -192,7 +192,7 @@ remove_item (GtkWidget *widget, gpointer data)
if (gtk_tree_selection_get_selected (selection, NULL, &iter)) if (gtk_tree_selection_get_selected (selection, NULL, &iter))
{ {
int i; gint i;
GtkTreePath *path; GtkTreePath *path;
path = gtk_tree_model_get_path (model, &iter); path = gtk_tree_model_get_path (model, &iter);
@@ -211,7 +211,7 @@ separator_row (GtkTreeModel *model,
gpointer data) gpointer data)
{ {
GtkTreePath *path; GtkTreePath *path;
int idx; gint idx;
path = gtk_tree_model_get_path (model, iter); path = gtk_tree_model_get_path (model, iter);
idx = gtk_tree_path_get_indices (path)[0]; idx = gtk_tree_path_get_indices (path)[0];
@@ -224,7 +224,7 @@ separator_row (GtkTreeModel *model,
static void static void
editing_started (GtkCellRenderer *cell, editing_started (GtkCellRenderer *cell,
GtkCellEditable *editable, GtkCellEditable *editable,
const char *path, const gchar *path,
gpointer data) gpointer data)
{ {
gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (editable), gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (editable),
@@ -233,15 +233,15 @@ editing_started (GtkCellRenderer *cell,
static void static void
cell_edited (GtkCellRendererText *cell, cell_edited (GtkCellRendererText *cell,
const char *path_string, const gchar *path_string,
const char *new_text, const gchar *new_text,
gpointer data) gpointer data)
{ {
GtkTreeModel *model = (GtkTreeModel *)data; GtkTreeModel *model = (GtkTreeModel *)data;
GtkTreePath *path = gtk_tree_path_new_from_string (path_string); GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
GtkTreeIter iter; GtkTreeIter iter;
int column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "column")); gint column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "column"));
gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_get_iter (model, &iter, path);
@@ -249,7 +249,7 @@ cell_edited (GtkCellRendererText *cell,
{ {
case COLUMN_ITEM_NUMBER: case COLUMN_ITEM_NUMBER:
{ {
int i; gint i;
i = gtk_tree_path_get_indices (path)[0]; i = gtk_tree_path_get_indices (path)[0];
g_array_index (articles, Item, i).number = atoi (new_text); g_array_index (articles, Item, i).number = atoi (new_text);
@@ -261,8 +261,8 @@ cell_edited (GtkCellRendererText *cell,
case COLUMN_ITEM_PRODUCT: case COLUMN_ITEM_PRODUCT:
{ {
int i; gint i;
char *old_text; gchar *old_text;
gtk_tree_model_get (model, &iter, column, &old_text, -1); gtk_tree_model_get (model, &iter, column, &old_text, -1);
g_free (old_text); g_free (old_text);
@@ -352,7 +352,8 @@ do_editable_cells (GtkWidget *do_widget)
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), "Editable Cells"); gtk_window_set_title (GTK_WINDOW (window), "Editable Cells");
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, 5); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
gtk_widget_set_margin_start (vbox, 5); gtk_widget_set_margin_start (vbox, 5);
@@ -361,15 +362,15 @@ do_editable_cells (GtkWidget *do_widget)
gtk_widget_set_margin_bottom (vbox, 5); gtk_widget_set_margin_bottom (vbox, 5);
gtk_window_set_child (GTK_WINDOW (window), vbox); gtk_window_set_child (GTK_WINDOW (window), vbox);
gtk_box_append (GTK_BOX (vbox), gtk_container_add (GTK_CONTAINER (vbox),
gtk_label_new ("Shopping list (you can edit the cells!)")); gtk_label_new ("Shopping list (you can edit the cells!)"));
sw = gtk_scrolled_window_new (); sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE); gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC); GTK_POLICY_AUTOMATIC);
gtk_box_append (GTK_BOX (vbox), sw); gtk_container_add (GTK_CONTAINER (vbox), sw);
/* create models */ /* create models */
items_model = create_items_model (); items_model = create_items_model ();
@@ -391,17 +392,17 @@ do_editable_cells (GtkWidget *do_widget)
/* some buttons */ /* some buttons */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE); gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
gtk_box_append (GTK_BOX (vbox), hbox); gtk_container_add (GTK_CONTAINER (vbox), hbox);
button = gtk_button_new_with_label ("Add item"); button = gtk_button_new_with_label ("Add item");
g_signal_connect (button, "clicked", g_signal_connect (button, "clicked",
G_CALLBACK (add_item), treeview); G_CALLBACK (add_item), treeview);
gtk_box_append (GTK_BOX (hbox), button); gtk_container_add (GTK_CONTAINER (hbox), button);
button = gtk_button_new_with_label ("Remove item"); button = gtk_button_new_with_label ("Remove item");
g_signal_connect (button, "clicked", g_signal_connect (button, "clicked",
G_CALLBACK (remove_item), treeview); G_CALLBACK (remove_item), treeview);
gtk_box_append (GTK_BOX (hbox), button); gtk_container_add (GTK_CONTAINER (hbox), button);
gtk_window_set_default_size (GTK_WINDOW (window), 320, 200); gtk_window_set_default_size (GTK_WINDOW (window), 320, 200);
} }
@@ -409,7 +410,7 @@ do_editable_cells (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;
} }

View File

@@ -1,4 +1,4 @@
/* Entry/Completion /* Entry/Entry Completion
* *
* GtkEntryCompletion provides a mechanism for adding support for * GtkEntryCompletion provides a mechanism for adding support for
* completion in GtkEntry. * completion in GtkEntry.
@@ -12,48 +12,22 @@
static GtkTreeModel * static GtkTreeModel *
create_completion_model (void) create_completion_model (void)
{ {
const char *strings[] = {
"GNOME",
"gnominious",
"Gnomonic projection",
"Gnosophy",
"total",
"totally",
"toto",
"tottery",
"totterer",
"Totten trust",
"Tottenham hotspurs",
"totipotent",
"totipotency",
"totemism",
"totem pole",
"Totara",
"totalizer",
"totalizator",
"totalitarianism",
"total parenteral nutrition",
"total eclipse",
"Totipresence",
"Totipalmi",
"zombie",
"aæx",
"aæy",
"aæz",
NULL
};
int i;
GtkListStore *store; GtkListStore *store;
GtkTreeIter iter; GtkTreeIter iter;
store = gtk_list_store_new (1, G_TYPE_STRING); store = gtk_list_store_new (1, G_TYPE_STRING);
for (i = 0; strings[i]; i++) /* Append one word */
{ gtk_list_store_append (store, &iter);
/* Append one word */ gtk_list_store_set (store, &iter, 0, "GNOME", -1);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, strings[i], -1); /* Append another word */
} gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "total", -1);
/* And another word */
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, "totally", -1);
return GTK_TREE_MODEL (store); return GTK_TREE_MODEL (store);
} }
@@ -74,9 +48,11 @@ do_entry_completion (GtkWidget *do_widget)
window = gtk_window_new (); window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget)); gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Completion"); gtk_window_set_title (GTK_WINDOW (window), "Entry Completion");
gtk_window_set_resizable (GTK_WINDOW (window), FALSE); 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);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
gtk_widget_set_margin_start (vbox, 5); gtk_widget_set_margin_start (vbox, 5);
@@ -86,12 +62,12 @@ do_entry_completion (GtkWidget *do_widget)
gtk_window_set_child (GTK_WINDOW (window), vbox); gtk_window_set_child (GTK_WINDOW (window), vbox);
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), "Try writing <b>total</b> or <b>gnome</b> for example."); gtk_label_set_markup (GTK_LABEL (label), "Completion demo, try writing <b>total</b> or <b>gnome</b> for example.");
gtk_box_append (GTK_BOX (vbox), label); gtk_container_add (GTK_CONTAINER (vbox), label);
/* Create our entry */ /* Create our entry */
entry = gtk_entry_new (); entry = gtk_entry_new ();
gtk_box_append (GTK_BOX (vbox), entry); gtk_container_add (GTK_CONTAINER (vbox), entry);
/* Create the completion object */ /* Create the completion object */
completion = gtk_entry_completion_new (); completion = gtk_entry_completion_new ();
@@ -107,15 +83,12 @@ do_entry_completion (GtkWidget *do_widget)
/* Use model column 0 as the text column */ /* Use model column 0 as the text column */
gtk_entry_completion_set_text_column (completion, 0); gtk_entry_completion_set_text_column (completion, 0);
gtk_entry_completion_set_inline_completion (completion, TRUE);
gtk_entry_completion_set_inline_selection (completion, TRUE);
} }
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;
} }

View File

@@ -1,8 +1,8 @@
/* Entry/Undo and Redo /* Entry/Entry Undo
* *
* GtkEntry can provide basic Undo/Redo support using standard keyboard * GtkEntry can provide basic Undo/Redo support using standard keyboard
* accelerators such as Control+z to undo and Control+Shift+z to redo. * accelerators such as Primary+z to undo and Primary+Shift+z to redo.
* Additionally, Control+y can be used to redo. * Additionally, Primary+y can be used to redo.
* *
* Use gtk_entry_set_enable_undo() to enable undo/redo support. * Use gtk_entry_set_enable_undo() to enable undo/redo support.
*/ */
@@ -23,9 +23,10 @@ do_entry_undo (GtkWidget *do_widget)
window = gtk_window_new (); window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget)); gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Undo and Redo"); gtk_window_set_title (GTK_WINDOW (window), "Entry Undo");
gtk_window_set_resizable (GTK_WINDOW (window), FALSE); 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);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
gtk_widget_set_margin_start (vbox, 5); gtk_widget_set_margin_start (vbox, 5);
@@ -37,18 +38,18 @@ do_entry_undo (GtkWidget *do_widget)
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"Use Primary+z or Primary+Shift+z to undo or redo changes"); "Use Primary+z or Primary+Shift+z to undo or redo changes");
gtk_box_append (GTK_BOX (vbox), label); gtk_container_add (GTK_CONTAINER (vbox), label);
/* Create our entry */ /* Create our entry */
entry = gtk_entry_new (); entry = gtk_entry_new ();
gtk_editable_set_enable_undo (GTK_EDITABLE (entry), TRUE); gtk_editable_set_enable_undo (GTK_EDITABLE (entry), TRUE);
gtk_box_append (GTK_BOX (vbox), entry); gtk_container_add (GTK_CONTAINER (vbox), 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;
} }

View File

@@ -13,9 +13,9 @@
static GtkWidget *window = NULL; static GtkWidget *window = NULL;
static void static void
response_cb (GtkDialog *dialog, int response_id) response_cb (GtkDialog *dialog, gint response_id)
{ {
gtk_window_destroy (GTK_WINDOW (window)); gtk_widget_destroy (window);
window = NULL; window = NULL;
} }
@@ -57,7 +57,7 @@ do_expander (GtkWidget *do_widget)
expander = gtk_expander_new ("Details:"); expander = gtk_expander_new ("Details:");
gtk_widget_set_vexpand (expander, TRUE); gtk_widget_set_vexpand (expander, TRUE);
sw = gtk_scrolled_window_new (); sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (sw), 100); gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (sw), 100);
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE); gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
@@ -79,8 +79,8 @@ do_expander (GtkWidget *do_widget)
"innuendo, just to make you scroll down or " "innuendo, just to make you scroll down or "
"resize the window. Do it already !", -1); "resize the window. Do it already !", -1);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), tv); gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), tv);
gtk_expander_set_child (GTK_EXPANDER (expander), sw); gtk_container_add (GTK_CONTAINER (expander), sw);
gtk_box_append (GTK_BOX (area), expander); gtk_container_add (GTK_CONTAINER (area), expander);
g_signal_connect (expander, "notify::expanded", g_signal_connect (expander, "notify::expanded",
G_CALLBACK (expander_cb), window); G_CALLBACK (expander_cb), window);
@@ -90,7 +90,7 @@ do_expander (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;
} }

View File

@@ -22,8 +22,8 @@ format_number (GtkTreeViewColumn *col,
GtkTreeIter *iter, GtkTreeIter *iter,
gpointer data) gpointer data)
{ {
int num; gint num;
char *text; gchar *text;
gtk_tree_model_get (model, iter, GPOINTER_TO_INT (data), &num, -1); gtk_tree_model_get (model, iter, GPOINTER_TO_INT (data), &num, -1);
text = g_strdup_printf ("%d", num); text = g_strdup_printf ("%d", num);
@@ -35,11 +35,11 @@ static void
filter_modify_func (GtkTreeModel *model, filter_modify_func (GtkTreeModel *model,
GtkTreeIter *iter, GtkTreeIter *iter,
GValue *value, GValue *value,
int column, gint column,
gpointer data) gpointer data)
{ {
GtkTreeModelFilter *filter_model = GTK_TREE_MODEL_FILTER (model); GtkTreeModelFilter *filter_model = GTK_TREE_MODEL_FILTER (model);
int width, height; gint width, height;
GtkTreeModel *child_model; GtkTreeModel *child_model;
GtkTreeIter child_iter; GtkTreeIter child_iter;
@@ -75,7 +75,7 @@ visible_func (GtkTreeModel *model,
GtkTreeIter *iter, GtkTreeIter *iter,
gpointer data) gpointer data)
{ {
int width; gint width;
gtk_tree_model_get (model, iter, gtk_tree_model_get (model, iter,
WIDTH_COLUMN, &width, WIDTH_COLUMN, &width,
@@ -125,7 +125,8 @@ do_filtermodel (GtkWidget *do_widget)
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);
store = (GtkListStore*)gtk_builder_get_object (builder, "liststore1"); store = (GtkListStore*)gtk_builder_get_object (builder, "liststore1");
@@ -198,7 +199,7 @@ do_filtermodel (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;
} }

View File

@@ -249,14 +249,6 @@ fishbowl_changes_toggled_cb (GtkToggleButton *button,
gtk_button_set_icon_name (GTK_BUTTON (button), "changes-allow"); gtk_button_set_icon_name (GTK_BUTTON (button), "changes-allow");
} }
char *
format_header_cb (GObject *object,
guint count,
double fps)
{
return g_strdup_printf ("%u Icons, %.2f fps", count, fps);
}
GtkWidget * GtkWidget *
do_fishbowl (GtkWidget *do_widget) do_fishbowl (GtkWidget *do_widget)
{ {
@@ -281,13 +273,15 @@ do_fishbowl (GtkWidget *do_widget)
builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui"); builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window")); window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window); g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl")); bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl"));
selected_widget_type = -1; selected_widget_type = -1;
set_widget_type (GTK_FISHBOWL (bowl), 0); set_widget_type (GTK_FISHBOWL (bowl), 0);
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_CALLBACK (gtk_widget_destroyed), &window);
gtk_widget_realize (window); gtk_widget_realize (window);
g_object_unref (builder); g_object_unref (builder);
@@ -296,7 +290,7 @@ do_fishbowl (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;
} }

View File

@@ -6,6 +6,7 @@
<property name="default-height">400</property> <property name="default-height">400</property>
<child type="titlebar"> <child type="titlebar">
<object class="GtkHeaderBar" id=""> <object class="GtkHeaderBar" id="">
<property name="show-title-buttons">1</property>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<style> <style>
@@ -27,12 +28,22 @@
</child> </child>
<child type="end"> <child type="end">
<object class="GtkLabel"> <object class="GtkLabel">
<binding name="label"> <property name="label">fps</property>
<closure type="gchararray" function="format_header_cb"> </object>
<lookup name="count">bowl</lookup> </child>
<lookup name="framerate">bowl</lookup> <child type="end">
</closure> <object class="GtkLabel">
</binding> <property name="label" bind-source="bowl" bind-property="framerate-string"/>
</object>
</child>
<child type="end">
<object class="GtkLabel">
<property name="label">Icons, </property>
</object>
</child>
<child type="end">
<object class="GtkLabel">
<property name="label" bind-source="bowl" bind-property="count"/>
</object> </object>
</child> </child>
<child type="end"> <child type="end">
@@ -47,7 +58,6 @@
<child> <child>
<object class="GtkFishbowl" id="bowl"> <object class="GtkFishbowl" id="bowl">
<property name="visible">True</property> <property name="visible">True</property>
<property name="overflow">hidden</property>
<property name="animating">True</property> <property name="animating">True</property>
<property name="benchmark" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean | sync-create"/> <property name="benchmark" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean | sync-create"/>
</object> </object>

View File

@@ -1,4 +1,4 @@
/* Fixed Layout /* Fixed layout
* *
* GtkFixed is a container that allows placing and transforming * GtkFixed is a container that allows placing and transforming
* widgets manually. * widgets manually.
@@ -53,7 +53,7 @@ create_faces (void)
faces[i].face = gtk_frame_new (NULL); faces[i].face = gtk_frame_new (NULL);
gtk_widget_set_size_request (faces[i].face, face_size, face_size); gtk_widget_set_size_request (faces[i].face, face_size, face_size);
gtk_widget_add_css_class (faces[i].face, faces[i].css_class); gtk_widget_add_css_class (faces[i].face, faces[i].css_class);
gtk_fixed_put (GTK_FIXED (fixed), faces[i].face, 0, 0); gtk_container_add (GTK_CONTAINER (fixed), faces[i].face);
/* Set up the transformation for each face */ /* Set up the transformation for each face */
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (w, h)); transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (w, h));
@@ -126,11 +126,11 @@ create_demo_window (GtkWidget *do_widget)
window = gtk_window_new (); window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget)); gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Fixed Layout"); gtk_window_set_title (GTK_WINDOW (window), "Fixed layout");
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400); gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL); g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
sw = gtk_scrolled_window_new (); sw = gtk_scrolled_window_new (NULL, NULL);
gtk_window_set_child (GTK_WINDOW (window), sw); gtk_window_set_child (GTK_WINDOW (window), sw);
fixed = gtk_fixed_new (); fixed = gtk_fixed_new ();
@@ -139,7 +139,7 @@ create_demo_window (GtkWidget *do_widget)
gtk_widget_set_valign (GTK_WIDGET (fixed), GTK_ALIGN_CENTER); gtk_widget_set_valign (GTK_WIDGET (fixed), GTK_ALIGN_CENTER);
cube = create_faces (); cube = create_faces ();
gtk_fixed_put (GTK_FIXED (fixed), cube, 0, 0); gtk_container_add (GTK_CONTAINER (fixed), cube);
gtk_widget_set_overflow (fixed, GTK_OVERFLOW_VISIBLE); gtk_widget_set_overflow (fixed, GTK_OVERFLOW_VISIBLE);
provider = gtk_css_provider_new (); provider = gtk_css_provider_new ();
@@ -161,7 +161,7 @@ do_fixed (GtkWidget *do_widget)
if (!gtk_widget_get_visible (demo_window)) if (!gtk_widget_get_visible (demo_window))
gtk_widget_show (demo_window); gtk_widget_show (demo_window);
else else
gtk_window_destroy (GTK_WINDOW (demo_window)); gtk_widget_destroy (demo_window);
return demo_window; return demo_window;
} }

View File

@@ -1,10 +1,9 @@
/* Flow Box /* Flow Box
* *
* GtkFlowBox allows flexible and responsive grids which reflow * GtkFlowBox allows flexible and responsive grids which reflow
* as needed and support sorting and filtering. The children of * as needed and support sorting and filtering.
* a GtkFlowBox are regular widgets
* *
* The dataset used here has 665 colors. * The children of a GtkFlowBox are regular widgets
*/ */
#include <gtk/gtk.h> #include <gtk/gtk.h>
@@ -29,7 +28,7 @@ draw_color (GtkDrawingArea *drawingarea,
} }
static GtkWidget * static GtkWidget *
color_swatch_new (const char *color) color_swatch_new (const gchar *color)
{ {
GtkWidget *button, *area; GtkWidget *button, *area;
@@ -48,7 +47,7 @@ do_flowbox (GtkWidget *do_widget)
{ {
static GtkWidget *window = NULL; static GtkWidget *window = NULL;
GtkWidget *scrolled, *flowbox; GtkWidget *scrolled, *flowbox;
const char *colors[] = { const gchar *colors[] = {
"AliceBlue", "AliceBlue",
"AntiqueWhite", "AntiqueWhite",
"AntiqueWhite1", "AntiqueWhite1",
@@ -716,7 +715,7 @@ do_flowbox (GtkWidget *do_widget)
"YellowGreen", "YellowGreen",
NULL NULL
}; };
int i; gint i;
if (!window) if (!window)
{ {
@@ -725,9 +724,11 @@ do_flowbox (GtkWidget *do_widget)
gtk_widget_get_display (do_widget)); gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Flow Box"); gtk_window_set_title (GTK_WINDOW (window), "Flow Box");
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600); gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
scrolled = gtk_scrolled_window_new (); g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
flowbox = gtk_flow_box_new (); flowbox = gtk_flow_box_new ();
gtk_widget_set_valign (flowbox, GTK_ALIGN_START); gtk_widget_set_valign (flowbox, GTK_ALIGN_START);
@@ -738,13 +739,13 @@ do_flowbox (GtkWidget *do_widget)
gtk_window_set_child (GTK_WINDOW (window), scrolled); gtk_window_set_child (GTK_WINDOW (window), scrolled);
for (i = 0; colors[i]; i++) for (i = 0; colors[i]; i++)
gtk_flow_box_insert (GTK_FLOW_BOX (flowbox), color_swatch_new (colors[i]), -1); gtk_container_add (GTK_CONTAINER (flowbox), color_swatch_new (colors[i]));
} }
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;
} }

View File

@@ -7,6 +7,7 @@
<property name="title">Font Explorer</property> <property name="title">Font Explorer</property>
<child type="titlebar"> <child type="titlebar">
<object class="GtkHeaderBar"> <object class="GtkHeaderBar">
<property name="show-title-buttons">1</property>
<child> <child>
<object class="GtkButton" id="reset"> <object class="GtkButton" id="reset">
<property name="receives-default">1</property> <property name="receives-default">1</property>

View File

@@ -194,7 +194,7 @@ add_check_group (GtkWidget *box,
pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD)); pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
gtk_label_set_attributes (GTK_LABEL (label), attrs); gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs); pango_attr_list_unref (attrs);
gtk_box_append (GTK_BOX (group), label); gtk_container_add (GTK_CONTAINER (group), label);
for (i = 0; tags[i]; i++) for (i = 0; tags[i]; i++)
{ {
@@ -211,7 +211,7 @@ add_check_group (GtkWidget *box,
g_signal_connect (feat, "notify::inconsistent", G_CALLBACK (update_display), NULL); g_signal_connect (feat, "notify::inconsistent", G_CALLBACK (update_display), NULL);
g_signal_connect (feat, "clicked", G_CALLBACK (feat_clicked), NULL); g_signal_connect (feat, "clicked", G_CALLBACK (feat_clicked), NULL);
gtk_box_append (GTK_BOX (group), feat); gtk_container_add (GTK_CONTAINER (group), feat);
item = g_new (FeatureItem, 1); item = g_new (FeatureItem, 1);
item->name = tags[i]; item->name = tags[i];
@@ -223,7 +223,7 @@ add_check_group (GtkWidget *box,
feature_items = g_list_prepend (feature_items, item); feature_items = g_list_prepend (feature_items, item);
} }
gtk_box_append (GTK_BOX (box), group); gtk_container_add (GTK_CONTAINER (box), group);
} }
static void static void
@@ -248,7 +248,7 @@ add_radio_group (GtkWidget *box,
pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD)); pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
gtk_label_set_attributes (GTK_LABEL (label), attrs); gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs); pango_attr_list_unref (attrs);
gtk_box_append (GTK_BOX (group), label); gtk_container_add (GTK_CONTAINER (group), label);
for (i = 0; tags[i]; i++) for (i = 0; tags[i]; i++)
{ {
@@ -268,7 +268,7 @@ add_radio_group (GtkWidget *box,
g_signal_connect (feat, "notify::active", G_CALLBACK (update_display), NULL); g_signal_connect (feat, "notify::active", G_CALLBACK (update_display), NULL);
g_object_set_data (G_OBJECT (feat), "default", group_button); g_object_set_data (G_OBJECT (feat), "default", group_button);
gtk_box_append (GTK_BOX (group), feat); gtk_container_add (GTK_CONTAINER (group), feat);
item = g_new (FeatureItem, 1); item = g_new (FeatureItem, 1);
item->name = tags[i]; item->name = tags[i];
@@ -280,7 +280,7 @@ add_radio_group (GtkWidget *box,
feature_items = g_list_prepend (feature_items, item); feature_items = g_list_prepend (feature_items, item);
} }
gtk_box_append (GTK_BOX (box), group); gtk_container_add (GTK_CONTAINER (box), group);
} }
static void static void
@@ -295,7 +295,7 @@ update_display (void)
GList *l; GList *l;
PangoAttrList *attrs; PangoAttrList *attrs;
PangoAttribute *attr; PangoAttribute *attr;
int ins, bound; gint ins, bound;
guint start, end; guint start, end;
PangoLanguage *lang; PangoLanguage *lang;
char *font_desc; char *font_desc;
@@ -479,7 +479,7 @@ update_script_combo (void)
{ {
GtkListStore *store; GtkListStore *store;
hb_font_t *hb_font; hb_font_t *hb_font;
int i, j, k; gint i, j, k;
PangoFont *pango_font; PangoFont *pango_font;
GHashTable *tags; GHashTable *tags;
GHashTableIter iter; GHashTableIter iter;
@@ -593,7 +593,7 @@ update_script_combo (void)
static void static void
update_features (void) update_features (void)
{ {
int i, j; gint i, j;
GtkTreeModel *model; GtkTreeModel *model;
GtkTreeIter iter; GtkTreeIter iter;
guint script_index, lang_index; guint script_index, lang_index;
@@ -728,8 +728,8 @@ static void
entry_activated (GtkEntry *entry, entry_activated (GtkEntry *entry,
GtkAdjustment *adjustment) GtkAdjustment *adjustment)
{ {
double value; gdouble value;
char *err = NULL; gchar *err = NULL;
value = g_strtod (gtk_editable_get_text (GTK_EDITABLE (entry)), &err); value = g_strtod (gtk_editable_get_text (GTK_EDITABLE (entry)), &err);
if (err != NULL) if (err != NULL)
@@ -939,7 +939,7 @@ instance_changed (GtkComboBox *combo)
{ {
Axis *axis; Axis *axis;
Axis akey; Axis akey;
double value; gdouble value;
value = coords[ai[i].axis_index]; value = coords[ai[i].axis_index];
@@ -1025,7 +1025,7 @@ denorm_coord (hb_ot_var_axis_info_t *axis, int coord)
static void static void
update_font_variations (void) update_font_variations (void)
{ {
GtkWidget *child; GtkWidget *child, *next;
PangoFont *pango_font = NULL; PangoFont *pango_font = NULL;
hb_font_t *hb_font; hb_font_t *hb_font;
hb_face_t *hb_face; hb_face_t *hb_face;
@@ -1037,8 +1037,12 @@ update_font_variations (void)
int i; int i;
child = gtk_widget_get_first_child (variations_grid); child = gtk_widget_get_first_child (variations_grid);
while ((child = gtk_widget_get_first_child (variations_grid))) while (child != NULL)
gtk_grid_remove (GTK_GRID (variations_grid), child); {
next = gtk_widget_get_next_sibling (child);
gtk_widget_destroy (child);
child = next;
}
instance_combo = NULL; instance_combo = NULL;
@@ -1329,7 +1333,8 @@ do_font_features (GtkWidget *do_widget)
font_features_font_changed (); font_features_font_changed ();
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window); g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
g_object_unref (builder); g_object_unref (builder);
@@ -1339,7 +1344,7 @@ do_font_features (GtkWidget *do_widget)
if (!gtk_widget_get_visible (window)) if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window)); gtk_window_present (GTK_WINDOW (window));
else else
gtk_window_destroy (GTK_WINDOW (window)); gtk_widget_destroy (window);
return window; return window;
} }

View File

@@ -36,11 +36,11 @@ adjustment_get_normalized_value (GtkAdjustment *adj)
static void static void
val_to_xy (GtkFontPlane *plane, val_to_xy (GtkFontPlane *plane,
int *x, gint *x,
int *y) gint *y)
{ {
double u, v; gdouble u, v;
int width, height; gint width, height;
width = gtk_widget_get_allocated_width (GTK_WIDGET (plane)); width = gtk_widget_get_allocated_width (GTK_WIDGET (plane));
height = gtk_widget_get_allocated_height (GTK_WIDGET (plane)); height = gtk_widget_get_allocated_height (GTK_WIDGET (plane));
@@ -57,8 +57,8 @@ plane_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot) GtkSnapshot *snapshot)
{ {
GtkFontPlane *plane = GTK_FONT_PLANE (widget); GtkFontPlane *plane = GTK_FONT_PLANE (widget);
int x, y; gint x, y;
int width, height; gint width, height;
cairo_t *cr; cairo_t *cr;
val_to_xy (plane, &x, &y); val_to_xy (plane, &x, &y);
@@ -125,11 +125,11 @@ adjustment_set_normalized_value (GtkAdjustment *adj,
static void static void
update_value (GtkFontPlane *plane, update_value (GtkFontPlane *plane,
int x, gint x,
int y) gint y)
{ {
GtkWidget *widget = GTK_WIDGET (plane); GtkWidget *widget = GTK_WIDGET (plane);
double u, v; gdouble u, v;
u = CLAMP (x * (1.0 / gtk_widget_get_allocated_width (widget)), 0, 1); u = CLAMP (x * (1.0 / gtk_widget_get_allocated_width (widget)), 0, 1);
v = CLAMP (1 - y * (1.0 / gtk_widget_get_allocated_height (widget)), 0, 1); v = CLAMP (1 - y * (1.0 / gtk_widget_get_allocated_height (widget)), 0, 1);
@@ -142,8 +142,8 @@ update_value (GtkFontPlane *plane,
static void static void
plane_drag_gesture_begin (GtkGestureDrag *gesture, plane_drag_gesture_begin (GtkGestureDrag *gesture,
double start_x, gdouble start_x,
double start_y, gdouble start_y,
GtkFontPlane *plane) GtkFontPlane *plane)
{ {
guint button; guint button;
@@ -164,11 +164,11 @@ plane_drag_gesture_begin (GtkGestureDrag *gesture,
static void static void
plane_drag_gesture_update (GtkGestureDrag *gesture, plane_drag_gesture_update (GtkGestureDrag *gesture,
double offset_x, gdouble offset_x,
double offset_y, gdouble offset_y,
GtkFontPlane *plane) GtkFontPlane *plane)
{ {
double start_x, start_y; gdouble start_x, start_y;
gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (gesture), gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (gesture),
&start_x, &start_y); &start_x, &start_y);
@@ -177,8 +177,8 @@ plane_drag_gesture_update (GtkGestureDrag *gesture,
static void static void
plane_drag_gesture_end (GtkGestureDrag *gesture, plane_drag_gesture_end (GtkGestureDrag *gesture,
double offset_x, gdouble offset_x,
double offset_y, gdouble offset_y,
GtkFontPlane *plane) GtkFontPlane *plane)
{ {
set_cross_cursor (GTK_WIDGET (plane), FALSE); set_cross_cursor (GTK_WIDGET (plane), FALSE);

View File

@@ -281,7 +281,7 @@ do_fontrendering (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;
} }

View File

@@ -53,7 +53,7 @@ create_axis_slider (GtkGears *gears,
} }
label = gtk_label_new (text); label = gtk_label_new (text);
gtk_box_append (GTK_BOX (box), label); gtk_container_add (GTK_CONTAINER (box), label);
gtk_widget_show (label); gtk_widget_show (label);
adj = gtk_adjustment_new (gtk_gears_get_axis (gears, axis), 0.0, 360.0, 1.0, 12.0, 0.0); adj = gtk_adjustment_new (gtk_gears_get_axis (gears, axis), 0.0, 360.0, 1.0, 12.0, 0.0);
@@ -63,7 +63,7 @@ create_axis_slider (GtkGears *gears,
gears); gears);
slider = gtk_scale_new (GTK_ORIENTATION_VERTICAL, adj); slider = gtk_scale_new (GTK_ORIENTATION_VERTICAL, adj);
gtk_scale_set_draw_value (GTK_SCALE (slider), FALSE); gtk_scale_set_draw_value (GTK_SCALE (slider), FALSE);
gtk_box_append (GTK_BOX (box), slider); gtk_container_add (GTK_CONTAINER (box), slider);
gtk_widget_set_vexpand (slider, TRUE); gtk_widget_set_vexpand (slider, TRUE);
gtk_widget_show (slider); gtk_widget_show (slider);
@@ -85,7 +85,7 @@ do_gears (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Gears"); gtk_window_set_title (GTK_WINDOW (window), "Gears");
gtk_window_set_resizable (GTK_WINDOW (window), TRUE); gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_default_size (GTK_WINDOW (window), 640, 640); gtk_window_set_default_size (GTK_WINDOW (window), 640, 640);
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 (); overlay = gtk_overlay_new ();
gtk_widget_set_margin_start (overlay, 12); gtk_widget_set_margin_start (overlay, 12);
@@ -111,19 +111,19 @@ do_gears (GtkWidget *do_widget)
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE);
gtk_box_set_spacing (GTK_BOX (box), 6); gtk_box_set_spacing (GTK_BOX (box), 6);
gtk_box_append (GTK_BOX (box), hbox); gtk_container_add (GTK_CONTAINER (box), hbox);
gears = gtk_gears_new (); gears = gtk_gears_new ();
gtk_widget_set_hexpand (gears, TRUE); gtk_widget_set_hexpand (gears, TRUE);
gtk_widget_set_vexpand (gears, TRUE); gtk_widget_set_vexpand (gears, TRUE);
gtk_box_append (GTK_BOX (hbox), gears); gtk_container_add (GTK_CONTAINER (hbox), gears);
for (i = 0; i < GTK_GEARS_N_AXIS; i++) for (i = 0; i < GTK_GEARS_N_AXIS; i++)
gtk_box_append (GTK_BOX (hbox), create_axis_slider (GTK_GEARS (gears), i)); gtk_container_add (GTK_CONTAINER (hbox), create_axis_slider (GTK_GEARS (gears), i));
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE);
gtk_box_set_spacing (GTK_BOX (hbox), 6); gtk_box_set_spacing (GTK_BOX (hbox), 6);
gtk_box_append (GTK_BOX (box), hbox); gtk_container_add (GTK_CONTAINER (box), hbox);
gtk_gears_set_fps_label (GTK_GEARS (gears), GTK_LABEL (fps_label)); gtk_gears_set_fps_label (GTK_GEARS (gears), GTK_LABEL (fps_label));
} }
@@ -131,7 +131,7 @@ do_gears (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;
} }

View File

@@ -13,16 +13,17 @@ in_files = sys.argv[2:]
file_output = """ file_output = """
typedef GtkWidget *(*GDoDemoFunc) (GtkWidget *do_widget); typedef GtkWidget *(*GDoDemoFunc) (GtkWidget *do_widget);
typedef struct _DemoData DemoData; typedef struct _Demo Demo;
struct _DemoData struct _Demo
{ {
const char *name; const char *name;
const char *title; const char *title;
const char *filename; const char *filename;
GDoDemoFunc func; GDoDemoFunc func;
DemoData *children; Demo *children;
}; };
""" """
# Demo = namedtuple('Demo', ['name', 'title', 'file', 'func']) # Demo = namedtuple('Demo', ['name', 'title', 'file', 'func'])
@@ -66,7 +67,7 @@ for demo in demos:
i = 0 i = 0
for parent in parents: for parent in parents:
id = parent_ids[i] id = parent_ids[i]
file_output += "\nDemoData child" + str(id) + "[] = {\n" file_output += "\nDemo child" + str(id) + "[] = {\n"
# iterate over all demos and check if the name starts with the given parent name # iterate over all demos and check if the name starts with the given parent name
for child in demos: for child in demos:
if child[1].startswith(parent + "/"): if child[1].startswith(parent + "/"):
@@ -81,7 +82,7 @@ for parent in parents:
# Sort demos by title # Sort demos by title
demos = sorted(demos, key=lambda x: x[1]) demos = sorted(demos, key=lambda x: x[1])
file_output += "\nDemoData gtk_demos[] = {\n" file_output += "\nDemo gtk_demos[] = {\n"
for demo in demos: for demo in demos:
# Do not generate one of these for demos with a parent demo # Do not generate one of these for demos with a parent demo
if "/" not in demo[1]: if "/" not in demo[1]:

View File

@@ -9,8 +9,8 @@
static GtkGesture *rotate = NULL; static GtkGesture *rotate = NULL;
static GtkGesture *zoom = NULL; static GtkGesture *zoom = NULL;
static double swipe_x = 0; static gdouble swipe_x = 0;
static double swipe_y = 0; static gdouble swipe_y = 0;
static gboolean long_pressed = FALSE; static gboolean long_pressed = FALSE;
static gboolean static gboolean
@@ -26,8 +26,8 @@ touchpad_swipe_gesture_begin (GtkGesture *gesture,
static void static void
swipe_gesture_swept (GtkGestureSwipe *gesture, swipe_gesture_swept (GtkGestureSwipe *gesture,
double velocity_x, gdouble velocity_x,
double velocity_y, gdouble velocity_y,
GtkWidget *widget) GtkWidget *widget)
{ {
swipe_x = velocity_x / 10; swipe_x = velocity_x / 10;
@@ -37,8 +37,8 @@ swipe_gesture_swept (GtkGestureSwipe *gesture,
static void static void
long_press_gesture_pressed (GtkGestureLongPress *gesture, long_press_gesture_pressed (GtkGestureLongPress *gesture,
double x, gdouble x,
double y, gdouble y,
GtkWidget *widget) GtkWidget *widget)
{ {
long_pressed = TRUE; long_pressed = TRUE;
@@ -56,8 +56,8 @@ long_press_gesture_end (GtkGesture *gesture,
static void static void
rotation_angle_changed (GtkGestureRotate *gesture, rotation_angle_changed (GtkGestureRotate *gesture,
double angle, gdouble angle,
double delta, gdouble delta,
GtkWidget *widget) GtkWidget *widget)
{ {
gtk_widget_queue_draw (widget); gtk_widget_queue_draw (widget);
@@ -65,7 +65,7 @@ rotation_angle_changed (GtkGestureRotate *gesture,
static void static void
zoom_scale_changed (GtkGestureZoom *gesture, zoom_scale_changed (GtkGestureZoom *gesture,
double scale, gdouble scale,
GtkWidget *widget) GtkWidget *widget)
{ {
gtk_widget_queue_draw (widget); gtk_widget_queue_draw (widget);
@@ -93,8 +93,8 @@ drawing_area_draw (GtkDrawingArea *area,
{ {
cairo_pattern_t *pat; cairo_pattern_t *pat;
cairo_matrix_t matrix; cairo_matrix_t matrix;
double angle, scale; gdouble angle, scale;
double x_center, y_center; gdouble x_center, y_center;
gtk_gesture_get_bounding_box_center (GTK_GESTURE (zoom), &x_center, &y_center); gtk_gesture_get_bounding_box_center (GTK_GESTURE (zoom), &x_center, &y_center);
@@ -149,7 +149,8 @@ do_gestures (GtkWidget *do_widget)
window = gtk_window_new (); window = gtk_window_new ();
gtk_window_set_default_size (GTK_WINDOW (window), 400, 400); gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
gtk_window_set_title (GTK_WINDOW (window), "Gestures"); gtk_window_set_title (GTK_WINDOW (window), "Gestures");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window); g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
drawing_area = gtk_drawing_area_new (); drawing_area = gtk_drawing_area_new ();
gtk_window_set_child (GTK_WINDOW (window), drawing_area); gtk_window_set_child (GTK_WINDOW (window), drawing_area);
@@ -209,7 +210,7 @@ do_gestures (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;
} }

View File

@@ -354,7 +354,7 @@ create_axis_slider (int axis)
} }
label = gtk_label_new (text); label = gtk_label_new (text);
gtk_box_append (GTK_BOX (box), label); gtk_container_add (GTK_CONTAINER (box), label);
gtk_widget_show (label); gtk_widget_show (label);
adj = gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 12.0, 0.0); adj = gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 12.0, 0.0);
@@ -362,7 +362,7 @@ create_axis_slider (int axis)
G_CALLBACK (on_axis_value_change), G_CALLBACK (on_axis_value_change),
GINT_TO_POINTER (axis)); GINT_TO_POINTER (axis));
slider = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adj); slider = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adj);
gtk_box_append (GTK_BOX (box), slider); gtk_container_add (GTK_CONTAINER (box), slider);
gtk_widget_set_hexpand (slider, TRUE); gtk_widget_set_hexpand (slider, TRUE);
gtk_widget_show (slider); gtk_widget_show (slider);
@@ -406,7 +406,7 @@ create_glarea_window (GtkWidget *do_widget)
gl_area = gtk_gl_area_new (); gl_area = gtk_gl_area_new ();
gtk_widget_set_hexpand (gl_area, TRUE); gtk_widget_set_hexpand (gl_area, TRUE);
gtk_widget_set_vexpand (gl_area, TRUE); gtk_widget_set_vexpand (gl_area, TRUE);
gtk_box_append (GTK_BOX (box), gl_area); gtk_container_add (GTK_CONTAINER (box), gl_area);
/* We need to initialize and free GL resources, so we use /* We need to initialize and free GL resources, so we use
* the realize and unrealize signals on the widget * the realize and unrealize signals on the widget
@@ -418,16 +418,16 @@ create_glarea_window (GtkWidget *do_widget)
g_signal_connect (gl_area, "render", G_CALLBACK (render), NULL); g_signal_connect (gl_area, "render", G_CALLBACK (render), NULL);
controls = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE); controls = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE);
gtk_box_append (GTK_BOX (box), controls); gtk_container_add (GTK_CONTAINER (box), controls);
gtk_widget_set_hexpand (controls, TRUE); gtk_widget_set_hexpand (controls, TRUE);
for (i = 0; i < N_AXIS; i++) for (i = 0; i < N_AXIS; i++)
gtk_box_append (GTK_BOX (controls), create_axis_slider (i)); gtk_container_add (GTK_CONTAINER (controls), create_axis_slider (i));
button = gtk_button_new_with_label ("Quit"); button = gtk_button_new_with_label ("Quit");
gtk_widget_set_hexpand (button, TRUE); gtk_widget_set_hexpand (button, TRUE);
gtk_box_append (GTK_BOX (box), button); gtk_container_add (GTK_CONTAINER (box), button);
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window); g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
return window; return window;
} }
@@ -441,7 +441,7 @@ do_glarea (GtkWidget *do_widget)
if (!gtk_widget_get_visible (demo_window)) if (!gtk_widget_get_visible (demo_window))
gtk_widget_show (demo_window); gtk_widget_show (demo_window);
else else
gtk_window_destroy (GTK_WINDOW (demo_window)); gtk_widget_destroy (demo_window);
return demo_window; return demo_window;
} }

View File

@@ -25,7 +25,7 @@ typedef struct _GtkFishbowlChild GtkFishbowlChild;
struct _GtkFishbowlPrivate struct _GtkFishbowlPrivate
{ {
GtkFishCreationFunc creation_func; GtkFishCreationFunc creation_func;
GHashTable *children; GList *children;
guint count; guint count;
gint64 last_frame_time; gint64 last_frame_time;
@@ -53,6 +53,7 @@ enum {
PROP_BENCHMARK, PROP_BENCHMARK,
PROP_COUNT, PROP_COUNT,
PROP_FRAMERATE, PROP_FRAMERATE,
PROP_FRAMERATE_STRING,
PROP_UPDATE_DELAY, PROP_UPDATE_DELAY,
NUM_PROPERTIES NUM_PROPERTIES
}; };
@@ -67,8 +68,6 @@ gtk_fishbowl_init (GtkFishbowl *fishbowl)
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl); GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
priv->update_delay = G_USEC_PER_SEC; priv->update_delay = G_USEC_PER_SEC;
priv->children = g_hash_table_new_full (NULL, NULL,
NULL, (GDestroyNotify) g_free);
} }
/** /**
@@ -95,18 +94,20 @@ gtk_fishbowl_measure (GtkWidget *widget,
{ {
GtkFishbowl *fishbowl = GTK_FISHBOWL (widget); GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl); GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
GHashTableIter iter;
gpointer key, value;
GtkFishbowlChild *child; GtkFishbowlChild *child;
int child_min, child_nat; GList *children;
gint child_min, child_nat;
*minimum = 0; *minimum = 0;
*natural = 0; *natural = 0;
g_hash_table_iter_init (&iter, priv->children); for (children = priv->children; children; children = children->next)
while (g_hash_table_iter_next (&iter, &key, &value))
{ {
child = value; child = children->data;
if (!gtk_widget_get_visible (child->widget))
continue;
if (orientation == GTK_ORIENTATION_HORIZONTAL) if (orientation == GTK_ORIENTATION_HORIZONTAL)
{ {
@@ -136,13 +137,14 @@ gtk_fishbowl_size_allocate (GtkWidget *widget,
GtkFishbowlChild *child; GtkFishbowlChild *child;
GtkAllocation child_allocation; GtkAllocation child_allocation;
GtkRequisition child_requisition; GtkRequisition child_requisition;
GHashTableIter iter; GList *children;
gpointer key, value;
g_hash_table_iter_init (&iter, priv->children); for (children = priv->children; children; children = children->next)
while (g_hash_table_iter_next (&iter, &key, &value))
{ {
child = value; child = children->data;
if (!gtk_widget_get_visible (child->widget))
continue;
gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL); gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
child_allocation.x = round (child->x * (width - child_requisition.width)); child_allocation.x = round (child->x * (width - child_requisition.width));
@@ -180,7 +182,7 @@ gtk_fishbowl_add (GtkFishbowl *fishbowl,
gtk_widget_set_parent (widget, GTK_WIDGET (fishbowl)); gtk_widget_set_parent (widget, GTK_WIDGET (fishbowl));
g_hash_table_insert (priv->children, widget, child_info); priv->children = g_list_prepend (priv->children, child_info);
priv->count++; priv->count++;
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]); g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
} }
@@ -190,26 +192,34 @@ gtk_fishbowl_remove (GtkFishbowl *fishbowl,
GtkWidget *widget) GtkWidget *widget)
{ {
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl); GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
GtkFishbowlChild *child;
GtkWidget *widget_bowl = GTK_WIDGET (fishbowl);
GList *children;
if (g_hash_table_remove (priv->children, widget)) for (children = priv->children; children; children = children->next)
{ {
gtk_widget_unparent (widget); child = children->data;
priv->count--; if (child->widget == widget)
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]); {
gboolean was_visible = gtk_widget_get_visible (widget);
gtk_widget_unparent (widget);
priv->children = g_list_remove_link (priv->children, children);
g_list_free (children);
g_free (child);
if (was_visible && gtk_widget_get_visible (widget_bowl))
gtk_widget_queue_resize (widget_bowl);
priv->count--;
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
break;
}
} }
} }
static void
gtk_fishbowl_finalize (GObject *object)
{
GtkFishbowl *fishbowl = GTK_FISHBOWL (object);
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
g_hash_table_destroy (priv->children);
priv->children = NULL;
}
static void static void
gtk_fishbowl_dispose (GObject *object) gtk_fishbowl_dispose (GObject *object)
{ {
@@ -279,6 +289,14 @@ gtk_fishbowl_get_property (GObject *object,
g_value_set_double (value, gtk_fishbowl_get_framerate (fishbowl)); g_value_set_double (value, gtk_fishbowl_get_framerate (fishbowl));
break; break;
case PROP_FRAMERATE_STRING:
{
char *s = g_strdup_printf ("%.2f", gtk_fishbowl_get_framerate (fishbowl));
g_value_set_string (value, s);
g_free (s);
}
break;
case PROP_UPDATE_DELAY: case PROP_UPDATE_DELAY:
g_value_set_int64 (value, gtk_fishbowl_get_update_delay (fishbowl)); g_value_set_int64 (value, gtk_fishbowl_get_update_delay (fishbowl));
break; break;
@@ -295,7 +313,6 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->finalize = gtk_fishbowl_finalize;
object_class->dispose = gtk_fishbowl_dispose; object_class->dispose = gtk_fishbowl_dispose;
object_class->set_property = gtk_fishbowl_set_property; object_class->set_property = gtk_fishbowl_set_property;
object_class->get_property = gtk_fishbowl_get_property; object_class->get_property = gtk_fishbowl_get_property;
@@ -333,6 +350,13 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
0, 0,
G_PARAM_READABLE); G_PARAM_READABLE);
props[PROP_FRAMERATE_STRING] =
g_param_spec_string ("framerate-string",
"Framerate as string",
"Framerate as string, with 2 decimals",
NULL,
G_PARAM_READABLE);
props[PROP_UPDATE_DELAY] = props[PROP_UPDATE_DELAY] =
g_param_spec_int64 ("update-delay", g_param_spec_int64 ("update-delay",
"Update delay", "Update delay",
@@ -484,6 +508,7 @@ gtk_fishbowl_do_update (GtkFishbowl *fishbowl)
priv->framerate = ((int)(priv->framerate * 100))/100.0; priv->framerate = ((int)(priv->framerate * 100))/100.0;
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE]); g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE]);
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE_STRING]);
if (!priv->benchmark) if (!priv->benchmark)
return; return;
@@ -527,9 +552,8 @@ gtk_fishbowl_tick (GtkWidget *widget,
GtkFishbowl *fishbowl = GTK_FISHBOWL (widget); GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl); GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
GtkFishbowlChild *child; GtkFishbowlChild *child;
GList *l;
gint64 frame_time, elapsed; gint64 frame_time, elapsed;
GHashTableIter iter;
gpointer key, value;
gboolean do_update; gboolean do_update;
frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget)); frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
@@ -541,10 +565,9 @@ gtk_fishbowl_tick (GtkWidget *widget,
if (elapsed == frame_time) if (elapsed == frame_time)
return G_SOURCE_CONTINUE; return G_SOURCE_CONTINUE;
g_hash_table_iter_init (&iter, priv->children); for (l = priv->children; l; l = l->next)
while (g_hash_table_iter_next (&iter, &key, &value))
{ {
child = value; child = l->data;
child->x += child->dx * ((double) elapsed / G_USEC_PER_SEC); child->x += child->dx * ((double) elapsed / G_USEC_PER_SEC);
child->y += child->dy * ((double) elapsed / G_USEC_PER_SEC); child->y += child->dy * ((double) elapsed / G_USEC_PER_SEC);

View File

@@ -197,7 +197,7 @@ gtk_gears_class_init (GtkGearsClass *klass)
* @param v the vertex to fill * @param v the vertex to fill
* @param x the x coordinate * @param x the x coordinate
* @param y the y coordinate * @param y the y coordinate
* @param z the z coordinate * @param z the z coortinate
* @param n pointer to the normal table * @param n pointer to the normal table
* *
* @return the operation error code * @return the operation error code

View File

@@ -25,11 +25,12 @@ do_headerbar (GtkWidget *do_widget)
window = gtk_window_new (); window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget)); gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Welcome to Facebook - Log in, sign up or learn more"); gtk_window_set_title (GTK_WINDOW (window), "Welcome to Facebook - Log in, sign up or learn more");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window); g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400); gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
header = gtk_header_bar_new (); header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
button = gtk_button_new (); button = gtk_button_new ();
icon = g_themed_icon_new ("mail-send-receive-symbolic"); icon = g_themed_icon_new ("mail-send-receive-symbolic");
@@ -42,10 +43,10 @@ do_headerbar (GtkWidget *do_widget)
gtk_widget_add_css_class (box, "linked"); gtk_widget_add_css_class (box, "linked");
button = gtk_button_new (); button = gtk_button_new ();
gtk_button_set_child (GTK_BUTTON (button), gtk_image_new_from_icon_name ("pan-start-symbolic")); gtk_button_set_child (GTK_BUTTON (button), gtk_image_new_from_icon_name ("pan-start-symbolic"));
gtk_box_append (GTK_BOX (box), button); gtk_container_add (GTK_CONTAINER (box), button);
button = gtk_button_new (); button = gtk_button_new ();
gtk_button_set_child (GTK_BUTTON (button), gtk_image_new_from_icon_name ("pan-end-symbolic")); gtk_button_set_child (GTK_BUTTON (button), gtk_image_new_from_icon_name ("pan-end-symbolic"));
gtk_box_append (GTK_BOX (box), button); gtk_container_add (GTK_CONTAINER (box), button);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), box); gtk_header_bar_pack_start (GTK_HEADER_BAR (header), box);
@@ -57,7 +58,7 @@ do_headerbar (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;
} }

View File

@@ -18,7 +18,7 @@ static void
insert_link (GtkTextBuffer *buffer, insert_link (GtkTextBuffer *buffer,
GtkTextIter *iter, GtkTextIter *iter,
const char *text, const char *text,
int page) gint page)
{ {
GtkTextTag *tag; GtkTextTag *tag;
@@ -35,7 +35,7 @@ insert_link (GtkTextBuffer *buffer,
*/ */
static void static void
show_page (GtkTextBuffer *buffer, show_page (GtkTextBuffer *buffer,
int page) gint page)
{ {
GtkTextIter iter; GtkTextIter iter;
@@ -91,7 +91,7 @@ follow_if_link (GtkWidget *text_view,
for (tagp = tags; tagp != NULL; tagp = tagp->next) for (tagp = tags; tagp != NULL; tagp = tagp->next)
{ {
GtkTextTag *tag = tagp->data; GtkTextTag *tag = tagp->data;
int page = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "page")); gint page = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "page"));
if (page != 0) if (page != 0)
{ {
@@ -134,14 +134,14 @@ key_pressed (GtkEventController *controller,
} }
static void set_cursor_if_appropriate (GtkTextView *text_view, static void set_cursor_if_appropriate (GtkTextView *text_view,
int x, gint x,
int y); gint y);
static void static void
released_cb (GtkGestureClick *gesture, released_cb (GtkGestureClick *gesture,
guint n_press, guint n_press,
double x, gdouble x,
double y, gdouble y,
GtkWidget *text_view) GtkWidget *text_view)
{ {
GtkTextIter start, end, iter; GtkTextIter start, end, iter;
@@ -168,8 +168,8 @@ released_cb (GtkGestureClick *gesture,
static void static void
motion_cb (GtkEventControllerMotion *controller, motion_cb (GtkEventControllerMotion *controller,
double x, gdouble x,
double y, gdouble y,
GtkTextView *text_view) GtkTextView *text_view)
{ {
set_cursor_if_appropriate (text_view, x, y); set_cursor_if_appropriate (text_view, x, y);
@@ -183,8 +183,8 @@ static gboolean hovering_over_link = FALSE;
*/ */
static void static void
set_cursor_if_appropriate (GtkTextView *text_view, set_cursor_if_appropriate (GtkTextView *text_view,
int x, gint x,
int y) gint y)
{ {
GSList *tags = NULL, *tagp = NULL; GSList *tags = NULL, *tagp = NULL;
GtkTextIter iter; GtkTextIter iter;
@@ -196,7 +196,7 @@ set_cursor_if_appropriate (GtkTextView *text_view,
for (tagp = tags; tagp != NULL; tagp = tagp->next) for (tagp = tags; tagp != NULL; tagp = tagp->next)
{ {
GtkTextTag *tag = tagp->data; GtkTextTag *tag = tagp->data;
int page = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "page")); gint page = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "page"));
if (page != 0) if (page != 0)
{ {
@@ -237,7 +237,9 @@ do_hypertext (GtkWidget *do_widget)
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_default_size (GTK_WINDOW (window), 450, 450); gtk_window_set_default_size (GTK_WINDOW (window), 450, 450);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
view = gtk_text_view_new (); view = gtk_text_view_new ();
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD); gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
@@ -260,7 +262,7 @@ do_hypertext (GtkWidget *do_widget)
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
gtk_text_buffer_set_enable_undo (buffer, TRUE); gtk_text_buffer_set_enable_undo (buffer, TRUE);
sw = gtk_scrolled_window_new (); sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC); GTK_POLICY_AUTOMATIC);
@@ -273,7 +275,7 @@ do_hypertext (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;
} }

View File

@@ -12,7 +12,7 @@ static GtkWidget *window = NULL;
static GtkWidget *scrolledwindow; static GtkWidget *scrolledwindow;
static int selected; static int selected;
#define N_WIDGET_TYPES 6 #define N_WIDGET_TYPES 4
static int hincrement = 5; static int hincrement = 5;
@@ -64,7 +64,6 @@ populate_icons (void)
gtk_grid_attach (GTK_GRID (grid), create_icon (), left, top, 1, 1); gtk_grid_attach (GTK_GRID (grid), create_icon (), left, top, 1, 1);
hincrement = 0; hincrement = 0;
vincrement = 5;
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
GTK_POLICY_NEVER, GTK_POLICY_NEVER,
@@ -101,7 +100,6 @@ populate_text (gboolean hilight)
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer); gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
hincrement = 0; hincrement = 0;
vincrement = 5;
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
GTK_POLICY_NEVER, GTK_POLICY_NEVER,
@@ -126,7 +124,6 @@ populate_image (void)
gtk_picture_set_can_shrink (GTK_PICTURE (image), FALSE); gtk_picture_set_can_shrink (GTK_PICTURE (image), FALSE);
hincrement = 5; hincrement = 5;
vincrement = 5;
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
@@ -134,42 +131,6 @@ populate_image (void)
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolledwindow), image); gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolledwindow), image);
} }
extern GtkWidget *create_weather_view (void);
static void
populate_list (void)
{
GtkWidget *list;
list = create_weather_view ();
hincrement = 5;
vincrement = 0;
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolledwindow), list);
}
extern GtkWidget *create_color_grid (void);
static void
populate_grid (void)
{
GtkWidget *list;
list = create_color_grid ();
hincrement = 0;
vincrement = 5;
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolledwindow), list);
}
static void static void
set_widget_type (int type) set_widget_type (int type)
{ {
@@ -203,16 +164,6 @@ set_widget_type (int type)
populate_image (); populate_image ();
break; break;
case 4:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a list");
populate_list ();
break;
case 5:
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a grid");
populate_grid ();
break;
default: default:
g_assert_not_reached (); g_assert_not_reached ();
} }
@@ -258,23 +209,23 @@ do_iconscroll (GtkWidget *do_widget)
builder = gtk_builder_new_from_resource ("/iconscroll/iconscroll.ui"); builder = gtk_builder_new_from_resource ("/iconscroll/iconscroll.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window")); window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window); g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &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_CALLBACK (gtk_widget_destroyed), &window);
scrolledwindow = GTK_WIDGET (gtk_builder_get_object (builder, "scrolledwindow")); scrolledwindow = GTK_WIDGET (gtk_builder_get_object (builder, "scrolledwindow"));
gtk_widget_realize (window); gtk_widget_realize (window);
hadjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "hadjustment")); hadjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "hadjustment"));
vadjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "vadjustment")); vadjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "vadjustment"));
set_widget_type (0); set_widget_type (0);
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;
} }

View File

@@ -6,6 +6,7 @@
<property name="default-height">500</property> <property name="default-height">500</property>
<child type="titlebar"> <child type="titlebar">
<object class="GtkHeaderBar"> <object class="GtkHeaderBar">
<property name="show-title-buttons">1</property>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<style> <style>

View File

@@ -25,7 +25,7 @@ enum
static GdkPixbuf *file_pixbuf, *folder_pixbuf; static GdkPixbuf *file_pixbuf, *folder_pixbuf;
char *parent; gchar *parent;
GtkWidget *up_button; GtkWidget *up_button;
/* Loads the images for the demo and returns whether the operation succeeded */ /* Loads the images for the demo and returns whether the operation succeeded */
@@ -47,7 +47,7 @@ static void
fill_store (GtkListStore *store) fill_store (GtkListStore *store)
{ {
GDir *dir; GDir *dir;
const char *name; const gchar *name;
GtkTreeIter iter; GtkTreeIter iter;
/* First clear the store */ /* First clear the store */
@@ -62,7 +62,7 @@ fill_store (GtkListStore *store)
name = g_dir_read_name (dir); name = g_dir_read_name (dir);
while (name != NULL) while (name != NULL)
{ {
char *path, *display_name; gchar *path, *display_name;
gboolean is_dir; gboolean is_dir;
/* We ignore hidden files that start with a '.' */ /* We ignore hidden files that start with a '.' */
@@ -90,14 +90,14 @@ fill_store (GtkListStore *store)
g_dir_close (dir); g_dir_close (dir);
} }
static int static gint
sort_func (GtkTreeModel *model, sort_func (GtkTreeModel *model,
GtkTreeIter *a, GtkTreeIter *a,
GtkTreeIter *b, GtkTreeIter *b,
gpointer user_data) gpointer user_data)
{ {
gboolean is_dir_a, is_dir_b; gboolean is_dir_a, is_dir_b;
char *name_a, *name_b; gchar *name_a, *name_b;
int ret; int ret;
/* We need this function because we want to sort /* We need this function because we want to sort
@@ -158,7 +158,7 @@ item_activated (GtkIconView *icon_view,
gpointer user_data) gpointer user_data)
{ {
GtkListStore *store; GtkListStore *store;
char *path; gchar *path;
GtkTreeIter iter; GtkTreeIter iter;
gboolean is_dir; gboolean is_dir;
@@ -192,7 +192,7 @@ up_clicked (GtkButton *item,
gpointer user_data) gpointer user_data)
{ {
GtkListStore *store; GtkListStore *store;
char *dir_name; gchar *dir_name;
store = GTK_LIST_STORE (user_data); store = GTK_LIST_STORE (user_data);
@@ -228,7 +228,7 @@ home_clicked (GtkButton *item,
static void close_window(void) static void close_window(void)
{ {
gtk_window_destroy (GTK_WINDOW (window)); gtk_widget_destroy (window);
window = NULL; window = NULL;
g_object_unref (file_pixbuf); g_object_unref (file_pixbuf);
@@ -266,24 +266,24 @@ do_iconview (GtkWidget *do_widget)
gtk_window_set_child (GTK_WINDOW (window), vbox); gtk_window_set_child (GTK_WINDOW (window), vbox);
tool_bar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); tool_bar = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_append (GTK_BOX (vbox), tool_bar); gtk_container_add (GTK_CONTAINER (vbox), tool_bar);
up_button = gtk_button_new_with_mnemonic ("_Up"); up_button = gtk_button_new_with_mnemonic ("_Up");
gtk_widget_set_sensitive (GTK_WIDGET (up_button), FALSE); gtk_widget_set_sensitive (GTK_WIDGET (up_button), FALSE);
gtk_box_append (GTK_BOX (tool_bar), up_button); gtk_container_add (GTK_CONTAINER (tool_bar), up_button);
home_button = gtk_button_new_with_mnemonic ("_Home"); home_button = gtk_button_new_with_mnemonic ("_Home");
gtk_box_append (GTK_BOX (tool_bar), home_button); gtk_container_add (GTK_CONTAINER (tool_bar), home_button);
sw = gtk_scrolled_window_new (); sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE); gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC); GTK_POLICY_AUTOMATIC);
gtk_widget_set_vexpand (sw, TRUE); gtk_widget_set_vexpand (sw, TRUE);
gtk_box_append (GTK_BOX (vbox), sw); gtk_container_add (GTK_CONTAINER (vbox), sw);
/* Create the store and fill it with the contents of '/' */ /* Create the store and fill it with the contents of '/' */
parent = g_strdup ("/"); parent = g_strdup ("/");
@@ -320,7 +320,7 @@ do_iconview (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;
} }

View File

@@ -19,8 +19,8 @@ static void
fill_store (GtkListStore *store) fill_store (GtkListStore *store)
{ {
GtkTreeIter iter; GtkTreeIter iter;
const char *text[] = { "Red", "Green", "Blue", "Yellow" }; const gchar *text[] = { "Red", "Green", "Blue", "Yellow" };
int i; gint i;
/* First clear the store */ /* First clear the store */
gtk_list_store_clear (store); gtk_list_store_clear (store);
@@ -49,7 +49,7 @@ set_cell_color (GtkCellLayout *cell_layout,
GtkTreeIter *iter, GtkTreeIter *iter,
gpointer data) gpointer data)
{ {
char *text; gchar *text;
GdkRGBA color; GdkRGBA color;
guint32 pixel = 0; guint32 pixel = 0;
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
@@ -60,10 +60,10 @@ set_cell_color (GtkCellLayout *cell_layout,
if (gdk_rgba_parse (&color, text)) if (gdk_rgba_parse (&color, text))
pixel = pixel =
((int)(color.red * 255)) << 24 | ((gint)(color.red * 255)) << 24 |
((int)(color.green * 255)) << 16 | ((gint)(color.green * 255)) << 16 |
((int)(color.blue * 255)) << 8 | ((gint)(color.blue * 255)) << 8 |
((int)(color.alpha * 255)); ((gint)(color.alpha * 255));
g_free (text); g_free (text);
@@ -77,8 +77,8 @@ set_cell_color (GtkCellLayout *cell_layout,
static void static void
edited (GtkCellRendererText *cell, edited (GtkCellRendererText *cell,
char *path_string, gchar *path_string,
char *text, gchar *text,
gpointer data) gpointer data)
{ {
GtkTreeModel *model; GtkTreeModel *model;
@@ -111,7 +111,9 @@ do_iconview_edit (GtkWidget *do_widget)
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), "Editing and Drag-and-Drop"); gtk_window_set_title (GTK_WINDOW (window), "Editing and Drag-and-Drop");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
store = create_store (); store = create_store ();
fill_store (store); fill_store (store);
@@ -150,7 +152,7 @@ do_iconview_edit (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;
} }

View File

@@ -43,10 +43,10 @@ progressive_prepared_callback (GdkPixbufLoader *loader,
static void static void
progressive_updated_callback (GdkPixbufLoader *loader, progressive_updated_callback (GdkPixbufLoader *loader,
int x, gint x,
int y, gint y,
int width, gint width,
int height, gint height,
gpointer data) gpointer data)
{ {
GtkWidget *picture; GtkWidget *picture;
@@ -58,7 +58,7 @@ progressive_updated_callback (GdkPixbufLoader *loader,
gtk_picture_set_pixbuf (GTK_PICTURE (picture), pixbuf); gtk_picture_set_pixbuf (GTK_PICTURE (picture), pixbuf);
} }
static int static gint
progressive_timeout (gpointer data) progressive_timeout (gpointer data)
{ {
GtkWidget *picture; GtkWidget *picture;
@@ -91,7 +91,7 @@ progressive_timeout (gpointer data)
g_error_free (error); g_error_free (error);
g_signal_connect (dialog, "response", g_signal_connect (dialog, "response",
G_CALLBACK (gtk_window_destroy), NULL); G_CALLBACK (gtk_widget_destroy), NULL);
g_object_unref (image_stream); g_object_unref (image_stream);
image_stream = NULL; image_stream = NULL;
@@ -119,7 +119,7 @@ progressive_timeout (gpointer data)
g_error_free (error); g_error_free (error);
g_signal_connect (dialog, "response", g_signal_connect (dialog, "response",
G_CALLBACK (gtk_window_destroy), NULL); G_CALLBACK (gtk_widget_destroy), NULL);
g_object_unref (image_stream); g_object_unref (image_stream);
image_stream = NULL; image_stream = NULL;
@@ -152,7 +152,7 @@ progressive_timeout (gpointer data)
g_error_free (error); g_error_free (error);
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);
@@ -189,7 +189,7 @@ progressive_timeout (gpointer data)
g_error_free (error); g_error_free (error);
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);
@@ -223,7 +223,7 @@ progressive_timeout (gpointer data)
g_error_free (error); g_error_free (error);
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);
@@ -293,16 +293,24 @@ static void
toggle_sensitivity_callback (GtkWidget *togglebutton, toggle_sensitivity_callback (GtkWidget *togglebutton,
gpointer user_data) gpointer user_data)
{ {
GtkWidget *child; GtkContainer *container = user_data;
GList *list;
GList *tmp;
for (child = gtk_widget_get_first_child (GTK_WIDGET (user_data)); list = gtk_container_get_children (container);
child != NULL;
child = gtk_widget_get_next_sibling (child)) tmp = list;
while (tmp != NULL)
{ {
/* don't disable our toggle */ /* don't disable our toggle */
if (child != togglebutton) if (GTK_WIDGET (tmp->data) != togglebutton)
gtk_widget_set_sensitive (child, !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (togglebutton))); gtk_widget_set_sensitive (GTK_WIDGET (tmp->data),
!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (togglebutton)));
tmp = tmp->next;
} }
g_list_free (list);
} }
@@ -327,8 +335,9 @@ do_images (GtkWidget *do_widget)
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), "Images"); gtk_window_set_title (GTK_WINDOW (window), "Images");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
g_signal_connect (window, "destroy", g_signal_connect (window, "destroy",
G_CALLBACK (cleanup_callback), NULL); G_CALLBACK (cleanup_callback), NULL);
@@ -340,20 +349,20 @@ do_images (GtkWidget *do_widget)
gtk_window_set_child (GTK_WINDOW (window), base_vbox); gtk_window_set_child (GTK_WINDOW (window), base_vbox);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 16); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 16);
gtk_box_append (GTK_BOX (base_vbox), hbox); gtk_container_add (GTK_CONTAINER (base_vbox), hbox);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
gtk_box_append (GTK_BOX (hbox), vbox); gtk_container_add (GTK_CONTAINER (hbox), vbox);
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"<u>Image loaded from a file</u>"); "<u>Image loaded from a file</u>");
gtk_box_append (GTK_BOX (vbox), label); gtk_container_add (GTK_CONTAINER (vbox), label);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER); gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER); gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
gtk_box_append (GTK_BOX (vbox), frame); gtk_container_add (GTK_CONTAINER (vbox), frame);
image = gtk_image_new_from_icon_name ("gtk3-demo"); image = gtk_image_new_from_icon_name ("gtk3-demo");
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE); gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
@@ -366,12 +375,12 @@ do_images (GtkWidget *do_widget)
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"<u>Animation loaded from a file</u>"); "<u>Animation loaded from a file</u>");
gtk_box_append (GTK_BOX (vbox), label); gtk_container_add (GTK_CONTAINER (vbox), label);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER); gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER); gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
gtk_box_append (GTK_BOX (vbox), frame); gtk_container_add (GTK_CONTAINER (vbox), frame);
picture = gtk_picture_new_for_resource ("/images/floppybuddy.gif"); picture = gtk_picture_new_for_resource ("/images/floppybuddy.gif");
@@ -382,12 +391,12 @@ do_images (GtkWidget *do_widget)
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"<u>Symbolic themed icon</u>"); "<u>Symbolic themed icon</u>");
gtk_box_append (GTK_BOX (vbox), label); gtk_container_add (GTK_CONTAINER (vbox), label);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER); gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER); gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
gtk_box_append (GTK_BOX (vbox), frame); gtk_container_add (GTK_CONTAINER (vbox), frame);
gicon = g_themed_icon_new_with_default_fallbacks ("battery-caution-charging-symbolic"); gicon = g_themed_icon_new_with_default_fallbacks ("battery-caution-charging-symbolic");
image = gtk_image_new_from_gicon (gicon); image = gtk_image_new_from_gicon (gicon);
@@ -398,17 +407,17 @@ do_images (GtkWidget *do_widget)
/* Progressive */ /* Progressive */
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
gtk_box_append (GTK_BOX (hbox), vbox); gtk_container_add (GTK_CONTAINER (hbox), vbox);
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"<u>Progressive image loading</u>"); "<u>Progressive image loading</u>");
gtk_box_append (GTK_BOX (vbox), label); gtk_container_add (GTK_CONTAINER (vbox), label);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER); gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER); gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
gtk_box_append (GTK_BOX (vbox), frame); gtk_container_add (GTK_CONTAINER (vbox), frame);
/* Create an empty image for now; the progressive loader /* Create an empty image for now; the progressive loader
* will create the pixbuf and fill it in. * will create the pixbuf and fill it in.
@@ -420,17 +429,17 @@ do_images (GtkWidget *do_widget)
/* Video */ /* Video */
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
gtk_box_append (GTK_BOX (hbox), vbox); gtk_container_add (GTK_CONTAINER (hbox), vbox);
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"<u>Displaying video</u>"); "<u>Displaying video</u>");
gtk_box_append (GTK_BOX (vbox), label); gtk_container_add (GTK_CONTAINER (vbox), label);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER); gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER); gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
gtk_box_append (GTK_BOX (vbox), frame); gtk_container_add (GTK_CONTAINER (vbox), frame);
video = gtk_video_new_for_resource ("/images/gtk-logo.webm"); video = gtk_video_new_for_resource ("/images/gtk-logo.webm");
gtk_media_stream_set_loop (gtk_video_get_media_stream (GTK_VIDEO (video)), TRUE); gtk_media_stream_set_loop (gtk_video_get_media_stream (GTK_VIDEO (video)), TRUE);
@@ -438,22 +447,22 @@ do_images (GtkWidget *do_widget)
/* Widget paintables */ /* Widget paintables */
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
gtk_box_append (GTK_BOX (hbox), vbox); gtk_container_add (GTK_CONTAINER (hbox), vbox);
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"<u>GtkWidgetPaintable</u>"); "<u>GtkWidgetPaintable</u>");
gtk_box_append (GTK_BOX (vbox), label); gtk_container_add (GTK_CONTAINER (vbox), label);
paintable = gtk_widget_paintable_new (do_widget); paintable = gtk_widget_paintable_new (do_widget);
picture = gtk_picture_new_for_paintable (paintable); picture = gtk_picture_new_for_paintable (paintable);
gtk_widget_set_size_request (picture, 100, 100); gtk_widget_set_size_request (picture, 100, 100);
gtk_widget_set_valign (picture, GTK_ALIGN_START); gtk_widget_set_valign (picture, GTK_ALIGN_START);
gtk_box_append (GTK_BOX (vbox), picture); gtk_container_add (GTK_CONTAINER (vbox), picture);
/* Sensitivity control */ /* Sensitivity control */
button = gtk_toggle_button_new_with_mnemonic ("_Insensitive"); button = gtk_toggle_button_new_with_mnemonic ("_Insensitive");
gtk_box_append (GTK_BOX (base_vbox), button); gtk_container_add (GTK_CONTAINER (base_vbox), button);
g_signal_connect (button, "toggled", g_signal_connect (button, "toggled",
G_CALLBACK (toggle_sensitivity_callback), G_CALLBACK (toggle_sensitivity_callback),
@@ -463,7 +472,7 @@ do_images (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;
} }

View File

@@ -8,7 +8,7 @@
static void static void
on_bar_response (GtkInfoBar *info_bar, on_bar_response (GtkInfoBar *info_bar,
int response_id, gint response_id,
gpointer user_data) gpointer user_data)
{ {
GtkWidget *dialog; GtkWidget *dialog;
@@ -29,8 +29,10 @@ on_bar_response (GtkInfoBar *info_bar,
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
"Your response has id %d", response_id); "Your response has id %d", response_id);
g_signal_connect_swapped (dialog, "response", g_signal_connect_swapped (dialog,
G_CALLBACK (gtk_window_destroy), dialog); "response",
G_CALLBACK (gtk_widget_destroy),
dialog);
gtk_widget_show (dialog); gtk_widget_show (dialog);
} }
@@ -56,7 +58,8 @@ do_infobar (GtkWidget *do_widget)
gtk_widget_get_display (do_widget)); gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Info Bars"); gtk_window_set_title (GTK_WINDOW (window), "Info Bars");
gtk_window_set_resizable (GTK_WINDOW (window), FALSE); 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);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_margin_start (vbox, 8); gtk_widget_set_margin_start (vbox, 8);
@@ -66,73 +69,73 @@ do_infobar (GtkWidget *do_widget)
gtk_window_set_child (GTK_WINDOW (window), vbox); gtk_window_set_child (GTK_WINDOW (window), vbox);
bar = gtk_info_bar_new (); bar = gtk_info_bar_new ();
gtk_box_append (GTK_BOX (vbox), bar); gtk_container_add (GTK_CONTAINER (vbox), bar);
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_INFO); gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_INFO);
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_INFO"); label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_INFO");
gtk_label_set_wrap (GTK_LABEL (label), TRUE); gtk_label_set_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_xalign (GTK_LABEL (label), 0); gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_info_bar_add_child (GTK_INFO_BAR (bar), label); gtk_container_add (GTK_CONTAINER (bar), label);
button = gtk_toggle_button_new_with_label ("Message"); button = gtk_toggle_button_new_with_label ("Message");
g_object_bind_property (bar, "revealed", button, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); g_object_bind_property (bar, "revealed", button, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
gtk_box_append (GTK_BOX (actions), button); gtk_container_add (GTK_CONTAINER (actions), button);
bar = gtk_info_bar_new (); bar = gtk_info_bar_new ();
gtk_box_append (GTK_BOX (vbox), bar); gtk_container_add (GTK_CONTAINER (vbox), bar);
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_WARNING); gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_WARNING);
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_WARNING"); label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_WARNING");
gtk_label_set_wrap (GTK_LABEL (label), TRUE); gtk_label_set_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_xalign (GTK_LABEL (label), 0); gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_info_bar_add_child (GTK_INFO_BAR (bar), label); gtk_container_add (GTK_CONTAINER (bar), label);
button = gtk_toggle_button_new_with_label ("Warning"); button = gtk_toggle_button_new_with_label ("Warning");
g_object_bind_property (bar, "revealed", button, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); g_object_bind_property (bar, "revealed", button, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
gtk_box_append (GTK_BOX (actions), button); gtk_container_add (GTK_CONTAINER (actions), button);
bar = gtk_info_bar_new_with_buttons (_("_OK"), GTK_RESPONSE_OK, NULL); bar = gtk_info_bar_new_with_buttons (_("_OK"), GTK_RESPONSE_OK, NULL);
gtk_info_bar_set_show_close_button (GTK_INFO_BAR (bar), TRUE); gtk_info_bar_set_show_close_button (GTK_INFO_BAR (bar), TRUE);
g_signal_connect (bar, "response", G_CALLBACK (on_bar_response), window); g_signal_connect (bar, "response", G_CALLBACK (on_bar_response), window);
gtk_box_append (GTK_BOX (vbox), bar); gtk_container_add (GTK_CONTAINER (vbox), bar);
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_QUESTION); gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_QUESTION);
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_QUESTION"); label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_QUESTION");
gtk_label_set_wrap (GTK_LABEL (label), TRUE); gtk_label_set_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_xalign (GTK_LABEL (label), 0); gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_info_bar_add_child (GTK_INFO_BAR (bar), label); gtk_container_add (GTK_CONTAINER (bar), label);
gtk_info_bar_set_default_response (GTK_INFO_BAR (bar), GTK_RESPONSE_OK); gtk_info_bar_set_default_response (GTK_INFO_BAR (bar), GTK_RESPONSE_OK);
button = gtk_toggle_button_new_with_label ("Question"); button = gtk_toggle_button_new_with_label ("Question");
g_object_bind_property (bar, "revealed", button, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); g_object_bind_property (bar, "revealed", button, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
gtk_box_append (GTK_BOX (actions), button); gtk_container_add (GTK_CONTAINER (actions), button);
bar = gtk_info_bar_new (); bar = gtk_info_bar_new ();
gtk_box_append (GTK_BOX (vbox), bar); gtk_container_add (GTK_CONTAINER (vbox), bar);
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_ERROR); gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_ERROR);
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_ERROR"); label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_ERROR");
gtk_label_set_wrap (GTK_LABEL (label), TRUE); gtk_label_set_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_xalign (GTK_LABEL (label), 0); gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_info_bar_add_child (GTK_INFO_BAR (bar), label); gtk_container_add (GTK_CONTAINER (bar), label);
button = gtk_toggle_button_new_with_label ("Error"); button = gtk_toggle_button_new_with_label ("Error");
g_object_bind_property (bar, "revealed", button, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); g_object_bind_property (bar, "revealed", button, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
gtk_box_append (GTK_BOX (actions), button); gtk_container_add (GTK_CONTAINER (actions), button);
bar = gtk_info_bar_new (); bar = gtk_info_bar_new ();
gtk_box_append (GTK_BOX (vbox), bar); gtk_container_add (GTK_CONTAINER (vbox), bar);
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_OTHER); gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_OTHER);
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_OTHER"); label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_OTHER");
gtk_label_set_wrap (GTK_LABEL (label), TRUE); gtk_label_set_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_xalign (GTK_LABEL (label), 0); gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_info_bar_add_child (GTK_INFO_BAR (bar), label); gtk_container_add (GTK_CONTAINER (bar), label);
button = gtk_toggle_button_new_with_label ("Other"); button = gtk_toggle_button_new_with_label ("Other");
g_object_bind_property (bar, "revealed", button, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); g_object_bind_property (bar, "revealed", button, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
gtk_box_append (GTK_BOX (actions), button); gtk_container_add (GTK_CONTAINER (actions), button);
frame = gtk_frame_new ("An example of different info bars"); frame = gtk_frame_new ("An example of different info bars");
gtk_widget_set_margin_top (frame, 8); gtk_widget_set_margin_top (frame, 8);
gtk_widget_set_margin_bottom (frame, 8); gtk_widget_set_margin_bottom (frame, 8);
gtk_box_append (GTK_BOX (vbox), frame); gtk_container_add (GTK_CONTAINER (vbox), frame);
gtk_widget_set_halign (actions, GTK_ALIGN_CENTER); gtk_widget_set_halign (actions, GTK_ALIGN_CENTER);
@@ -146,7 +149,7 @@ do_infobar (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;
} }

View File

@@ -9,15 +9,15 @@
static void static void
response_cb (GtkWidget *dialog, response_cb (GtkWidget *dialog,
int response_id, gint response_id,
gpointer data) gpointer data)
{ {
gtk_window_destroy (GTK_WINDOW (dialog)); gtk_widget_destroy (dialog);
} }
static gboolean static gboolean
activate_link (GtkWidget *label, activate_link (GtkWidget *label,
const char *uri, const gchar *uri,
gpointer data) gpointer data)
{ {
if (g_strcmp0 (uri, "keynav") == 0) if (g_strcmp0 (uri, "keynav") == 0)
@@ -59,7 +59,8 @@ do_links (GtkWidget *do_widget)
gtk_widget_get_display (do_widget)); gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Links"); gtk_window_set_title (GTK_WINDOW (window), "Links");
gtk_window_set_resizable (GTK_WINDOW (window), FALSE); 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);
label = gtk_label_new ("Some <a href=\"http://en.wikipedia.org/wiki/Text\"" label = gtk_label_new ("Some <a href=\"http://en.wikipedia.org/wiki/Text\""
"title=\"plain text\">text</a> may be marked up " "title=\"plain text\">text</a> may be marked up "
@@ -87,7 +88,7 @@ do_links (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;
} }

View File

@@ -81,7 +81,7 @@ spinner_timeout (gpointer data)
static GtkTreeModel * static GtkTreeModel *
create_model (void) create_model (void)
{ {
int i = 0; gint i = 0;
GtkListStore *store; GtkListStore *store;
GtkTreeIter iter; GtkTreeIter iter;
@@ -257,7 +257,9 @@ do_list_store (GtkWidget *do_widget)
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), "List Store"); gtk_window_set_title (GTK_WINDOW (window), "List Store");
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, 8); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
gtk_widget_set_margin_start (vbox, 8); gtk_widget_set_margin_start (vbox, 8);
@@ -267,14 +269,14 @@ do_list_store (GtkWidget *do_widget)
gtk_window_set_child (GTK_WINDOW (window), vbox); gtk_window_set_child (GTK_WINDOW (window), vbox);
label = gtk_label_new ("This is the bug list (note: not based on real data, it would be nice to have a nice ODBC interface to bugzilla or so, though)."); label = gtk_label_new ("This is the bug list (note: not based on real data, it would be nice to have a nice ODBC interface to bugzilla or so, though).");
gtk_box_append (GTK_BOX (vbox), label); gtk_container_add (GTK_CONTAINER (vbox), label);
sw = gtk_scrolled_window_new (); sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE); gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_NEVER, GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC); GTK_POLICY_AUTOMATIC);
gtk_box_append (GTK_BOX (vbox), sw); gtk_container_add (GTK_CONTAINER (vbox), sw);
/* create tree model */ /* create tree model */
model = create_model (); model = create_model ();
@@ -307,7 +309,7 @@ do_list_store (GtkWidget *do_widget)
} }
else else
{ {
gtk_window_destroy (GTK_WINDOW (window)); gtk_widget_destroy (window);
window = NULL; window = NULL;
if (timeout != 0) if (timeout != 0)
{ {

View File

@@ -236,6 +236,7 @@ reshare_clicked (GtkMessageRow *row,
priv->message->n_reshares++; priv->message->n_reshares++;
gtk_message_row_update (row); gtk_message_row_update (row);
} }
static void static void
@@ -254,12 +255,11 @@ gtk_message_row_state_flags_changed (GtkWidget *widget,
{ {
GtkMessageRowPrivate *priv = GTK_MESSAGE_ROW (widget)->priv; GtkMessageRowPrivate *priv = GTK_MESSAGE_ROW (widget)->priv;
GtkStateFlags flags; GtkStateFlags flags;
gboolean visible;
flags = gtk_widget_get_state_flags (widget); flags = gtk_widget_get_state_flags (widget);
visible = flags & (GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_SELECTED) ? TRUE : FALSE; gtk_widget_set_visible (priv->extra_buttons_box,
gtk_widget_set_visible (priv->extra_buttons_box, visible); flags & (GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_SELECTED));
GTK_WIDGET_CLASS (gtk_message_row_parent_class)->state_flags_changed (widget, previous_state_flags); GTK_WIDGET_CLASS (gtk_message_row_parent_class)->state_flags_changed (widget, previous_state_flags);
} }
@@ -351,17 +351,22 @@ do_listbox (GtkWidget *do_widget)
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), "List Box"); gtk_window_set_title (GTK_WINDOW (window), "List Box");
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600); gtk_window_set_default_size (GTK_WINDOW (window),
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window); 400, 600);
/* NULL window variable when window is closed */
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed),
&window);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_window_set_child (GTK_WINDOW (window), vbox); gtk_window_set_child (GTK_WINDOW (window), vbox);
label = gtk_label_new ("Messages from GTK and friends"); label = gtk_label_new ("Messages from GTK and friends");
gtk_box_append (GTK_BOX (vbox), label); gtk_container_add (GTK_CONTAINER (vbox), label);
scrolled = gtk_scrolled_window_new (); scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_widget_set_vexpand (scrolled, TRUE); gtk_widget_set_vexpand (scrolled, TRUE);
gtk_box_append (GTK_BOX (vbox), scrolled); gtk_container_add (GTK_CONTAINER (vbox), scrolled);
listbox = gtk_list_box_new (); listbox = gtk_list_box_new ();
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled), listbox); gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled), listbox);
@@ -377,7 +382,7 @@ do_listbox (GtkWidget *do_widget)
message = gtk_message_new (lines[i]); message = gtk_message_new (lines[i]);
row = gtk_message_row_new (message); row = gtk_message_row_new (message);
gtk_widget_show (GTK_WIDGET (row)); gtk_widget_show (GTK_WIDGET (row));
gtk_list_box_insert (GTK_LIST_BOX (listbox), GTK_WIDGET (row), -1); gtk_container_add (GTK_CONTAINER (listbox), GTK_WIDGET (row));
} }
g_strfreev (lines); g_strfreev (lines);
@@ -387,7 +392,7 @@ do_listbox (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;
} }

View File

@@ -150,7 +150,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="GtkButton" id="favorite-button"> <object class="GtkButton" id="favorite-buttton">
<property name="label" translatable="yes">Favorite</property> <property name="label" translatable="yes">Favorite</property>
<property name="receives-default">1</property> <property name="receives-default">1</property>
<property name="has-frame">0</property> <property name="has-frame">0</property>

View File

@@ -1,202 +0,0 @@
/* Lists/Application launcher
*
* This demo uses the GtkListView widget as a fancy application launcher.
*
* It is also a very small introduction to listviews.
*/
#include <gtk/gtk.h>
/* This is the function that creates the #GListModel that we need.
* GTK list widgets need a #GListModel to display, as models support change
* notifications.
* Unfortunately various older APIs do not provide list models, so we create
* our own.
*/
static GListModel *
create_application_list (void)
{
GListStore *store;
GList *apps, *l;
/* We use a #GListStore here, which is a simple array-like list implementation
* for manual management.
* List models need to know what type of data they provide, so we need to
* provide the type here. As we want to do a list of applications, #GAppInfo
* is the object we provide.
*/
store = g_list_store_new (G_TYPE_APP_INFO);
apps = g_app_info_get_all ();
for (l = apps; l; l = l->next)
g_list_store_append (store, l->data);
g_list_free_full (apps, g_object_unref);
return G_LIST_MODEL (store);
}
/* This is the function we use for setting up new listitems to display.
* We add just an #GtkImage and a #GtkKabel here to display the application's
* icon and name, as this is just a simple demo.
*/
static void
setup_listitem_cb (GtkListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *box;
GtkWidget *image;
GtkWidget *label;
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
image = gtk_image_new ();
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
gtk_box_append (GTK_BOX (box), image);
label = gtk_label_new ("");
gtk_box_append (GTK_BOX (box), label);
gtk_list_item_set_child (list_item, box);
}
/* Here we need to prepare the listitem for displaying its item. We get the
* listitem already set up from the previous function, so we can reuse the
* #GtkImage widget we set up above.
* We get the item - which we know is a #GAppInfo because it comes out of
* the model we set up above, grab its icon and display it.
*/
static void
bind_listitem_cb (GtkListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *image;
GtkWidget *label;
GAppInfo *app_info;
image = gtk_widget_get_first_child (gtk_list_item_get_child (list_item));
label = gtk_widget_get_next_sibling (image);
app_info = gtk_list_item_get_item (list_item);
gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (app_info));
gtk_label_set_label (GTK_LABEL (label), g_app_info_get_display_name (app_info));
}
/* In more complex code, we would also need functions to unbind and teardown
* the listitem, but this is simple code, so the default implementations are
* enough. If we had connected signals, this step would have been necessary.
*
* The #GtkSignalListItemFactory documentation contains more information about
* this step.
*/
/* This function is called whenever an item in the list is activated. This is
* the simple way to allow reacting to the Enter key or double-clicking on a
* listitem.
* Of course, it is possible to use far more complex interactions by turning
* off activation and adding buttons or other widgets in the setup function
* above, but this is a simple demo, so we'll use the simple way.
*/
static void
activate_cb (GtkListView *list,
guint position,
gpointer unused)
{
GAppInfo *app_info;
GdkAppLaunchContext *context;
GError *error = NULL;
app_info = g_list_model_get_item (gtk_list_view_get_model (list), position);
/* Prepare the context for launching the application and launch it. This
* code is explained in detail in the documentation for #GdkAppLaunchContext
* and #GAppInfo.
*/
context = gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (list)));
if (!g_app_info_launch (app_info,
NULL,
G_APP_LAUNCH_CONTEXT (context),
&error))
{
GtkWidget *dialog;
/* And because error handling is important, even a simple demo has it:
* We display an error dialog that something went wrong.
*/
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (list))),
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Could not launch %s", g_app_info_get_display_name (app_info));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
g_clear_error (&error);
gtk_widget_show (dialog);
}
g_object_unref (context);
g_object_unref (app_info);
}
static GtkWidget *window = NULL;
GtkWidget *
do_listview_applauncher (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *list, *sw;
GListModel *model;
GtkListItemFactory *factory;
/* Create a window and set a few defaults */
window = gtk_window_new ();
gtk_window_set_default_size (GTK_WINDOW (window), 640, 320);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Application Launcher");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
/* The #GtkListitemFactory is what is used to create #GtkListItems
* to display the data from the model. So it is absolutely necessary
* to create one.
* We will use a #GtkSignalListItemFactory because it is the simplest
* one to use. Different ones are available for different use cases.
* The most powerful one is #GtkBuilderListItemFactory which uses
* #GtkBuilder .ui files, so it requires little code.
*/
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_listitem_cb), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_listitem_cb), NULL);
/* Create the list widget here.
*/
list = gtk_list_view_new_with_factory (factory);
/* We connect the activate signal here. It's the function we defined
* above for launching the selected application.
*/
g_signal_connect (list, "activate", G_CALLBACK (activate_cb), NULL);
/* And of course we need to set the data model. Here we call the function
* we wrote above that gives us the list of applications. Then we set
* it on the list widget.
* The list will now take items from the model and use the factory
* to create as many listitems as it needs to show itself to the user.
*/
model = create_application_list ();
gtk_list_view_set_model (GTK_LIST_VIEW (list), model);
g_object_unref (model);
/* List widgets should always be contained in a #GtkScrolledWindow,
* because otherwise they might get too large or they might not
* be scrollable.
*/
sw = gtk_scrolled_window_new ();
gtk_window_set_child (GTK_WINDOW (window), sw);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), list);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,506 +0,0 @@
/* Lists/Clocks
*
* This demo displays the time in different timezones.
*
* The goal is to show how to set up expressions that track changes
* in objects and make them update widgets. For that, we create a
* GtkClock object that updates its time every second and then use
* various ways to display that time.
*
* Typically, this will be done using GtkBuilder .ui files with the
* help of the <binding> tag, but this demo shows the code that runs
* behind that.
*/
#include <gtk/gtk.h>
#define GTK_TYPE_CLOCK (gtk_clock_get_type ())
G_DECLARE_FINAL_TYPE (GtkClock, gtk_clock, GTK, CLOCK, GObject)
/* This is our object. It's just a timezone */
typedef struct _GtkClock GtkClock;
struct _GtkClock
{
GObject parent_instance;
/* We allow this to be NULL for the local timezone */
GTimeZone *timezone;
/* Name of the location we're displaying time for */
char *location;
};
enum {
PROP_0,
PROP_LOCATION,
PROP_TIME,
PROP_TIMEZONE,
N_PROPS
};
/* This function returns the current time in the clock's timezone.
* Note that this returns a new object every time, so we need to
* remember to unref it after use.
*/
static GDateTime *
gtk_clock_get_time (GtkClock *clock)
{
if (clock->timezone)
return g_date_time_new_now (clock->timezone);
else
return g_date_time_new_now_local ();
}
/* Here, we implement the functionality required by the GdkPaintable
* interface. This way we have a trivial way to display an analog clock.
* It also allows demonstrating how to directly use objects in the
* listview later by making this object do something interesting.
*/
static void
gtk_clock_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkClock *self = GTK_CLOCK (paintable);
GDateTime *time;
GskRoundedRect outline;
#define BLACK ((GdkRGBA) { 0, 0, 0, 1 })
/* save/restore() is necessary so we can undo the transforms we start
* out with.
*/
gtk_snapshot_save (snapshot);
/* First, we move the (0, 0) point to the center of the area so
* we can draw everything relative to it.
*/
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (width / 2, height / 2));
/* Next we scale it, so that we can pretend that the clock is
* 100px in size. That way, we don't need to do any complicated
* math later. We use MIN() here so that we use the smaller
* dimension for sizing. That way we don't overdraw but keep
* the aspect ratio.
*/
gtk_snapshot_scale (snapshot, MIN (width, height) / 100.0, MIN (width, height) / 100.0);
/* Now we have a circle with diameter 100px (and radius 50px) that
* has its (0, 0) point at the center. Let's draw a simple clock into it.
*/
time = gtk_clock_get_time (self);
/* First, draw a circle. This is a neat little trick to draw a circle
* without requiring Cairo.
*/
gsk_rounded_rect_init_from_rect (&outline, &GRAPHENE_RECT_INIT(-50, -50, 100, 100), 50);
gtk_snapshot_append_border (snapshot,
&outline,
(float[4]) { 4, 4, 4, 4 },
(GdkRGBA [4]) { BLACK, BLACK, BLACK, BLACK });
/* Next, draw the hour hand.
* We do this using tranforms again: Instead of computing where the angle
* points to, we just rotate everything and then draw the hand as if it
* was :00. We don't even need to care about am/pm here because rotations
* just work.
*/
gtk_snapshot_save (snapshot);
gtk_snapshot_rotate (snapshot, 30 * g_date_time_get_hour (time) + 0.5 * g_date_time_get_minute (time));
gsk_rounded_rect_init_from_rect (&outline, &GRAPHENE_RECT_INIT(-2, -23, 4, 25), 2);
gtk_snapshot_push_rounded_clip (snapshot, &outline);
gtk_snapshot_append_color (snapshot, &BLACK, &outline.bounds);
gtk_snapshot_pop (snapshot);
gtk_snapshot_restore (snapshot);
/* And the same as above for the minute hand. Just make this one longer
* so people can tell the hands apart.
*/
gtk_snapshot_save (snapshot);
gtk_snapshot_rotate (snapshot, 6 * g_date_time_get_minute (time));
gsk_rounded_rect_init_from_rect (&outline, &GRAPHENE_RECT_INIT(-2, -43, 4, 45), 2);
gtk_snapshot_push_rounded_clip (snapshot, &outline);
gtk_snapshot_append_color (snapshot, &BLACK, &outline.bounds);
gtk_snapshot_pop (snapshot);
gtk_snapshot_restore (snapshot);
/* and finally, the second indicator. */
gtk_snapshot_save (snapshot);
gtk_snapshot_rotate (snapshot, 6 * g_date_time_get_second (time));
gsk_rounded_rect_init_from_rect (&outline, &GRAPHENE_RECT_INIT(-2, -43, 4, 10), 2);
gtk_snapshot_push_rounded_clip (snapshot, &outline);
gtk_snapshot_append_color (snapshot, &BLACK, &outline.bounds);
gtk_snapshot_pop (snapshot);
gtk_snapshot_restore (snapshot);
/* And finally, don't forget to restore the initial save() that
* we did for the initial transformations.
*/
gtk_snapshot_restore (snapshot);
g_date_time_unref (time);
}
/* Our desired size is 100px. That sounds okay for an analog clock */
static int
gtk_clock_get_intrinsic_width (GdkPaintable *paintable)
{
return 100;
}
static int
gtk_clock_get_intrinsic_height (GdkPaintable *paintable)
{
return 100;
}
/* Initialize the paintable interface. This way we turn our clocks
* into objects that can be drawn. There are more functions to this
* interface to define desired size, but this is enough.
*/
static void
gtk_clock_paintable_init (GdkPaintableInterface *iface)
{
iface->snapshot = gtk_clock_snapshot;
iface->get_intrinsic_width = gtk_clock_get_intrinsic_width;
iface->get_intrinsic_height = gtk_clock_get_intrinsic_height;
}
/* Finally, we define the type. The important part is adding the
* paintable interface, so GTK knows that this object can indeed
* be drawn.
*/
G_DEFINE_TYPE_WITH_CODE (GtkClock, gtk_clock, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_clock_paintable_init))
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gtk_clock_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GtkClock *self = GTK_CLOCK (object);
switch (property_id)
{
case PROP_LOCATION:
g_value_set_string (value, self->location);
break;
case PROP_TIME:
g_value_take_boxed (value, gtk_clock_get_time (self));
break;
case PROP_TIMEZONE:
g_value_set_boxed (value, self->timezone);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gtk_clock_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GtkClock *self = GTK_CLOCK (object);
switch (property_id)
{
case PROP_LOCATION:
self->location = g_value_dup_string (value);
break;
case PROP_TIMEZONE:
self->timezone = g_value_dup_boxed (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
/* This is the list of all the ticking clocks */
static GSList *ticking_clocks = NULL;
/* This is the ID of the timeout source that is updating all
* ticking clocks.
*/
static guint ticking_clock_id = 0;
/* Every second, this function is called to tell everybody that
* the clocks are ticking.
*/
static gboolean
gtk_clock_tick (gpointer unused)
{
GSList *l;
for (l = ticking_clocks; l; l = l->next)
{
GtkClock *clock = l->data;
/* We will now return a different value for the time property,
* so notify about that.
*/
g_object_notify_by_pspec (G_OBJECT (clock), properties[PROP_TIME]);
/* We will also draw the hands of the clock differently.
* So notify about that, too.
*/
gdk_paintable_invalidate_contents (GDK_PAINTABLE (clock));
}
return G_SOURCE_CONTINUE;
}
static void
gtk_clock_stop_ticking (GtkClock *self)
{
ticking_clocks = g_slist_remove (ticking_clocks, self);
/* If no clock is remaining, stop running the tick updates */
if (ticking_clocks == NULL && ticking_clock_id != 0)
g_clear_handle_id (&ticking_clock_id, g_source_remove);
}
static void
gtk_clock_start_ticking (GtkClock *self)
{
/* if no clock is ticking yet, start */
if (ticking_clock_id == 0)
ticking_clock_id = g_timeout_add_seconds (1, gtk_clock_tick, NULL);
ticking_clocks = g_slist_prepend (ticking_clocks, self);
}
static void
gtk_clock_finalize (GObject *object)
{
GtkClock *self = GTK_CLOCK (object);
gtk_clock_stop_ticking (self);
g_free (self->location);
g_clear_pointer (&self->timezone, g_time_zone_unref);
G_OBJECT_CLASS (gtk_clock_parent_class)->finalize (object);
}
static void
gtk_clock_class_init (GtkClockClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = gtk_clock_get_property;
gobject_class->set_property = gtk_clock_set_property;
gobject_class->finalize = gtk_clock_finalize;
properties[PROP_LOCATION] =
g_param_spec_string ("location", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
properties[PROP_TIME] =
g_param_spec_boxed ("time", NULL, NULL, G_TYPE_DATE_TIME, G_PARAM_READABLE);
properties[PROP_TIMEZONE] =
g_param_spec_boxed ("timezone", NULL, NULL, G_TYPE_TIME_ZONE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
gtk_clock_init (GtkClock *self)
{
gtk_clock_start_ticking (self);
}
static GtkClock *
gtk_clock_new (const char *location,
GTimeZone *_tz)
{
GtkClock *result;
result = g_object_new (GTK_TYPE_CLOCK,
"location", location,
"timezone", _tz,
NULL);
g_clear_pointer (&_tz, g_time_zone_unref);
return result;
}
static GListModel *
create_clocks_model (void)
{
GListStore *result;
GtkClock *clock;
result = g_list_store_new (GTK_TYPE_CLOCK);
/* local time */
clock = gtk_clock_new ("local", NULL);
g_list_store_append (result, clock);
g_object_unref (clock);
/* UTC time */
clock = gtk_clock_new ("UTC", g_time_zone_new_utc ());
g_list_store_append (result, clock);
g_object_unref (clock);
/* A bunch of timezones with GTK hackers */
clock = gtk_clock_new ("San Francisco", g_time_zone_new ("America/Los_Angeles"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Xalapa", g_time_zone_new ("America/Mexico_City"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Boston", g_time_zone_new ("America/New_York"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("London", g_time_zone_new ("Europe/London"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Berlin", g_time_zone_new ("Europe/Berlin"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Moscow", g_time_zone_new ("Europe/Moscow"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("New Delhi", g_time_zone_new ("Asia/Kolkata"));
g_list_store_append (result, clock);
g_object_unref (clock);
clock = gtk_clock_new ("Shanghai", g_time_zone_new ("Asia/Shanghai"));
g_list_store_append (result, clock);
g_object_unref (clock);
return G_LIST_MODEL (result);
}
static char *
convert_time_to_string (GObject *image,
GDateTime *time,
gpointer unused)
{
return g_date_time_format (time, "%x\n%X");
}
/* And this function is the crux for this whole demo.
* It shows how to use expressions to set up bindings.
*/
static void
setup_listitem_cb (GtkListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *box, *picture, *location_label, *time_label;
GtkExpression *clock_expression, *expression;
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_list_item_set_child (list_item, box);
/* First, we create an expression that gets us the clock from the listitem:
* 1. Create an expression that gets the list item.
* 2. Use that expression's "item" property to get the clock
*/
expression = gtk_constant_expression_new (GTK_TYPE_LIST_ITEM, list_item);
clock_expression = gtk_property_expression_new (GTK_TYPE_LIST_ITEM, expression, "item");
/* Bind the clock's location to a label.
* This is easy: We just get the "location" property of the clock.
*/
expression = gtk_property_expression_new (GTK_TYPE_CLOCK,
gtk_expression_ref (clock_expression),
"location");
/* Now create the label and bind the expression to it. */
location_label = gtk_label_new (NULL);
gtk_expression_bind (expression, location_label, "label", location_label);
gtk_box_append (GTK_BOX (box), location_label);
/* Here we bind the item itself to a GdkPicture.
* This is simply done by using the clock expression itself.
*/
expression = gtk_expression_ref (clock_expression);
/* Now create the widget and bind the expression to it. */
picture = gtk_picture_new ();
gtk_expression_bind (expression, picture, "paintable", picture);
gtk_box_append (GTK_BOX (box), picture);
/* And finally, everything comes together.
* We create a label for displaying the time as text.
* For that, we need to transform the "GDateTime" of the
* time property into a string so that the label can display it.
*/
expression = gtk_property_expression_new (GTK_TYPE_CLOCK,
gtk_expression_ref (clock_expression),
"time");
expression = gtk_cclosure_expression_new (G_TYPE_STRING,
NULL,
1, (GtkExpression *[1]) { expression },
G_CALLBACK (convert_time_to_string),
NULL, NULL);
/* Now create the label and bind the expression to it. */
time_label = gtk_label_new (NULL);
gtk_expression_bind (expression, time_label, "label", time_label);
gtk_box_append (GTK_BOX (box), time_label);
gtk_expression_unref (clock_expression);
}
static GtkWidget *window = NULL;
GtkWidget *
do_listview_clocks (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *gridview, *sw;
GtkListItemFactory *factory;
GListModel *model;
GtkNoSelection *selection;
/* This is the normal window setup code every demo does */
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Clocks");
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
/* List widgets go into a scrolled window. Always. */
sw = gtk_scrolled_window_new ();
gtk_window_set_child (GTK_WINDOW (window), sw);
/* Create the factory that creates the listitems. Because we
* used bindings above during setup, we only need to connect
* to the setup signal.
* The bindings take care of the bind step.
*/
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_listitem_cb), NULL);
gridview = gtk_grid_view_new_with_factory (factory);
gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
gtk_scrollable_set_vscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
model = create_clocks_model ();
selection = gtk_no_selection_new (model);
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), G_LIST_MODEL (selection));
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), gridview);
g_object_unref (selection);
g_object_unref (model);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +0,0 @@
.view.compact > child {
padding: 1px;
}

View File

@@ -1,281 +0,0 @@
/* Lists/File browser
*
* This demo shows off the different layouts that are quickly achievable
* with GtkListview and GtkGridView by implementing a file browser with
* different views.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
static GtkWidget *window = NULL;
/* Create a simple object that holds the data for the different views */
typedef struct _FileBrowserView FileBrowserView;
struct _FileBrowserView
{
GObject parent_instance;
GtkListItemFactory *factory;
char *icon_name;
char *title;
GtkOrientation orientation;
};
enum {
PROP_0,
PROP_FACTORY,
PROP_ICON_NAME,
PROP_TITLE,
PROP_ORIENTATION,
N_PROPS
};
#define FILE_BROWSER_TYPE_VIEW (file_browser_view_get_type ())
G_DECLARE_FINAL_TYPE (FileBrowserView, file_browser_view, FILE_BROWSER, VIEW, GObject);
G_DEFINE_TYPE (FileBrowserView, file_browser_view, G_TYPE_OBJECT);
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
file_browser_view_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
FileBrowserView *self = FILE_BROWSER_VIEW (object);
switch (property_id)
{
case PROP_FACTORY:
g_value_set_object (value, self->factory);
break;
case PROP_ICON_NAME:
g_value_set_string (value, self->icon_name);
break;
case PROP_TITLE:
g_value_set_string (value, self->title);
break;
case PROP_ORIENTATION:
g_value_set_enum (value, self->orientation);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
file_browser_view_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
FileBrowserView *self = FILE_BROWSER_VIEW (object);
switch (prop_id)
{
case PROP_FACTORY:
g_set_object (&self->factory, g_value_get_object (value));
break;
case PROP_ICON_NAME:
g_free (self->icon_name);
self->icon_name = g_value_dup_string (value);
break;
case PROP_TITLE:
g_free (self->title);
self->title = g_value_dup_string (value);
break;
case PROP_ORIENTATION:
self->orientation = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
file_browser_view_finalize (GObject *object)
{
FileBrowserView *self = FILE_BROWSER_VIEW (object);
g_object_unref (self->factory);
g_free (self->icon_name);
g_free (self->title);
G_OBJECT_CLASS (file_browser_view_parent_class)->dispose (object);
}
static void
file_browser_view_class_init (FileBrowserViewClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = file_browser_view_get_property;
gobject_class->set_property = file_browser_view_set_property;
gobject_class->finalize = file_browser_view_finalize;
properties[PROP_FACTORY] =
g_param_spec_object ("factory",
"factory",
"factory to use in the main view",
GTK_TYPE_LIST_ITEM_FACTORY,
G_PARAM_READWRITE);
properties[PROP_ICON_NAME] =
g_param_spec_string ("icon-name",
"icon name",
"icon to display for selecting this view",
NULL,
G_PARAM_READWRITE);
properties[PROP_TITLE] =
g_param_spec_string ("title",
"title",
"title to display for selecting this view",
NULL,
G_PARAM_READWRITE);
properties[PROP_ORIENTATION] =
g_param_spec_enum ("orientation",
"orientation",
"orientation of the view",
GTK_TYPE_ORIENTATION,
GTK_ORIENTATION_VERTICAL,
G_PARAM_READWRITE);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void file_browser_view_init (FileBrowserView *self)
{
}
char *
filebrowser_get_display_name (GObject *object,
GFileInfo *info)
{
if (!info)
return NULL;
return g_strdup (g_file_info_get_attribute_string (info, "standard::display-name"));
}
char *
filebrowser_get_content_type (GObject *object,
GFileInfo *info)
{
if (!info)
return NULL;
return g_strdup (g_file_info_get_attribute_string (info, "standard::content-type"));
}
char *
filebrowser_get_size (GObject *object,
GFileInfo *info)
{
if (!info)
return NULL;
return g_format_size (g_file_info_get_attribute_uint64 (info, "standard::size"));
}
GIcon *
filebrowser_get_icon (GObject *object,
GFileInfo *info)
{
GIcon *icon;
if (info)
icon = G_ICON (g_file_info_get_attribute_object (info, "standard::icon"));
else
icon = NULL;
if (icon)
g_object_ref (icon);
return icon;
}
void
filebrowser_up_clicked_cb (GtkButton *button,
GtkDirectoryList *list)
{
GFile *file;
file = g_file_get_parent (gtk_directory_list_get_file (list));
if (file == NULL)
return;
gtk_directory_list_set_file (list, file);
}
void
filebrowser_view_activated_cb (GtkGridView *view,
guint pos,
GtkDirectoryList *list)
{
GFileInfo *info;
info = g_list_model_get_item (gtk_grid_view_get_model (view), pos);
if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
gtk_directory_list_set_file (list, G_FILE (g_file_info_get_attribute_object (info, "standard::file")));
g_object_unref (info);
}
GtkWidget *
do_listview_filebrowser (GtkWidget *do_widget)
{
if (!window)
{
GtkWidget *view;
GtkBuilder *builder;
GtkDirectoryList *dirlist;
GFile *file;
char *cwd;
GtkCssProvider *provider;
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/listview_filebrowser/listview_filebrowser.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
800);
g_object_unref (provider);
builder = gtk_builder_new_from_resource ("/listview_filebrowser/listview_filebrowser.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
/* Create the model and fill it with the contents of the current directory */
cwd = g_get_current_dir ();
file = g_file_new_for_path (cwd);
g_free (cwd);
dirlist = GTK_DIRECTORY_LIST (gtk_builder_get_object (builder, "dirlist"));
gtk_directory_list_set_file (dirlist, file);
g_object_unref (file);
/* grab focus in the view */
view = GTK_WIDGET (gtk_builder_get_object (builder, "view"));
gtk_widget_grab_focus (view);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,11 +0,0 @@
listview.viewswitcher {
border: 1px solid gray;
}
listview.viewswitcher > row {
padding: 5px;
}
listview.viewswitcher row:selected {
background: gray;
}

View File

@@ -1,248 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GListStore" id="viewlist">
<property name="item-type">FileBrowserView</property>
<child>
<object class="FileBrowserView">
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkBox">
<child>
<object class="GtkImage">
<binding name="gicon">
<closure type="GIcon" function="filebrowser_get_icon">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<closure type="gchararray" function="filebrowser_get_display_name">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
</object>
</child>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
<property name="icon-name">view-list-symbolic</property>
<property name="title" translatable="yes">List</property>
<property name="orientation">horizontal</property>
</object>
</child>
<child>
<object class="FileBrowserView">
<property name="icon-name">view-grid-symbolic</property>
<property name="title" translatable="yes">Grid</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkImage">
<property name="icon-size">large</property>
<binding name="gicon">
<closure type="GIcon" function="filebrowser_get_icon">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="wrap">1</property>
<property name="wrap-mode">word-char</property>
<property name="lines">2</property>
<property name="ellipsize">end</property>
<property name="width-chars">10</property>
<property name="max-width-chars">30</property>
<binding name="label">
<closure type="gchararray" function="filebrowser_get_display_name">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
</object>
</child>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
<property name="orientation">vertical</property>
</object>
</child>
<child>
<object class="FileBrowserView">
<property name="icon-name">view-paged-symbolic</property>
<property name="title" translatable="yes">Paged</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkBox">
<child>
<object class="GtkImage">
<property name="icon-size">large</property>
<binding name="gicon">
<closure type="GIcon" function="filebrowser_get_icon">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<closure type="gchararray" function="filebrowser_get_display_name">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<closure type="gchararray" function="filebrowser_get_size">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<closure type="gchararray" function="filebrowser_get_content_type">
<lookup name="item">GtkListItem</lookup>
</closure>
</binding>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
</child>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
<property name="orientation">horizontal</property>
</object>
</child>
</object>
<object class="GtkDirectoryList" id="dirlist">
<property name="attributes">standard::name,standard::display-name,standard::icon,standard::size,standard::content-type</property>
</object>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">File browser</property>
<property name="default-width">600</property>
<property name="default-height">400</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="">
<child>
<object class="GtkButton">
<property name="icon-name">go-up-symbolic</property>
<signal name="clicked" handler="filebrowser_up_clicked_cb" object="dirlist" swapped="no"/>
</object>
</child>
<child type="end">
<object class="GtkListView">
<property name="valign">center</property>
<property name="orientation">horizontal</property>
<style>
<class name="linked"/>
<class name="viewswitcher"/>
</style>
<property name="model">
<object class="GtkSingleSelection" id="selected-view">
<property name="model">viewlist</property>
</object>
</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkImage">
<binding name="icon-name">
<lookup type="FileBrowserView" name="icon-name">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
<binding name="tooltip-text">
<lookup type="FileBrowserView" name="title">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="can-focus">1</property>
<child>
<object class="GtkGridView" id="view">
<property name="model">dirlist</property>
<property name="max-columns">15</property>
<binding name="factory">
<lookup name="factory" type="FileBrowserView">
<lookup name="selected-item">selected-view</lookup>
</lookup>
</binding>
<binding name="orientation">
<lookup name="orientation" type="FileBrowserView">
<lookup name="selected-item">selected-view</lookup>
</lookup>
</binding>
<signal name="activate" handler="filebrowser_view_activated_cb" object="dirlist" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -1,472 +0,0 @@
/* Lists/Minesweeper
*
* This demo shows how to develop a user interface for small game using a
* gridview.
*
* It demonstrates how to use the activate signal and single-press behavior
* to implement rather different interaction behavior to a typical list.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
/*** The cell object ***/
/* Create an object that holds the data for a cell in the game */
typedef struct _SweeperCell SweeperCell;
struct _SweeperCell
{
GObject parent_instance;
gboolean is_mine;
gboolean is_visible;
guint neighbor_mines;
};
enum {
CELL_PROP_0,
CELL_PROP_LABEL,
N_CELL_PROPS
};
#define SWEEPER_TYPE_CELL (sweeper_cell_get_type ())
G_DECLARE_FINAL_TYPE (SweeperCell, sweeper_cell, SWEEPER, CELL, GObject);
G_DEFINE_TYPE (SweeperCell, sweeper_cell, G_TYPE_OBJECT);
static GParamSpec *cell_properties[N_CELL_PROPS] = { NULL, };
static const char *
sweeper_cell_get_label (SweeperCell *self)
{
static const char *minecount_labels[10] = { "", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
if (!self->is_visible)
return "?";
if (self->is_mine)
return "💣";
return minecount_labels[self->neighbor_mines];
}
static void
sweeper_cell_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
SweeperCell *self = SWEEPER_CELL (object);
switch (property_id)
{
case CELL_PROP_LABEL:
g_value_set_string (value, sweeper_cell_get_label (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
sweeper_cell_class_init (SweeperCellClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = sweeper_cell_get_property;
cell_properties[CELL_PROP_LABEL] =
g_param_spec_string ("label",
"label",
"label to display for this row",
NULL,
G_PARAM_READABLE);
g_object_class_install_properties (gobject_class, N_CELL_PROPS, cell_properties);
}
static void
sweeper_cell_init (SweeperCell *self)
{
}
static void
sweeper_cell_reveal (SweeperCell *self)
{
if (self->is_visible)
return;
self->is_visible = TRUE;
g_object_notify_by_pspec (G_OBJECT (self), cell_properties[CELL_PROP_LABEL]);
}
static SweeperCell *
sweeper_cell_new (void)
{
return g_object_new (SWEEPER_TYPE_CELL, NULL);
}
/*** The board object ***/
/* Create an object that holds the data for the game */
typedef struct _SweeperGame SweeperGame;
struct _SweeperGame
{
GObject parent_instance;
GPtrArray *cells;
guint width;
guint height;
gboolean playing;
gboolean win;
};
enum {
GAME_PROP_0,
GAME_PROP_HEIGHT,
GAME_PROP_PLAYING,
GAME_PROP_WIDTH,
GAME_PROP_WIN,
N_GAME_PROPS
};
#define SWEEPER_TYPE_GAME (sweeper_game_get_type ())
G_DECLARE_FINAL_TYPE (SweeperGame, sweeper_game, SWEEPER, GAME, GObject);
static GType
sweeper_game_list_model_get_item_type (GListModel *model)
{
return SWEEPER_TYPE_GAME;
}
static guint
sweeper_game_list_model_get_n_items (GListModel *model)
{
SweeperGame *self = SWEEPER_GAME (model);
return self->width * self->height;
}
static gpointer
sweeper_game_list_model_get_item (GListModel *model,
guint position)
{
SweeperGame *self = SWEEPER_GAME (model);
return g_object_ref (g_ptr_array_index (self->cells, position));
}
static void
sweeper_game_list_model_init (GListModelInterface *iface)
{
iface->get_item_type = sweeper_game_list_model_get_item_type;
iface->get_n_items = sweeper_game_list_model_get_n_items;
iface->get_item = sweeper_game_list_model_get_item;
}
G_DEFINE_TYPE_WITH_CODE (SweeperGame, sweeper_game, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, sweeper_game_list_model_init))
static GParamSpec *game_properties[N_GAME_PROPS] = { NULL, };
static void
sweeper_game_dispose (GObject *object)
{
SweeperGame *self = SWEEPER_GAME (object);
g_clear_pointer (&self->cells, g_ptr_array_unref);
G_OBJECT_CLASS (sweeper_game_parent_class)->dispose (object);
}
static void
sweeper_game_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
SweeperGame *self = SWEEPER_GAME (object);
switch (property_id)
{
case GAME_PROP_HEIGHT:
g_value_set_uint (value, self->height);
break;
case GAME_PROP_PLAYING:
g_value_set_boolean (value, self->playing);
break;
case GAME_PROP_WIDTH:
g_value_set_uint (value, self->width);
break;
case GAME_PROP_WIN:
g_value_set_boolean (value, self->win);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
sweeper_game_class_init (SweeperGameClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = sweeper_game_dispose;
gobject_class->get_property = sweeper_game_get_property;
game_properties[GAME_PROP_HEIGHT] =
g_param_spec_uint ("height",
"height",
"height of the game grid",
1, G_MAXUINT, 8,
G_PARAM_READABLE);
game_properties[GAME_PROP_PLAYING] =
g_param_spec_boolean ("playing",
"playing",
"if the game is still going on",
FALSE,
G_PARAM_READABLE);
game_properties[GAME_PROP_WIDTH] =
g_param_spec_uint ("width",
"width",
"width of the game grid",
1, G_MAXUINT, 8,
G_PARAM_READABLE);
game_properties[GAME_PROP_WIN] =
g_param_spec_boolean ("win",
"win",
"if the game was won",
FALSE,
G_PARAM_READABLE);
g_object_class_install_properties (gobject_class, N_GAME_PROPS, game_properties);
}
static void
sweeper_game_reset_board (SweeperGame *self,
guint width,
guint height)
{
guint i;
g_ptr_array_set_size (self->cells, 0);
for (i = 0; i < width * height; i++)
{
g_ptr_array_add (self->cells, sweeper_cell_new ());
}
if (self->width != width)
{
self->width = width;
g_object_notify_by_pspec (G_OBJECT (self), game_properties[GAME_PROP_WIDTH]);
}
if (self->height != height)
{
self->height = height;
g_object_notify_by_pspec (G_OBJECT (self), game_properties[GAME_PROP_HEIGHT]);
}
if (!self->playing)
{
self->playing = TRUE;
g_object_notify_by_pspec (G_OBJECT (self), game_properties[GAME_PROP_PLAYING]);
}
if (self->win)
{
self->win = FALSE;
g_object_notify_by_pspec (G_OBJECT (self), game_properties[GAME_PROP_WIN]);
}
}
static void
sweeper_game_place_mines (SweeperGame *self,
guint n_mines)
{
guint i;
for (i = 0; i < n_mines; i++)
{
SweeperCell *cell;
do {
cell = g_ptr_array_index (self->cells, g_random_int_range (0, self->cells->len));
} while (cell->is_mine);
cell->is_mine = TRUE;
}
}
static SweeperCell *
get_cell (SweeperGame *self,
guint x,
guint y)
{
return g_ptr_array_index (self->cells, y * self->width + x);
}
static void
sweeper_game_count_neighbor_mines (SweeperGame *self,
guint width,
guint height)
{
guint x, y, x2, y2;
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
SweeperCell *cell = get_cell (self, x, y);
for (y2 = MAX (1, y) - 1; y2 < MIN (height, y + 2); y2++)
{
for (x2 = MAX (1, x) - 1; x2 < MIN (width, x + 2); x2++)
{
SweeperCell *other = get_cell (self, x2, y2);
if (other->is_mine)
cell->neighbor_mines++;
}
}
}
}
}
static void
sweeper_game_new_game (SweeperGame *self,
guint width,
guint height,
guint n_mines)
{
guint n_items_before;
g_return_if_fail (n_mines <= width * height);
n_items_before = self->width * self->height;
g_object_freeze_notify (G_OBJECT (self));
sweeper_game_reset_board (self, width, height);
sweeper_game_place_mines (self, n_mines);
sweeper_game_count_neighbor_mines (self, width, height);
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items_before, width * height);
g_object_thaw_notify (G_OBJECT (self));
}
static void
sweeper_game_init (SweeperGame *self)
{
self->cells = g_ptr_array_new_with_free_func (g_object_unref);
sweeper_game_new_game (self, 8, 8, 10);
}
static void
sweeper_game_end (SweeperGame *self,
gboolean win)
{
if (self->playing)
{
self->playing = FALSE;
g_object_notify_by_pspec (G_OBJECT (self), game_properties[GAME_PROP_PLAYING]);
}
if (self->win != win)
{
self->win = win;
g_object_notify_by_pspec (G_OBJECT (self), game_properties[GAME_PROP_WIN]);
}
}
static void
sweeper_game_check_finished (SweeperGame *self)
{
guint i;
if (!self->playing)
return;
for (i = 0; i < self->cells->len; i++)
{
SweeperCell *cell = g_ptr_array_index (self->cells, i);
/* There's still a non-revealed cell that isn't a mine */
if (!cell->is_visible && !cell->is_mine)
return;
}
sweeper_game_end (self, TRUE);
}
static void
sweeper_game_reveal_cell (SweeperGame *self,
guint position)
{
SweeperCell *cell;
if (!self->playing)
return;
cell = g_ptr_array_index (self->cells, position);
sweeper_cell_reveal (cell);
if (cell->is_mine)
sweeper_game_end (self, FALSE);
sweeper_game_check_finished (self);
}
void
minesweeper_cell_clicked_cb (GtkGridView *gridview,
guint pos,
SweeperGame *game)
{
sweeper_game_reveal_cell (game, pos);
}
void
minesweeper_new_game_cb (GtkButton *button,
SweeperGame *game)
{
sweeper_game_new_game (game, 8, 8, 10);
}
static GtkWidget *window = NULL;
GtkWidget *
do_listview_minesweeper (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkBuilder *builder;
g_type_ensure (SWEEPER_TYPE_GAME);
builder = gtk_builder_new_from_resource ("/listview_minesweeper/listview_minesweeper.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,48 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="SweeperGame" id="game">
</object>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">Minesweeper</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="">
<child>
<object class="GtkButton">
<property name="label">New Game</property>
<signal name="clicked" handler="minesweeper_new_game_cb" object="game" swapped="no"/>
</object>
</child>
<child type="title">
<object class="GtkImage">
<property name="icon-name">trophy-gold</property>
<binding name="visible">
<lookup name="win">game</lookup>
</binding>
</object>
</child>
</object>
</child>
<child>
<object class="GtkGridView" id="view">
<property name="model">
<object class="GtkNoSelection">
<property name="model">game</property>
</object>
</property>
<property name="single-click-activate">1</property>
<binding name="max-columns">
<lookup name="width">game</lookup>
</binding>
<binding name="min-columns">
<lookup name="width">game</lookup>
</binding>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="resource">/listview_minesweeper/listview_minesweeper_cell.ui</property>
</object>
</property>
<signal name="activate" handler="minesweeper_cell_clicked_cb" object="game" swapped="no"/>
</object>
</child>
</object>
</interface>

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="halign">center</property>
<property name="valign">center</property>
<binding name="label">
<lookup name="label" type="SweeperCell">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>

View File

@@ -1,438 +0,0 @@
/* Lists/Settings
*
* This demo shows a settings viewer for GSettings.
*
* It demonstrates how to implement support for trees with GtkListView.
* It also shows how to set up sorting and filtering for columns in a
* GtkColumnView.
*/
#include <gtk/gtk.h>
#include <stdlib.h>
/* Create an object that wraps GSettingsSchemaKey because that's a boxed type */
typedef struct _SettingsKey SettingsKey;
struct _SettingsKey
{
GObject parent_instance;
GSettings *settings;
GSettingsSchemaKey *key;
};
enum {
PROP_0,
PROP_NAME,
PROP_SUMMARY,
PROP_DESCRIPTION,
PROP_VALUE,
PROP_TYPE,
PROP_DEFAULT_VALUE,
N_PROPS
};
#define SETTINGS_TYPE_KEY (settings_key_get_type ())
G_DECLARE_FINAL_TYPE (SettingsKey, settings_key, SETTINGS, KEY, GObject);
G_DEFINE_TYPE (SettingsKey, settings_key, G_TYPE_OBJECT);
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
settings_key_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
SettingsKey *self = SETTINGS_KEY (object);
switch (property_id)
{
case PROP_DESCRIPTION:
g_value_set_string (value, g_settings_schema_key_get_description (self->key));
break;
case PROP_NAME:
g_value_set_string (value, g_settings_schema_key_get_name (self->key));
break;
case PROP_SUMMARY:
g_value_set_string (value, g_settings_schema_key_get_summary (self->key));
break;
case PROP_VALUE:
{
GVariant *variant = g_settings_get_value (self->settings, g_settings_schema_key_get_name (self->key));
g_value_take_string (value, g_variant_print (variant, FALSE));
g_variant_unref (variant);
}
break;
case PROP_TYPE:
{
const GVariantType *type = g_settings_schema_key_get_value_type (self->key);
g_value_set_string (value, g_variant_type_peek_string (type));
}
break;
case PROP_DEFAULT_VALUE:
{
GVariant *variant = g_settings_schema_key_get_default_value (self->key);
g_value_take_string (value, g_variant_print (variant, FALSE));
g_variant_unref (variant);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
settings_key_finalize (GObject *object)
{
SettingsKey *self = SETTINGS_KEY (object);
g_object_unref (self->settings);
g_settings_schema_key_unref (self->key);
G_OBJECT_CLASS (settings_key_parent_class)->finalize (object);
}
static void
settings_key_class_init (SettingsKeyClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = settings_key_finalize;
gobject_class->get_property = settings_key_get_property;
properties[PROP_DESCRIPTION] =
g_param_spec_string ("description", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_NAME] =
g_param_spec_string ("name", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_SUMMARY] =
g_param_spec_string ("summary", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_VALUE] =
g_param_spec_string ("value", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_TYPE] =
g_param_spec_string ("type", NULL, NULL, NULL, G_PARAM_READABLE);
properties[PROP_DEFAULT_VALUE] =
g_param_spec_string ("default-value", NULL, NULL, NULL, G_PARAM_READABLE);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
settings_key_init (SettingsKey *self)
{
}
static SettingsKey *
settings_key_new (GSettings *settings,
GSettingsSchemaKey *key)
{
SettingsKey *result = g_object_new (SETTINGS_TYPE_KEY, NULL);
result->settings = g_object_ref (settings);
result->key = g_settings_schema_key_ref (key);
return result;
}
static void
item_value_changed (GtkEditableLabel *label,
GParamSpec *pspec,
GtkListItem *item)
{
SettingsKey *self;
const char *text;
const GVariantType *type;
GVariant *variant;
GError *error = NULL;
const char *name;
char *value;
text = gtk_editable_get_text (GTK_EDITABLE (label));
g_object_get (item, "item", &self, NULL);
g_object_unref (self);
type = g_settings_schema_key_get_value_type (self->key);
name = g_settings_schema_key_get_name (self->key);
variant = g_variant_parse (type, text, NULL, NULL, &error);
if (!variant)
{
g_warning ("%s", error->message);
g_clear_error (&error);
goto revert;
}
if (!g_settings_schema_key_range_check (self->key, variant))
{
g_warning ("Not a valid value for %s", name);
goto revert;
}
g_settings_set_value (self->settings, name, variant);
g_variant_unref (variant);
return;
revert:
gtk_widget_error_bell (GTK_WIDGET (label));
g_object_get (self, "value", &value, NULL);
gtk_editable_set_text (GTK_EDITABLE (label), value);
g_free (value);
}
static int
strvcmp (gconstpointer p1,
gconstpointer p2)
{
const char * const *s1 = p1;
const char * const *s2 = p2;
return strcmp (*s1, *s2);
}
static GtkFilter *current_filter;
static gboolean
transform_settings_to_keys (GBinding *binding,
const GValue *from_value,
GValue *to_value,
gpointer data)
{
GtkTreeListRow *treelistrow;
GSettings *settings;
GSettingsSchema *schema;
GListStore *store;
GtkSortListModel *sort_model;
GtkFilterListModel *filter_model;
GtkFilter *filter;
GtkNoSelection *selection_model;
char **keys;
guint i;
treelistrow = g_value_get_object (from_value);
if (treelistrow == NULL)
return TRUE;
settings = gtk_tree_list_row_get_item (treelistrow);
g_object_get (settings, "settings-schema", &schema, NULL);
store = g_list_store_new (SETTINGS_TYPE_KEY);
keys = g_settings_schema_list_keys (schema);
for (i = 0; keys[i] != NULL; i++)
{
GSettingsSchemaKey *almost_there = g_settings_schema_get_key (schema, keys[i]);
SettingsKey *finally = settings_key_new (settings, almost_there);
g_list_store_append (store, finally);
g_object_unref (finally);
g_settings_schema_key_unref (almost_there);
}
g_strfreev (keys);
g_settings_schema_unref (schema);
g_object_unref (settings);
sort_model = gtk_sort_list_model_new (G_LIST_MODEL (store),
gtk_column_view_get_sorter (GTK_COLUMN_VIEW (data)));
g_object_unref (store);
filter = gtk_string_filter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name"));
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (sort_model), filter);
g_object_unref (sort_model);
g_set_object (&current_filter, filter);
g_object_unref (filter);
selection_model = gtk_no_selection_new (G_LIST_MODEL (filter_model));
g_object_unref (filter_model);
g_value_take_object (to_value, selection_model);
return TRUE;
}
static GListModel *
create_settings_model (gpointer item,
gpointer unused)
{
GSettings *settings = item;
char **schemas;
GListStore *result;
guint i;
if (settings == NULL)
{
g_settings_schema_source_list_schemas (g_settings_schema_source_get_default (),
TRUE,
&schemas,
NULL);
}
else
{
schemas = g_settings_list_children (settings);
}
if (schemas == NULL || schemas[0] == NULL)
{
g_free (schemas);
return NULL;
}
qsort (schemas, g_strv_length (schemas), sizeof (char *), strvcmp);
result = g_list_store_new (G_TYPE_SETTINGS);
for (i = 0; schemas[i] != NULL; i++)
{
GSettings *child;
if (settings == NULL)
child = g_settings_new (schemas[i]);
else
child = g_settings_get_child (settings, schemas[i]);
g_list_store_append (result, child);
g_object_unref (child);
}
g_strfreev (schemas);
return G_LIST_MODEL (result);
}
static void
search_enabled (GtkSearchEntry *entry)
{
gtk_editable_set_text (GTK_EDITABLE (entry), "");
}
static void
search_changed (GtkSearchEntry *entry,
gpointer data)
{
const char *text = gtk_editable_get_text (GTK_EDITABLE (entry));
if (current_filter)
gtk_string_filter_set_search (GTK_STRING_FILTER (current_filter), text);
}
static void
stop_search (GtkSearchEntry *entry,
gpointer data)
{
gtk_editable_set_text (GTK_EDITABLE (entry), "");
if (current_filter)
gtk_string_filter_set_search (GTK_STRING_FILTER (current_filter), "");
}
static GtkWidget *window = NULL;
GtkWidget *
do_listview_settings (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *listview, *columnview;
GListModel *model;
GtkTreeListModel *treemodel;
GtkSingleSelection *selection;
GtkBuilderScope *scope;
GtkBuilder *builder;
GtkColumnViewColumn *name_column;
GtkColumnViewColumn *type_column;
GtkColumnViewColumn *default_column;
GtkColumnViewColumn *summary_column;
GtkColumnViewColumn *description_column;
GtkSorter *sorter;
GActionGroup *actions;
GAction *action;
g_type_ensure (SETTINGS_TYPE_KEY);
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "search_enabled", (GCallback)search_enabled);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "search_changed", (GCallback)search_changed);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "stop_search", (GCallback)stop_search);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "item_value_changed", (GCallback)item_value_changed);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
gtk_builder_add_from_resource (builder, "/listview_settings/listview_settings.ui", NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
listview = GTK_WIDGET (gtk_builder_get_object (builder, "listview"));
columnview = GTK_WIDGET (gtk_builder_get_object (builder, "columnview"));
type_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "type_column"));
default_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "default_column"));
summary_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "summary_column"));
description_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "description_column"));
actions = G_ACTION_GROUP (g_simple_action_group_new ());
action = G_ACTION (g_property_action_new ("show-type", type_column, "visible"));
g_action_map_add_action (G_ACTION_MAP (actions), action);
g_object_unref (action);
action = G_ACTION (g_property_action_new ("show-default", default_column, "visible"));
g_action_map_add_action (G_ACTION_MAP (actions), action);
g_object_unref (action);
action = G_ACTION (g_property_action_new ("show-summary", summary_column, "visible"));
g_action_map_add_action (G_ACTION_MAP (actions), action);
g_object_unref (action);
action = G_ACTION (g_property_action_new ("show-description", description_column, "visible"));
g_action_map_add_action (G_ACTION_MAP (actions), action);
g_object_unref (action);
gtk_widget_insert_action_group (columnview, "columnview", actions);
g_object_unref (actions);
model = create_settings_model (NULL, NULL);
treemodel = gtk_tree_list_model_new (FALSE,
model,
TRUE,
create_settings_model,
NULL,
NULL);
selection = gtk_single_selection_new (G_LIST_MODEL (treemodel));
g_object_bind_property_full (selection, "selected-item",
columnview, "model",
G_BINDING_SYNC_CREATE,
transform_settings_to_keys,
NULL,
columnview, NULL);
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
g_object_unref (selection);
g_object_unref (treemodel);
g_object_unref (model);
name_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "name_column"));
sorter = gtk_string_sorter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name"));
gtk_column_view_column_set_sorter (name_column, sorter);
g_object_unref (sorter);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,279 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">Settings</property>
<property name="default-width">640</property>
<property name="default-height">480</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child type="end">
<object class="GtkToggleButton" id="search_button">
<property name="icon-name">system-search-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkPaned">
<property name="position">300</property>
<child>
<object class="GtkScrolledWindow">
<child>
<object class="GtkListView" id="listview">
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkTreeExpander" id="expander">
<binding name="list-row">
<lookup name="item">GtkListItem</lookup>
</binding>
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="schema" type="GSettings">
<lookup name="item">expander</lookup>
</lookup>
</binding>
</object>
</property>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkSearchBar">
<property name="search-mode-enabled" bind-source="search_button" bind-property="active" bind-flags="bidirectional"/>
<signal name="notify::search-mode-enabled" handler="search_enabled" object="entry"/>
<child>
<object class="GtkSearchEntry" id="entry">
<signal name="search-changed" handler="search_changed"/>
<signal name="stop-search" handler="stop_search"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<child>
<object class="GtkColumnView" id="columnview">
<child>
<object class="GtkColumnViewColumn" id="name_column">
<property name="title">Name</property>
<property name="header-menu">header_menu</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="name" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn">
<property name="title">Value</property>
<property name="resizable">1</property>
<property name="header-menu">header_menu</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkEditableLabel">
<binding name="text">
<lookup name="value" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
<signal name="notify::label" handler="item_value_changed"/>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="type_column">
<property name="title">Type</property>
<property name="resizable">1</property>
<property name="header-menu">header_menu</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="type" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="default_column">
<property name="title">Default</property>
<property name="resizable">1</property>
<property name="expand">1</property>
<property name="header-menu">header_menu</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="default-value" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="summary_column">
<property name="title">Summary</property>
<property name="resizable">1</property>
<property name="visible">0</property>
<property name="expand">1</property>
<property name="header-menu">header_menu</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<property name="wrap">1</property>
<binding name="label">
<lookup name="summary" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkColumnViewColumn" id="description_column">
<property name="title">Description</property>
<property name="resizable">1</property>
<property name="visible">0</property>
<property name="expand">1</property>
<property name="header-menu">header_menu</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="xalign">0</property>
<property name="wrap">1</property>
<binding name="label">
<lookup name="description" type="SettingsKey">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</property>
</template>
</interface>
]]></property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<menu id="header_menu">
<section>
<item>
<attribute name="label" translatable="yes">Type</attribute>
<attribute name="action">columnview.show-type</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Default value</attribute>
<attribute name="action">columnview.show-default</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Summary</attribute>
<attribute name="action">columnview.show-summary</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Description</attribute>
<attribute name="action">columnview.show-description</attribute>
</item>
</section>
</menu>
</interface>

View File

@@ -1,329 +0,0 @@
/* Lists/Weather
*
* This demo shows a few of the rarer features of GtkListView and
* how they can be used to display weather information.
*
* The hourly weather info uses a horizontal listview. This is easy
* to achieve because GtkListView implements the GtkOrientable interface.
* To make the items in the list stand out more, the listview uses
* separators.
*
* A GtkNoSelectionModel is used to make sure no item in the list can be
* selected. All other interactions with the items is still possible.
*
* The dataset used here has 70000 items.
*/
#include <gtk/gtk.h>
#define GTK_TYPE_WEATHER_INFO (gtk_weather_info_get_type ())
G_DECLARE_FINAL_TYPE (GtkWeatherInfo, gtk_weather_info, GTK, WEATHER_INFO, GObject)
typedef enum {
GTK_WEATHER_CLEAR,
GTK_WEATHER_FEW_CLOUDS,
GTK_WEATHER_FOG,
GTK_WEATHER_OVERCAST,
GTK_WEATHER_SCATTERED_SHOWERS,
GTK_WEATHER_SHOWERS,
GTK_WEATHER_SNOW,
GTK_WEATHER_STORM
} GtkWeatherType;
struct _GtkWeatherInfo
{
GObject parent_instance;
gint64 timestamp;
int temperature;
GtkWeatherType weather_type;
};
struct _GtkWeatherInfoClass
{
GObjectClass parent_class;
};
G_DEFINE_TYPE (GtkWeatherInfo, gtk_weather_info, G_TYPE_OBJECT)
static void
gtk_weather_info_class_init (GtkWeatherInfoClass *klass)
{
}
static void
gtk_weather_info_init (GtkWeatherInfo *self)
{
}
static GtkWeatherInfo *
gtk_weather_info_new (GDateTime *timestamp,
GtkWeatherInfo *copy_from)
{
GtkWeatherInfo *result;
result = g_object_new (GTK_TYPE_WEATHER_INFO, NULL);
result->timestamp = g_date_time_to_unix (timestamp);
if (copy_from)
{
result->temperature = copy_from->temperature;
result->weather_type = copy_from->weather_type;
}
return result;
}
static GDateTime *
parse_timestamp (const char *string,
GTimeZone *_tz)
{
char *with_seconds;
GDateTime *result;
with_seconds = g_strconcat (string, ":00", NULL);
result = g_date_time_new_from_iso8601 (with_seconds, _tz);
g_free (with_seconds);
return result;
}
static GtkWeatherType
parse_weather_type (const char *clouds,
const char *precip,
GtkWeatherType fallback)
{
if (strstr (precip, "SN"))
return GTK_WEATHER_SNOW;
if (strstr (precip, "TS"))
return GTK_WEATHER_STORM;
if (strstr (precip, "DZ"))
return GTK_WEATHER_SCATTERED_SHOWERS;
if (strstr (precip, "SH") || strstr (precip, "RA"))
return GTK_WEATHER_SHOWERS;
if (strstr (precip, "FG"))
return GTK_WEATHER_FOG;
if (g_str_equal (clouds, "M") ||
g_str_equal (clouds, ""))
return fallback;
if (strstr (clouds, "OVC") ||
strstr (clouds, "BKN"))
return GTK_WEATHER_OVERCAST;
if (strstr (clouds, "BKN") ||
strstr (clouds, "SCT"))
return GTK_WEATHER_FEW_CLOUDS;
if (strstr (clouds, "VV"))
return GTK_WEATHER_FOG;
return GTK_WEATHER_CLEAR;
}
static double
parse_temperature (const char *s,
double fallback)
{
char *endptr;
double d;
d = g_ascii_strtod (s, &endptr);
if (*endptr != '\0')
return fallback;
return d;
}
static GListModel *
create_weather_model (void)
{
GListStore *store;
GTimeZone *utc;
GDateTime *timestamp;
GtkWeatherInfo *info;
GBytes *data;
char **lines;
guint i;
store = g_list_store_new (GTK_TYPE_WEATHER_INFO);
data = g_resources_lookup_data ("/listview_weather/listview_weather.txt", 0, NULL);
lines = g_strsplit (g_bytes_get_data (data, NULL), "\n", 0);
utc = g_time_zone_new_utc ();
timestamp = g_date_time_new (utc, 2011, 1, 1, 0, 0, 0);
info = gtk_weather_info_new (timestamp, NULL);
g_list_store_append (store, info);
g_object_unref (info);
for (i = 0; lines[i] != NULL && *lines[i]; i++)
{
char **fields;
GDateTime *date;
fields = g_strsplit (lines[i], ",", 0);
date = parse_timestamp (fields[0], utc);
while (g_date_time_difference (date, timestamp) > 30 * G_TIME_SPAN_MINUTE)
{
GDateTime *new_timestamp = g_date_time_add_hours (timestamp, 1);
g_date_time_unref (timestamp);
timestamp = new_timestamp;
info = gtk_weather_info_new (timestamp, info);
g_list_store_append (store, info);
g_object_unref (info);
}
info->temperature = parse_temperature (fields[1], info->temperature);
info->weather_type = parse_weather_type (fields[2], fields[3], info->weather_type);
g_date_time_unref (date);
g_strfreev (fields);
}
g_date_time_unref (timestamp);
g_strfreev (lines);
g_bytes_unref (data);
g_time_zone_unref (utc);
return G_LIST_MODEL (store);
}
static void
setup_widget (GtkSignalListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *box, *child;
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_list_item_set_child (list_item, box);
child = gtk_label_new (NULL);
gtk_label_set_width_chars (GTK_LABEL (child), 5);
gtk_box_append (GTK_BOX (box), child);
child = gtk_image_new ();
gtk_image_set_icon_size (GTK_IMAGE (child), GTK_ICON_SIZE_LARGE);
gtk_box_append (GTK_BOX (box), child);
child = gtk_label_new (NULL);
gtk_widget_set_vexpand (child, TRUE);
gtk_widget_set_valign (child, GTK_ALIGN_END);
gtk_label_set_width_chars (GTK_LABEL (child), 4);
gtk_box_append (GTK_BOX (box), child);
}
static void
bind_widget (GtkSignalListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *box, *child;
GtkWeatherInfo *info;
GDateTime *timestamp;
char *s;
box = gtk_list_item_get_child (list_item);
info = gtk_list_item_get_item (list_item);
child = gtk_widget_get_first_child (box);
timestamp = g_date_time_new_from_unix_utc (info->timestamp);
s = g_date_time_format (timestamp, "%R");
gtk_label_set_text (GTK_LABEL (child), s);
g_free (s);
g_date_time_unref (timestamp);
child = gtk_widget_get_next_sibling (child);
switch (info->weather_type)
{
case GTK_WEATHER_CLEAR:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-clear-symbolic");
break;
case GTK_WEATHER_FEW_CLOUDS:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-few-clouds-symbolic");
break;
case GTK_WEATHER_FOG:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-fog-symbolic");
break;
case GTK_WEATHER_OVERCAST:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-overcast-symbolic");
break;
case GTK_WEATHER_SCATTERED_SHOWERS:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-showers-scattered-symbolic");
break;
case GTK_WEATHER_SHOWERS:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-showers-symbolic");
break;
case GTK_WEATHER_SNOW:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-snow-symbolic");
break;
case GTK_WEATHER_STORM:
gtk_image_set_from_icon_name (GTK_IMAGE (child), "weather-storm-symbolic");
break;
default:
gtk_image_clear (GTK_IMAGE (child));
break;
}
child = gtk_widget_get_next_sibling (child);
s = g_strdup_printf ("%d°", info->temperature);
gtk_label_set_text (GTK_LABEL (child), s);
g_free (s);
}
static GtkWidget *window = NULL;
GtkWidget *
create_weather_view (void)
{
GtkWidget *listview;
GListModel *model, *selection;
GtkListItemFactory *factory;
factory = gtk_signal_list_item_factory_new ();
g_signal_connect (factory, "setup", G_CALLBACK (setup_widget), NULL);
g_signal_connect (factory, "bind", G_CALLBACK (bind_widget), NULL);
listview = gtk_list_view_new_with_factory (factory);
gtk_orientable_set_orientation (GTK_ORIENTABLE (listview), GTK_ORIENTATION_HORIZONTAL);
gtk_list_view_set_show_separators (GTK_LIST_VIEW (listview), TRUE);
model = create_weather_model ();
selection = G_LIST_MODEL (gtk_no_selection_new (model));
gtk_list_view_set_model (GTK_LIST_VIEW (listview), selection);
g_object_unref (selection);
g_object_unref (model);
return listview;
}
GtkWidget *
do_listview_weather (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *listview, *sw;
window = gtk_window_new ();
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
gtk_window_set_title (GTK_WINDOW (window), "Weather");
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Weather");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
sw = gtk_scrolled_window_new ();
gtk_window_set_child (GTK_WINDOW (window), sw);
listview = create_weather_view ();
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,238 +0,0 @@
/* Lists/Words
*
* This demo shows filtering a long list - of words.
*
* You should have the file `/usr/share/dict/words` installed for
* this demo to work.
*/
#include <gtk/gtk.h>
static GtkWidget *window = NULL;
static GtkWidget *progress;
const char *factory_text =
"<?xml version='1.0' encoding='UTF-8'?>\n"
"<interface>\n"
" <template class='GtkListItem'>\n"
" <property name='child'>\n"
" <object class='GtkLabel'>\n"
" <property name='ellipsize'>end</property>\n"
" <property name='xalign'>0</property>\n"
" <binding name='label'>\n"
" <lookup name='string' type='GtkStringObject'>\n"
" <lookup name='item'>GtkListItem</lookup>\n"
" </lookup>\n"
" </binding>\n"
" </object>\n"
" </property>\n"
" </template>\n"
"</interface>\n";
static void
update_title_cb (GtkFilterListModel *model)
{
guint total;
char *title;
guint pending;
total = g_list_model_get_n_items (gtk_filter_list_model_get_model (model));
pending = gtk_filter_list_model_get_pending (model);
title = g_strdup_printf ("%u lines", g_list_model_get_n_items (G_LIST_MODEL (model)));
gtk_widget_set_visible (progress, pending != 0);
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), (total - pending) / (double) total);
gtk_window_set_title (GTK_WINDOW (window), title);
g_free (title);
}
static void
read_lines_cb (GObject *object,
GAsyncResult *result,
gpointer data)
{
GBufferedInputStream *stream = G_BUFFERED_INPUT_STREAM (object);
GtkStringList *stringlist = data;
GError *error = NULL;
gsize size;
GPtrArray *lines;
gssize n_filled;
const char *buffer, *newline;
n_filled = g_buffered_input_stream_fill_finish (stream, result, &error);
if (n_filled < 0)
{
g_print ("Could not read data: %s\n", error->message);
g_clear_error (&error);
return;
}
buffer = g_buffered_input_stream_peek_buffer (stream, &size);
if (n_filled == 0)
{
if (size)
gtk_string_list_take (stringlist, g_utf8_make_valid (buffer, size));
return;
}
lines = NULL;
while ((newline = memchr (buffer, '\n', size)))
{
if (newline > buffer)
{
if (lines == NULL)
lines = g_ptr_array_new_with_free_func (g_free);
g_ptr_array_add (lines, g_utf8_make_valid (buffer, newline - buffer));
}
if (g_input_stream_skip (G_INPUT_STREAM (stream), newline - buffer + 1, NULL, &error) < 0)
{
g_clear_error (&error);
break;
}
buffer = g_buffered_input_stream_peek_buffer (stream, &size);
}
if (lines == NULL)
{
g_buffered_input_stream_set_buffer_size (stream, g_buffered_input_stream_get_buffer_size (stream) + 4096);
}
else
{
g_ptr_array_add (lines, NULL);
gtk_string_list_splice (stringlist, g_list_model_get_n_items (G_LIST_MODEL (stringlist)), 0, (const char **) lines->pdata);
g_ptr_array_free (lines, TRUE);
}
g_buffered_input_stream_fill_async (stream, -1, G_PRIORITY_HIGH_IDLE, NULL, read_lines_cb, data);
}
static void
file_is_open_cb (GObject *file,
GAsyncResult *result,
gpointer data)
{
GError *error = NULL;
GFileInputStream *file_stream;
GBufferedInputStream *stream;
file_stream = g_file_read_finish (G_FILE (file), result, &error);
if (file_stream == NULL)
{
g_print ("Could not open file: %s\n", error->message);
g_error_free (error);
return;
}
stream = G_BUFFERED_INPUT_STREAM (g_buffered_input_stream_new (G_INPUT_STREAM (file_stream)));
g_buffered_input_stream_fill_async (stream, -1, G_PRIORITY_HIGH_IDLE, NULL, read_lines_cb, data);
g_object_unref (stream);
}
static void
load_file (GtkStringList *list,
GFile *file)
{
gtk_string_list_splice (list, 0, g_list_model_get_n_items (G_LIST_MODEL (list)), NULL);
g_file_read_async (file, G_PRIORITY_HIGH_IDLE, NULL, file_is_open_cb, list);
}
static void
file_selected_cb (GtkWidget *button,
GtkStringList *stringlist)
{
GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (button));
if (file)
{
load_file (stringlist, file);
g_object_unref (file);
}
}
GtkWidget *
do_listview_words (GtkWidget *do_widget)
{
if (window == NULL)
{
GtkWidget *header, *listview, *sw, *vbox, *search_entry, *open_button, *overlay;
GtkFilterListModel *filter_model;
GtkNoSelection *selection;
GtkStringList *stringlist;
GtkFilter *filter;
GFile *file;
file = g_file_new_for_path ("/usr/share/dict/words");
if (g_file_query_exists (file, NULL))
{
stringlist = gtk_string_list_new (NULL);
load_file (stringlist, file);
}
else
{
char **words;
words = g_strsplit ("lorem ipsum dolor sit amet consectetur adipisci elit sed eiusmod tempor incidunt labore et dolore magna aliqua ut enim ad minim veniam quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat", " ", -1);
stringlist = gtk_string_list_new ((const char **) words);
g_strfreev (words);
}
filter = gtk_string_filter_new (gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string"));
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (stringlist), filter);
gtk_filter_list_model_set_incremental (filter_model, TRUE);
window = gtk_window_new ();
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
open_button = gtk_file_chooser_button_new ("_Open", GTK_FILE_CHOOSER_ACTION_OPEN);
g_signal_connect (open_button, "file-set", G_CALLBACK (file_selected_cb), stringlist);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), open_button);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer*)&window);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_window_set_child (GTK_WINDOW (window), vbox);
search_entry = gtk_search_entry_new ();
g_object_bind_property (search_entry, "text", filter, "search", 0);
gtk_box_append (GTK_BOX (vbox), search_entry);
overlay = gtk_overlay_new ();
gtk_box_append (GTK_BOX (vbox), overlay);
progress = gtk_progress_bar_new ();
gtk_widget_set_halign (progress, GTK_ALIGN_FILL);
gtk_widget_set_valign (progress, GTK_ALIGN_START);
gtk_widget_set_hexpand (progress, TRUE);
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), progress);
sw = gtk_scrolled_window_new ();
gtk_widget_set_vexpand (sw, TRUE);
gtk_overlay_set_child (GTK_OVERLAY (overlay), sw);
listview = gtk_list_view_new_with_factory (
gtk_builder_list_item_factory_new_from_bytes (NULL,
g_bytes_new_static (factory_text, strlen (factory_text))));
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);
selection = gtk_no_selection_new (G_LIST_MODEL (filter_model));
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
g_object_unref (selection);
g_signal_connect (filter_model, "items-changed", G_CALLBACK (update_title_cb), progress);
g_signal_connect (filter_model, "notify::pending", G_CALLBACK (update_title_cb), progress);
update_title_cb (filter_model);
g_object_unref (filter_model);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkTreeExpander" id="expander">
<binding name="list-row">
<lookup name="item">GtkListItem</lookup>
</binding>
<property name="child">
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<lookup name="title" type="GtkDemo">
<lookup name="item">expander</lookup>
</lookup>
</binding>
</object>
</property>
</object>
</property>
</template>
</interface>

View File

@@ -13,100 +13,21 @@
static GtkWidget *info_view; static GtkWidget *info_view;
static GtkWidget *source_view; static GtkWidget *source_view;
static char *current_file = NULL; static gchar *current_file = NULL;
static GtkWidget *notebook; static GtkWidget *notebook;
static GtkSingleSelection *selection; static GtkWidget *treeview;
static GtkWidget *toplevel; static GtkWidget *toplevel;
static char **search_needle;
typedef struct _GtkDemo GtkDemo;
struct _GtkDemo
{
GObject parent_instance;
const char *name;
const char *title;
const char *filename;
GDoDemoFunc func;
GListModel *children_model;
};
enum { enum {
PROP_0, NAME_COLUMN,
PROP_FILENAME, TITLE_COLUMN,
PROP_NAME, FILENAME_COLUMN,
PROP_TITLE, FUNC_COLUMN,
STYLE_COLUMN,
N_PROPS NUM_COLUMNS
}; };
# define GTK_TYPE_DEMO (gtk_demo_get_type ())
G_DECLARE_FINAL_TYPE (GtkDemo, gtk_demo, GTK, DEMO, GObject);
G_DEFINE_TYPE (GtkDemo, gtk_demo, G_TYPE_OBJECT);
static GParamSpec *properties[N_PROPS] = { NULL, };
static void
gtk_demo_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GtkDemo *self = GTK_DEMO (object);
switch (property_id)
{
case PROP_FILENAME:
g_value_set_string (value, self->filename);
break;
case PROP_NAME:
g_value_set_string (value, self->name);
break;
case PROP_TITLE:
g_value_set_string (value, self->title);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void gtk_demo_class_init (GtkDemoClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = gtk_demo_get_property;
properties[PROP_FILENAME] =
g_param_spec_string ("filename",
"filename",
"filename",
NULL,
G_PARAM_READABLE);
properties[PROP_NAME] =
g_param_spec_string ("name",
"name",
"name",
NULL,
G_PARAM_READABLE);
properties[PROP_TITLE] =
g_param_spec_string ("title",
"title",
"title",
NULL,
G_PARAM_READABLE);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void gtk_demo_init (GtkDemo *self)
{
}
typedef struct _CallbackData CallbackData; typedef struct _CallbackData CallbackData;
struct _CallbackData struct _CallbackData
{ {
@@ -114,34 +35,13 @@ struct _CallbackData
GtkTreePath *path; GtkTreePath *path;
}; };
static gboolean
gtk_demo_run (GtkDemo *self,
GtkWidget *window)
{
GtkWidget *result;
if (!self->func)
return FALSE;
result = self->func (window);
if (result == NULL)
return FALSE;
if (GTK_IS_WINDOW (result))
{
gtk_window_set_transient_for (GTK_WINDOW (result), GTK_WINDOW (window));
gtk_window_set_modal (GTK_WINDOW (result), TRUE);
}
return TRUE;
}
static void static void
activate_about (GSimpleAction *action, activate_about (GSimpleAction *action,
GVariant *parameter, GVariant *parameter,
gpointer user_data) gpointer user_data)
{ {
GtkApplication *app = user_data; GtkApplication *app = user_data;
const char *authors[] = { const gchar *authors[] = {
"The GTK Team", "The GTK Team",
NULL NULL
}; };
@@ -161,7 +61,7 @@ activate_about (GSimpleAction *action,
gtk_get_major_version (), gtk_get_major_version (),
gtk_get_minor_version (), gtk_get_minor_version (),
gtk_get_micro_version ()); gtk_get_micro_version ());
g_string_append_printf (s, "\nA link can appear here: <http://www.gtk.org>"); g_string_append_printf (s, "\nA link can apppear here: <http://www.gtk.org>");
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,
@@ -201,7 +101,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;
} }
@@ -215,15 +115,82 @@ activate_inspector (GSimpleAction *action,
gtk_window_set_interactive_debugging (TRUE); gtk_window_set_interactive_debugging (TRUE);
} }
static void
window_closed_cb (GtkWidget *window, gpointer data)
{
CallbackData *cbdata = data;
GtkTreeIter iter;
PangoStyle style;
gtk_tree_model_get_iter (cbdata->model, &iter, cbdata->path);
gtk_tree_model_get (GTK_TREE_MODEL (cbdata->model), &iter,
STYLE_COLUMN, &style,
-1);
if (style == PANGO_STYLE_ITALIC)
gtk_tree_store_set (GTK_TREE_STORE (cbdata->model), &iter,
STYLE_COLUMN, PANGO_STYLE_NORMAL,
-1);
gtk_tree_path_free (cbdata->path);
g_free (cbdata);
}
static void
run_example_for_row (GtkWidget *window,
GtkTreeModel *model,
GtkTreeIter *iter)
{
PangoStyle style;
GDoDemoFunc func;
GtkWidget *demo;
gtk_tree_model_get (GTK_TREE_MODEL (model),
iter,
FUNC_COLUMN, &func,
STYLE_COLUMN, &style,
-1);
if (func)
{
gtk_tree_store_set (GTK_TREE_STORE (model),
iter,
STYLE_COLUMN, (style == PANGO_STYLE_ITALIC ? PANGO_STYLE_NORMAL : PANGO_STYLE_ITALIC),
-1);
demo = (func) (window);
if (demo != NULL)
{
CallbackData *cbdata;
cbdata = g_new (CallbackData, 1);
cbdata->model = model;
cbdata->path = gtk_tree_model_get_path (model, iter);
if (GTK_IS_WINDOW (demo))
{
gtk_window_set_transient_for (GTK_WINDOW (demo), GTK_WINDOW (window));
gtk_window_set_modal (GTK_WINDOW (demo), TRUE);
}
g_signal_connect (demo, "destroy",
G_CALLBACK (window_closed_cb), cbdata);
}
}
}
static void static void
activate_run (GSimpleAction *action, activate_run (GSimpleAction *action,
GVariant *parameter, GVariant *parameter,
gpointer window) gpointer user_data)
{ {
GtkTreeListRow *row = gtk_single_selection_get_selected_item (selection); GtkWidget *window = user_data;
GtkDemo *demo = gtk_tree_list_row_get_item (row); GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
gtk_demo_run (demo, window); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
if (gtk_tree_selection_get_selected (selection, &model, &iter))
run_example_for_row (window, model, &iter);
} }
/* Stupid syntax highlighting. /* Stupid syntax highlighting.
@@ -252,9 +219,11 @@ static const char *types[] =
"static", "static",
"const ", "const ",
"void", "void",
"gint",
" int ", " int ",
" char ", " char ",
"char ", "gchar ",
"gfloat",
"float", "float",
"double", "double",
"gint8", "gint8",
@@ -270,6 +239,8 @@ static const char *types[] =
"gshort", "gshort",
"gushort", "gushort",
"gulong", "gulong",
"gdouble",
"gldouble",
"gpointer", "gpointer",
"NULL", "NULL",
"GList", "GList",
@@ -381,14 +352,14 @@ static const char *control[] =
NULL NULL
}; };
void void
parse_chars (char *text, parse_chars (gchar *text,
char **end_ptr, gchar **end_ptr,
int *state, gint *state,
const char **tag, const char **tag,
gboolean start) gboolean start)
{ {
int i; gint i;
char *next_token; gchar *next_token;
/* Handle comments first */ /* Handle comments first */
if (*state == STATE_IN_COMMENT) if (*state == STATE_IN_COMMENT)
@@ -458,7 +429,7 @@ parse_chars (char *text,
/* check for string */ /* check for string */
if (text[0] == '"') if (text[0] == '"')
{ {
int maybe_escape = FALSE; gint maybe_escape = FALSE;
*end_ptr = text + 1; *end_ptr = text + 1;
*tag = "string"; *tag = "string";
@@ -521,9 +492,9 @@ void
fontify (GtkTextBuffer *source_buffer) fontify (GtkTextBuffer *source_buffer)
{ {
GtkTextIter start_iter, next_iter, tmp_iter; GtkTextIter start_iter, next_iter, tmp_iter;
int state; gint state;
char *text; gchar *text;
char *start_ptr, *end_ptr; gchar *start_ptr, *end_ptr;
const char *tag; const char *tag;
gtk_text_buffer_create_tag (source_buffer, "source", gtk_text_buffer_create_tag (source_buffer, "source",
@@ -596,10 +567,10 @@ display_image (const char *resource)
{ {
GtkWidget *sw, *image; GtkWidget *sw, *image;
image = gtk_picture_new_for_resource (resource); image = gtk_image_new_from_resource (resource);
gtk_widget_set_halign (image, GTK_ALIGN_CENTER); gtk_widget_set_halign (image, GTK_ALIGN_CENTER);
gtk_widget_set_valign (image, GTK_ALIGN_CENTER); gtk_widget_set_valign (image, GTK_ALIGN_CENTER);
sw = gtk_scrolled_window_new (); sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), image); gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), image);
return sw; return sw;
@@ -639,7 +610,7 @@ display_text (const char *resource)
g_bytes_unref (bytes); g_bytes_unref (bytes);
sw = gtk_scrolled_window_new (); sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC); GTK_POLICY_AUTOMATIC);
@@ -691,10 +662,10 @@ static struct {
}; };
static void static void
add_data_tab (const char *demoname) add_data_tab (const gchar *demoname)
{ {
char *resource_dir, *resource_name; gchar *resource_dir, *resource_name;
char **resources; gchar **resources;
GtkWidget *widget, *label; GtkWidget *widget, *label;
guint i, j; guint i, j;
@@ -738,15 +709,15 @@ add_data_tab (const char *demoname)
static void static void
remove_data_tabs (void) remove_data_tabs (void)
{ {
int i; gint i;
for (i = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) - 1; i > 1; i--) for (i = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) - 1; i > 1; i--)
gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), i); gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), i);
} }
void void
load_file (const char *demoname, load_file (const gchar *demoname,
const char *filename) const gchar *filename)
{ {
GtkTextBuffer *info_buffer, *source_buffer; GtkTextBuffer *info_buffer, *source_buffer;
GtkTextIter start, end; GtkTextIter start, end;
@@ -754,9 +725,9 @@ load_file (const char *demoname,
GError *err = NULL; GError *err = NULL;
int state = 0; int state = 0;
gboolean in_para = 0; gboolean in_para = 0;
char **lines; gchar **lines;
GBytes *bytes; GBytes *bytes;
int i; gint i;
if (!g_strcmp0 (current_file, filename)) if (!g_strcmp0 (current_file, filename))
return; return;
@@ -796,9 +767,9 @@ load_file (const char *demoname,
gtk_text_buffer_get_iter_at_offset (info_buffer, &start, 0); gtk_text_buffer_get_iter_at_offset (info_buffer, &start, 0);
for (i = 0; lines[i] != NULL; i++) for (i = 0; lines[i] != NULL; i++)
{ {
char *p; gchar *p;
char *q; gchar *q;
char *r; gchar *r;
/* Make sure \r is stripped at the end for the poor windows people */ /* Make sure \r is stripped at the end for the poor windows people */
lines[i] = g_strchomp (lines[i]); lines[i] = g_strchomp (lines[i]);
@@ -924,194 +895,124 @@ load_file (const char *demoname,
} }
static void static void
activate_cb (GtkWidget *widget, selection_cb (GtkTreeSelection *selection,
guint position, GtkTreeModel *model)
gpointer window)
{ {
GtkTreeListRow *row = g_list_model_get_item (gtk_list_view_get_model (GTK_LIST_VIEW (widget)), position); GtkTreeIter iter;
GtkDemo *demo = gtk_tree_list_row_get_item (row); char *name;
char *filename;
char *title;
gtk_demo_run (demo, window); if (! gtk_tree_selection_get_selected (selection, NULL, &iter))
return;
g_object_unref (row); gtk_tree_model_get (model, &iter,
NAME_COLUMN, &name,
TITLE_COLUMN, &title,
FILENAME_COLUMN, &filename,
-1);
if (filename)
load_file (name, filename);
gtk_window_set_title (GTK_WINDOW (toplevel), title);
g_free (name);
g_free (title);
g_free (filename);
} }
static void static void
selection_cb (GtkSingleSelection *sel, populate_model (GtkTreeModel *model)
GParamSpec *pspec,
gpointer user_data)
{ {
GtkTreeListRow *row = gtk_single_selection_get_selected_item (sel); Demo *d = gtk_demos;
GtkDemo *demo;
gtk_widget_set_sensitive (GTK_WIDGET (notebook), !!row); /* this code only supports 1 level of children. If we
* want more we probably have to use a recursing function.
if (!row) */
while (d->title)
{ {
gtk_window_set_title (GTK_WINDOW (toplevel), "No match"); Demo *children = d->children;
GtkTreeIter iter;
return; gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
}
demo = gtk_tree_list_row_get_item (row); gtk_tree_store_set (GTK_TREE_STORE (model),
&iter,
NAME_COLUMN, d->name,
TITLE_COLUMN, d->title,
FILENAME_COLUMN, d->filename,
FUNC_COLUMN, d->func,
STYLE_COLUMN, PANGO_STYLE_NORMAL,
-1);
if (demo->filename) d++;
load_file (demo->name, demo->filename);
gtk_window_set_title (GTK_WINDOW (toplevel), demo->title); if (!children)
}
static gboolean
filter_demo (GtkDemo *demo)
{
int i;
/* Show only if the name maches every needle */
for (i = 0; search_needle[i]; i++)
{
if (!demo->title)
return FALSE;
if (g_str_match_string (search_needle[i], demo->title, TRUE))
continue; continue;
return FALSE; while (children->title)
}
return TRUE;
}
static gboolean
demo_filter_by_name (GtkTreeListRow *row,
GtkFilterListModel *model)
{
GListModel *children;
GtkDemo *demo;
guint i, n;
/* Show all items if search is empty */
if (!search_needle || !search_needle[0] || !*search_needle[0])
return TRUE;
g_assert (GTK_IS_TREE_LIST_ROW (row));
g_assert (GTK_IS_FILTER_LIST_MODEL (model));
children = gtk_tree_list_row_get_children (row);
if (children)
{
n = g_list_model_get_n_items (children);
for (i = 0; i < n; i++)
{ {
demo = g_list_model_get_item (children, i); GtkTreeIter child_iter;
g_assert (GTK_IS_DEMO (demo));
if (filter_demo (demo)) gtk_tree_store_append (GTK_TREE_STORE (model), &child_iter, &iter);
{
g_object_unref (demo); gtk_tree_store_set (GTK_TREE_STORE (model),
return TRUE; &child_iter,
} NAME_COLUMN, children->name,
g_object_unref (demo); TITLE_COLUMN, children->title,
FILENAME_COLUMN, children->filename,
FUNC_COLUMN, children->func,
STYLE_COLUMN, PANGO_STYLE_NORMAL,
-1);
children++;
} }
} }
demo = gtk_tree_list_row_get_item (row);
g_assert (GTK_IS_DEMO (demo));
return filter_demo (demo);
} }
static void static void
demo_search_changed_cb (GtkSearchEntry *entry, startup (GApplication *app)
GtkFilter *filter)
{ {
const char *text; GtkBuilder *builder;
GMenuModel *appmenu;
const char *ids[] = { "appmenu", NULL };
g_assert (GTK_IS_SEARCH_ENTRY (entry)); builder = gtk_builder_new ();
g_assert (GTK_IS_FILTER (filter)); gtk_builder_add_objects_from_resource (builder, "/ui/appmenu.ui", ids, NULL);
text = gtk_editable_get_text (GTK_EDITABLE (entry)); appmenu = (GMenuModel *)gtk_builder_get_object (builder, "appmenu");
g_clear_pointer (&search_needle, g_strfreev); gtk_application_set_app_menu (GTK_APPLICATION (app), appmenu);
if (text && *text) g_object_unref (builder);
search_needle = g_strsplit (text, " ", 0);
gtk_filter_changed (filter, GTK_FILTER_CHANGE_DIFFERENT);
}
static GListModel *
create_demo_model (void)
{
GListStore *store = g_list_store_new (GTK_TYPE_DEMO);
DemoData *demo = gtk_demos;
while (demo->title)
{
GtkDemo *d = GTK_DEMO (g_object_new (GTK_TYPE_DEMO, NULL));
DemoData *children = demo->children;
d->name = demo->name;
d->title = demo->title;
d->filename = demo->filename;
d->func = demo->func;
g_list_store_append (store, d);
if (children)
{
d->children_model = G_LIST_MODEL (g_list_store_new (GTK_TYPE_DEMO));
while (children->title)
{
GtkDemo *child = GTK_DEMO (g_object_new (GTK_TYPE_DEMO, NULL));
child->name = children->name;
child->title = children->title;
child->filename = children->filename;
child->func = children->func;
g_list_store_append (G_LIST_STORE (d->children_model), child);
children++;
}
}
demo++;
}
return G_LIST_MODEL (store);
}
static GListModel *
get_child_model (gpointer item,
gpointer user_data)
{
GtkDemo *demo = item;
if (demo->children_model)
return g_object_ref (G_LIST_MODEL (demo->children_model));
return NULL;
} }
static void static void
clear_search (GtkSearchBar *bar) row_activated_cb (GtkWidget *tree_view,
GtkTreePath *path,
GtkTreeViewColumn *column)
{ {
if (!gtk_search_bar_get_search_mode (bar)) GtkTreeIter iter;
{ GtkWidget *window;
GtkWidget *entry = gtk_search_bar_get_child (GTK_SEARCH_BAR (bar)); GtkTreeModel *model;
gtk_editable_set_text (GTK_EDITABLE (entry), "");
} window = GTK_WIDGET (gtk_widget_get_root (tree_view));
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
gtk_tree_model_get_iter (model, &iter, path);
run_example_for_row (window, model, &iter);
} }
static void static void
activate (GApplication *app) activate (GApplication *app)
{ {
GtkBuilder *builder; GtkBuilder *builder;
GListModel *listmodel; GtkWindow *window;
GtkTreeListModel *treemodel; GtkWidget *widget;
GtkWidget *window, *listview, *search_entry, *search_bar; GtkTreeModel *model;
GtkFilterListModel *filter_model; GtkTreeIter iter;
GtkFilter *filter;
static GActionEntry win_entries[] = { static GActionEntry win_entries[] = {
{ "run", activate_run, NULL, NULL, NULL } { "run", activate_run, NULL, NULL, NULL }
@@ -1119,40 +1020,35 @@ activate (GApplication *app)
builder = gtk_builder_new_from_resource ("/ui/main.ui"); builder = gtk_builder_new_from_resource ("/ui/main.ui");
window = (GtkWidget *)gtk_builder_get_object (builder, "window"); window = (GtkWindow *)gtk_builder_get_object (builder, "window");
gtk_application_add_window (GTK_APPLICATION (app), GTK_WINDOW (window)); gtk_application_add_window (GTK_APPLICATION (app), window);
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),
window); window);
notebook = GTK_WIDGET (gtk_builder_get_object (builder, "notebook")); notebook = (GtkWidget *)gtk_builder_get_object (builder, "notebook");
info_view = GTK_WIDGET (gtk_builder_get_object (builder, "info-textview")); info_view = (GtkWidget *)gtk_builder_get_object (builder, "info-textview");
source_view = GTK_WIDGET (gtk_builder_get_object (builder, "source-textview")); source_view = (GtkWidget *)gtk_builder_get_object (builder, "source-textview");
treeview = (GtkWidget *)gtk_builder_get_object (builder, "treeview");
model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
toplevel = GTK_WIDGET (window); toplevel = GTK_WIDGET (window);
listview = GTK_WIDGET (gtk_builder_get_object (builder, "listview"));
g_signal_connect (listview, "activate", G_CALLBACK (activate_cb), window);
search_bar = GTK_WIDGET (gtk_builder_get_object (builder, "searchbar"));
g_signal_connect (search_bar, "notify::search-mode-enabled", G_CALLBACK (clear_search), NULL);
listmodel = create_demo_model (); load_file (gtk_demos[0].name, gtk_demos[0].filename);
treemodel = gtk_tree_list_model_new (FALSE,
G_LIST_MODEL (listmodel),
TRUE,
get_child_model,
NULL,
NULL);
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (treemodel), NULL);
filter = gtk_custom_filter_new ((GtkCustomFilterFunc)demo_filter_by_name, filter_model, NULL);
gtk_filter_list_model_set_filter (filter_model, filter);
search_entry = GTK_WIDGET (gtk_builder_get_object (builder, "search-entry"));
g_signal_connect (search_entry, "search-changed", G_CALLBACK (demo_search_changed_cb), filter);
selection = gtk_single_selection_new (G_LIST_MODEL (filter_model)); populate_model (model);
g_signal_connect (selection, "notify::selected-item", G_CALLBACK (selection_cb), NULL);
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
selection_cb (selection, NULL, NULL); g_signal_connect (treeview, "row-activated", G_CALLBACK (row_activated_cb), model);
widget = (GtkWidget *)gtk_builder_get_object (builder, "treeview-selection");
g_signal_connect (widget, "changed", G_CALLBACK (selection_cb), model);
gtk_tree_model_get_iter_first (gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)), &iter);
gtk_tree_selection_select_iter (GTK_TREE_SELECTION (widget), &iter);
gtk_tree_view_collapse_all (GTK_TREE_VIEW (treeview));
gtk_widget_show (GTK_WIDGET (window));
g_object_unref (builder); g_object_unref (builder);
} }
@@ -1167,7 +1063,7 @@ auto_quit (gpointer data)
static void static void
list_demos (void) list_demos (void)
{ {
DemoData *d, *c; Demo *d, *c;
d = gtk_demos; d = gtk_demos;
@@ -1186,15 +1082,15 @@ list_demos (void)
} }
} }
static int static gint
command_line (GApplication *app, command_line (GApplication *app,
GApplicationCommandLine *cmdline) GApplicationCommandLine *cmdline)
{ {
GVariantDict *options; GVariantDict *options;
const char *name = NULL; const gchar *name = NULL;
gboolean autoquit = FALSE; gboolean autoquit = FALSE;
gboolean list = FALSE; gboolean list = FALSE;
DemoData *d, *c; Demo *d, *c;
GDoDemoFunc func = 0; GDoDemoFunc func = 0;
GtkWidget *window, *demo; GtkWidget *window, *demo;
@@ -1212,11 +1108,11 @@ command_line (GApplication *app,
return 0; return 0;
} }
window = gtk_application_get_windows (GTK_APPLICATION (app))->data;
if (name == NULL) if (name == NULL)
goto out; goto out;
window = gtk_application_get_windows (GTK_APPLICATION (app))->data;
d = gtk_demos; d = gtk_demos;
while (d->title) while (d->title)
@@ -1245,11 +1141,8 @@ out:
demo = (func) (window); demo = (func) (window);
gtk_window_set_transient_for (GTK_WINDOW (demo), GTK_WINDOW (window)); gtk_window_set_transient_for (GTK_WINDOW (demo), GTK_WINDOW (window));
gtk_window_set_modal (GTK_WINDOW (demo), TRUE);
g_signal_connect_swapped (G_OBJECT (demo), "destroy", G_CALLBACK (g_application_quit), app);
} }
else
gtk_widget_show (GTK_WIDGET (window));
if (autoquit) if (autoquit)
g_timeout_add_seconds (1, auto_quit, app); g_timeout_add_seconds (1, auto_quit, app);
@@ -1260,7 +1153,7 @@ out:
static void static void
print_version (void) print_version (void)
{ {
g_print ("gtk4-demo %d.%d.%d\n", g_print ("gtk3-demo %d.%d.%d\n",
gtk_get_major_version (), gtk_get_major_version (),
gtk_get_minor_version (), gtk_get_minor_version (),
gtk_get_micro_version ()); gtk_get_micro_version ());
@@ -1294,14 +1187,24 @@ main (int argc, char **argv)
{ "inspector", activate_inspector, NULL, NULL, NULL }, { "inspector", activate_inspector, NULL, NULL, NULL },
}; };
struct { struct {
const char *action_and_target; const gchar *action_and_target;
const char *accelerators[2]; const gchar *accelerators[2];
} accels[] = { } accels[] = {
{ "app.about", { "F1", NULL } }, { "app.about", { "F1", NULL } },
{ "app.quit", { "<Control>q", NULL } }, { "app.quit", { "<Control>q", NULL } },
}; };
int i; int i;
/* Most code in gtk-demo is intended to be exemplary, but not
* these few lines, which are just a hack so gtk-demo will work
* in the GTK tree without installing it.
*/
if (g_file_test ("../../modules/input/immodules.cache", G_FILE_TEST_EXISTS))
{
g_setenv ("GTK_IM_MODULE_FILE", "../../modules/input/immodules.cache", TRUE);
}
/* -- End of hack -- */
app = gtk_application_new ("org.gtk.Demo4", G_APPLICATION_NON_UNIQUE|G_APPLICATION_HANDLES_COMMAND_LINE); app = gtk_application_new ("org.gtk.Demo4", G_APPLICATION_NON_UNIQUE|G_APPLICATION_HANDLES_COMMAND_LINE);
g_action_map_add_action_entries (G_ACTION_MAP (app), g_action_map_add_action_entries (G_ACTION_MAP (app),
@@ -1316,6 +1219,7 @@ main (int argc, char **argv)
g_application_add_main_option (G_APPLICATION (app), "list", 0, 0, G_OPTION_ARG_NONE, "List examples", NULL); g_application_add_main_option (G_APPLICATION (app), "list", 0, 0, G_OPTION_ARG_NONE, "List examples", NULL);
g_application_add_main_option (G_APPLICATION (app), "autoquit", 0, 0, G_OPTION_ARG_NONE, "Quit after a delay", NULL); g_application_add_main_option (G_APPLICATION (app), "autoquit", 0, 0, G_OPTION_ARG_NONE, "Quit after a delay", NULL);
g_signal_connect (app, "startup", G_CALLBACK (startup), NULL);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL); g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL);
g_signal_connect (app, "handle-local-options", G_CALLBACK (local_options), NULL); g_signal_connect (app, "handle-local-options", G_CALLBACK (local_options), NULL);

View File

@@ -16,6 +16,15 @@
</item> </item>
</section> </section>
</menu> </menu>
<object class="GtkTreeStore" id="treestore">
<columns>
<column type="gchararray"/>
<column type="gchararray"/>
<column type="gchararray"/>
<column type="gpointer"/>
<column type="gint"/>
</columns>
</object>
<object class="GtkApplicationWindow" id="window"> <object class="GtkApplicationWindow" id="window">
<style> <style>
<class name="devel"/> <class name="devel"/>
@@ -24,6 +33,7 @@
<property name="default-height">600</property> <property name="default-height">600</property>
<child type="titlebar"> <child type="titlebar">
<object class="GtkHeaderBar" id="headerbar"> <object class="GtkHeaderBar" id="headerbar">
<property name="show-title-buttons">1</property>
<child> <child>
<object class="GtkButton"> <object class="GtkButton">
<property name="valign">center</property> <property name="valign">center</property>
@@ -50,41 +60,43 @@
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<child> <child>
<object class="GtkScrolledWindow"> <object class="GtkFrame">
<property name="width-request">120</property>
<property name="hscrollbar-policy">never</property>
<property name="min-content-width">150</property>
<child> <child>
<object class="GtkBox"> <object class="GtkScrolledWindow">
<property name="width-request">220</property> <property name="width-request">120</property>
<property name="orientation">vertical</property> <property name="hscrollbar-policy">never</property>
<property name="min-content-width">150</property>
<child> <child>
<object class="GtkSearchBar" id="searchbar"> <object class="GtkTreeView" id="treeview">
<property name="key-capture-widget">window</property> <property name="model">treestore</property>
<property name="headers-visible">0</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection">
<property name="mode">browse</property>
</object>
</child>
<child> <child>
<object class="GtkSearchEntry" id="search-entry"/> <object class="GtkTreeViewColumn">
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="style">4</attribute>
<attribute name="text">1</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererText">
<property name="text"> </property>
</object>
</child>
</object>
</child> </child>
</object> </object>
</child> </child>
<child>
<object class="GtkListView" id="listview">
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="resource">/ui/main-listitem.ui</property>
</object>
</property>
</object>
</child>
</object> </object>
</child> </child>
</object> </object>
</child> </child>
<child>
<object class="GtkSeparator"/>
</child>
<child> <child>
<object class="GtkNotebook" id="notebook"> <object class="GtkNotebook" id="notebook">
<property name="scrollable">1</property> <property name="scrollable">1</property>

View File

@@ -21,7 +21,7 @@ source_toggled (GtkToggleButton *button)
{ {
GtkTextBuffer *buffer; GtkTextBuffer *buffer;
GtkTextIter start, end; GtkTextIter start, end;
char *markup; gchar *markup;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view2)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view2));
gtk_text_buffer_get_bounds (buffer, &start, &end); gtk_text_buffer_get_bounds (buffer, &start, &end);
@@ -50,7 +50,7 @@ do_markup (GtkWidget *do_widget)
GtkTextBuffer *buffer; GtkTextBuffer *buffer;
GtkTextIter iter; GtkTextIter iter;
GBytes *bytes; GBytes *bytes;
const char *markup; const gchar *markup;
GtkWidget *header; GtkWidget *header;
GtkWidget *show_source; GtkWidget *show_source;
@@ -58,7 +58,8 @@ do_markup (GtkWidget *do_widget)
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_default_size (GTK_WINDOW (window), 450, 450); gtk_window_set_default_size (GTK_WINDOW (window), 450, 450);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window); g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
stack = gtk_stack_new (); stack = gtk_stack_new ();
gtk_widget_show (stack); gtk_widget_show (stack);
@@ -69,6 +70,7 @@ do_markup (GtkWidget *do_widget)
g_signal_connect (show_source, "toggled", G_CALLBACK (source_toggled), stack); g_signal_connect (show_source, "toggled", G_CALLBACK (source_toggled), stack);
header = gtk_header_bar_new (); header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), show_source); gtk_header_bar_pack_start (GTK_HEADER_BAR (header), show_source);
gtk_window_set_titlebar (GTK_WINDOW (window), header); gtk_window_set_titlebar (GTK_WINDOW (window), header);
@@ -80,7 +82,7 @@ do_markup (GtkWidget *do_widget)
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 10); gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 10);
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view), 10); gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view), 10);
sw = gtk_scrolled_window_new (); sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC); GTK_POLICY_AUTOMATIC);
@@ -93,7 +95,7 @@ do_markup (GtkWidget *do_widget)
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view2), 10); gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view2), 10);
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view2), 10); gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view2), 10);
sw = gtk_scrolled_window_new (); sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC); GTK_POLICY_AUTOMATIC);
@@ -102,7 +104,7 @@ do_markup (GtkWidget *do_widget)
gtk_stack_add_named (GTK_STACK (stack), sw, "source"); gtk_stack_add_named (GTK_STACK (stack), sw, "source");
bytes = g_resources_lookup_data ("/markup/markup.txt", 0, NULL); bytes = g_resources_lookup_data ("/markup/markup.txt", 0, NULL);
markup = (const char *)g_bytes_get_data (bytes, NULL); markup = (const gchar *)g_bytes_get_data (bytes, NULL);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
gtk_text_buffer_get_start_iter (buffer, &iter); gtk_text_buffer_get_start_iter (buffer, &iter);
@@ -124,7 +126,7 @@ do_markup (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;
} }

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