Compare commits
1 Commits
wip/otte/s
...
arnaudb/cs
Author | SHA1 | Date | |
---|---|---|---|
|
95b26ac974 |
154
.gitlab-ci.yml
154
.gitlab-ci.yml
@@ -17,12 +17,7 @@ stages:
|
||||
# Common variables
|
||||
variables:
|
||||
COMMON_MESON_FLAGS: "--fatal-meson-warnings --werror"
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true -Dvulkan=yes"
|
||||
FEATURE_FLAGS: "-Dcloudproviders=true"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v20"
|
||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v19"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 2
|
||||
|
||||
.only-default:
|
||||
only:
|
||||
@@ -32,89 +27,94 @@ variables:
|
||||
|
||||
style-check-diff:
|
||||
extends: .only-default
|
||||
image: $FEDORA_IMAGE
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/fedora:v16
|
||||
stage: .pre
|
||||
allow_failure: true
|
||||
script:
|
||||
- .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:
|
||||
extends: .build-fedora-default
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/fedora:v16
|
||||
stage: build
|
||||
variables:
|
||||
EXTRA_MESON_FLAGS: "--buildtype=debug --default-library=both"
|
||||
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
|
||||
_build
|
||||
- ninja -C _build
|
||||
- .gitlab-ci/run-tests.sh _build x11
|
||||
- .gitlab-ci/run-tests.sh _build wayland
|
||||
- .gitlab-ci/run-tests.sh _build broadway
|
||||
- .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
|
||||
|
||||
release-build:
|
||||
extends: .build-fedora-default
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/fedora:v16
|
||||
stage: build
|
||||
variables:
|
||||
EXTRA_MESON_FLAGS: "--buildtype=release"
|
||||
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
|
||||
- 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
|
||||
tags:
|
||||
- win32-ps
|
||||
- win32
|
||||
script:
|
||||
- C:\msys64\usr\bin\pacman --noconfirm -Syyuu
|
||||
- C:\msys64\usr\bin\bash -lc "bash -x ./.gitlab-ci/test-msys2.sh"
|
||||
cache:
|
||||
key: "$CI_JOB_NAME"
|
||||
paths:
|
||||
- _ccache/
|
||||
- subprojects/gdk-pixbuf/
|
||||
- subprojects/glib/
|
||||
- subprojects/graphene/
|
||||
- subprojects/libepoxy/
|
||||
- subprojects/pango/
|
||||
key: "%CI_JOB_NAME%"
|
||||
<<: *cache-paths
|
||||
|
||||
msys2-mingw64:
|
||||
extends: .mingw-defaults
|
||||
msys2-mingw32:
|
||||
variables:
|
||||
MSYSTEM: "MINGW64"
|
||||
MSYSTEM: "MINGW32"
|
||||
CHERE_INVOKING: "yes"
|
||||
<<: *mingw-defaults
|
||||
|
||||
.flatpak-defaults:
|
||||
image: $FLATPAK_IMAGE
|
||||
.flatpak-defaults: &flatpak-defaults
|
||||
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master
|
||||
stage: flatpak
|
||||
allow_failure: true
|
||||
tags:
|
||||
@@ -127,48 +127,48 @@ msys2-mingw64:
|
||||
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
|
||||
|
||||
# Manual jobs, for branches and MRs
|
||||
.flatpak-manual:
|
||||
extends: .flatpak-defaults
|
||||
.flatpak-manual: &flatpak-manual
|
||||
<<: *flatpak-defaults
|
||||
when: manual
|
||||
|
||||
# Only build Flatpak bundles automatically on master
|
||||
.flatpak-master:
|
||||
extends: .flatpak-defaults
|
||||
.flatpak-master: &flatpak-master
|
||||
<<: *flatpak-defaults
|
||||
only:
|
||||
- master
|
||||
|
||||
flatpak-manual:demo:
|
||||
extends: .flatpak-manual
|
||||
variables:
|
||||
APPID: org.gtk.Demo4
|
||||
<<: *flatpak-manual
|
||||
|
||||
flatpak-master:demo:
|
||||
extends: .flatpak-master
|
||||
variables:
|
||||
APPID: org.gtk.Demo4
|
||||
<<: *flatpak-master
|
||||
|
||||
flatpak-manual:widget-factory:
|
||||
extends: .flatpak-manual
|
||||
variables:
|
||||
APPID: org.gtk.WidgetFactory4
|
||||
<<: *flatpak-manual
|
||||
|
||||
flatpak-master:widget-factory:
|
||||
extends: .flatpak-master
|
||||
variables:
|
||||
APPID: org.gtk.WidgetFactory4
|
||||
<<: *flatpak-master
|
||||
|
||||
flatpak-manual:icon-browser:
|
||||
extends: .flatpak-manual
|
||||
variables:
|
||||
APPID: org.gtk.IconBrowser4
|
||||
<<: *flatpak-manual
|
||||
|
||||
flatpak-master:icon-browser:
|
||||
extends: .flatpak-master
|
||||
variables:
|
||||
APPID: org.gtk.IconBrowser4
|
||||
<<: *flatpak-master
|
||||
|
||||
static-scan:
|
||||
image: $FEDORA_IMAGE
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/fedora:v16
|
||||
stage: analysis
|
||||
variables:
|
||||
EXTRA_MESON_FLAGS: "--buildtype=debug"
|
||||
@@ -180,24 +180,8 @@ static-scan:
|
||||
- _scan_build/meson-logs
|
||||
allow_failure: true
|
||||
|
||||
# Run tests with the address sanitizer. We need to turn off introspection,
|
||||
# since it is incompatible with asan
|
||||
asan-build:
|
||||
image: $FEDORA_IMAGE
|
||||
tags: [ asan ]
|
||||
stage: analysis
|
||||
variables:
|
||||
script:
|
||||
- CC=clang meson --buildtype=debugoptimized -Db_sanitize=address -Db_lundef=false -Dintrospection=false _build
|
||||
- ninja -C _build
|
||||
- .gitlab-ci/run-tests.sh _build wayland
|
||||
artifacts:
|
||||
paths:
|
||||
- _build/meson-logs
|
||||
allow_failure: true
|
||||
|
||||
reference:
|
||||
image: $DOCS_IMAGE
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/fedora:v16
|
||||
stage: docs
|
||||
variables:
|
||||
EXTRA_MESON_FLAGS: "--buildtype=release"
|
||||
|
@@ -35,13 +35,4 @@ branch, as well as their available versions.
|
||||
- [ ] Add the new job to `.gitlab-ci.yml` referencing the image
|
||||
- [ ] Open a merge request with your changes and let it run
|
||||
|
||||
### Checklist for Adding a new dependency to a CI image
|
||||
|
||||
Our images are layered, and the base (called fedora-base) contains
|
||||
all the rpm payload. Therefore, adding a new dependency is a 2-step
|
||||
process:
|
||||
|
||||
1. [ ] Build and upload fedora-base:$version+1
|
||||
1. [ ] Build and upload fedora:$version+1 based on fedora-base:version+1
|
||||
|
||||
[registry]: https://gitlab.gnome.org/GNOME/gtk/container_registry
|
||||
|
@@ -1,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
|
||||
|
@@ -1,12 +0,0 @@
|
||||
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v19
|
||||
|
||||
RUN dnf -y install pandoc
|
||||
|
||||
ARG HOST_USER_ID=5555
|
||||
ENV HOST_USER_ID ${HOST_USER_ID}
|
||||
RUN useradd -u $HOST_USER_ID -ms /bin/bash user
|
||||
|
||||
USER user
|
||||
WORKDIR /home/user
|
||||
|
||||
ENV LANG C.UTF-8
|
@@ -1,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
|
||||
ENV HOST_USER_ID ${HOST_USER_ID}
|
||||
|
@@ -138,13 +138,12 @@ ul.images li {
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>{{ report.project_name }}/{{ report.backend }}/{{ report.branch_name }} :: Test Reports</h1>
|
||||
<h1>{{ report.project_name }}/{{ report.branch_name }} :: Test Reports</h1>
|
||||
</header>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<div class="report-meta">
|
||||
<p><strong>Backend:</strong> {{ report.backend }}</p>
|
||||
<p><strong>Branch:</strong> {{ report.branch_name }}</p>
|
||||
<p><strong>Date:</strong> <time datetime="{{ report.date.isoformat() }}">{{ report.locale_date }}</time></p>
|
||||
{% if report.job_id %}<p><strong>Job ID:</strong> {{ report.job_id }}</p>{% endif %}
|
||||
@@ -260,9 +259,6 @@ aparser = argparse.ArgumentParser(description='Turns a Meson test log into an HT
|
||||
aparser.add_argument('--project-name', metavar='NAME',
|
||||
help='The project name',
|
||||
default='Unknown')
|
||||
aparser.add_argument('--backend', metavar='NAME',
|
||||
help='The used backend',
|
||||
default='unknown')
|
||||
aparser.add_argument('--job-id', metavar='ID',
|
||||
help='The job ID for the report',
|
||||
default=None)
|
||||
@@ -323,7 +319,6 @@ report = {}
|
||||
report['date'] = datetime.datetime.utcnow()
|
||||
report['locale_date'] = report['date'].strftime("%c")
|
||||
report['project_name'] = args.project_name
|
||||
report['backend'] = args.backend
|
||||
report['job_id'] = args.job_id
|
||||
report['branch_name'] = args.branch
|
||||
report['total_successes'] = 0
|
||||
|
@@ -19,9 +19,6 @@ aparser = argparse.ArgumentParser(description='Turns a Meson test log into a JUn
|
||||
aparser.add_argument('--project-name', metavar='NAME',
|
||||
help='The project name',
|
||||
default='unknown')
|
||||
aparser.add_argument('--backend', metavar='NAME',
|
||||
help='The used backend',
|
||||
default='unknown')
|
||||
aparser.add_argument('--job-id', metavar='ID',
|
||||
help='The job ID for the report',
|
||||
default='Unknown')
|
||||
@@ -95,18 +92,18 @@ for name, units in suites.items():
|
||||
for unit in successes:
|
||||
testcase = ET.SubElement(testsuite, 'testcase')
|
||||
testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
|
||||
testcase.set('name', '{}/{}'.format(args.backend, unit['name']))
|
||||
testcase.set('name', unit['name'])
|
||||
testcase.set('time', str(unit['duration']))
|
||||
|
||||
for unit in failures:
|
||||
testcase = ET.SubElement(testsuite, 'testcase')
|
||||
testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
|
||||
testcase.set('name', '{}/{}'.format(args.backend, unit['name']))
|
||||
testcase.set('name', unit['name'])
|
||||
testcase.set('time', str(unit['duration']))
|
||||
|
||||
failure = ET.SubElement(testcase, 'failure')
|
||||
failure.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
|
||||
testcase.set('name', '{}/{}'.format(args.backend, unit['name']))
|
||||
failure.set('name', unit['name'])
|
||||
failure.set('type', 'error')
|
||||
failure.text = unit['stdout']
|
||||
|
||||
|
@@ -81,7 +81,7 @@ fi
|
||||
|
||||
if [ -z $base_version ]; then
|
||||
base_version="latest"
|
||||
elif [ $base_version != "latest" ]; then
|
||||
else
|
||||
base_version="v$base_version"
|
||||
fi
|
||||
|
||||
@@ -95,7 +95,7 @@ if [ ! -x "$(command -v docker)" ] || [ docker --help |& grep -q podman ]; then
|
||||
else
|
||||
echo "Using: Docker"
|
||||
format=""
|
||||
CMD="sudo docker"
|
||||
CMD="sudo socker"
|
||||
fi
|
||||
|
||||
REGISTRY="registry.gitlab.gnome.org"
|
||||
|
@@ -4,15 +4,8 @@ set -e
|
||||
|
||||
# We need to add a new remote for the upstream master, since this script could
|
||||
# be running in a personal fork of the repository which has out of date branches.
|
||||
if [ "${CI_PROJECT_NAMESPACE}" != "GNOME" ]; then
|
||||
echo "Retrieving the current upstream repository from ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}..."
|
||||
git remote add upstream https://gitlab.gnome.org/GNOME/gtk.git
|
||||
git fetch upstream
|
||||
ORIGIN="upstream"
|
||||
else
|
||||
echo "Reusing the existing repository on ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}"
|
||||
ORIGIN="origin"
|
||||
fi
|
||||
git remote add upstream https://gitlab.gnome.org/GNOME/gtk.git
|
||||
git fetch upstream
|
||||
|
||||
# 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
|
||||
@@ -20,7 +13,7 @@ fi
|
||||
#
|
||||
# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` is only defined if we’re running in
|
||||
# a merge request pipeline; fall back to `${CI_DEFAULT_BRANCH}` otherwise.
|
||||
newest_common_ancestor_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${ORIGIN}/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}") <(git rev-list --first-parent HEAD) | head -1)
|
||||
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
|
||||
exit_status=$?
|
||||
|
||||
|
@@ -5,81 +5,30 @@ set +e
|
||||
|
||||
srcdir=$( pwd )
|
||||
builddir=$1
|
||||
backend=$2
|
||||
|
||||
# Ignore memory leaks lower in dependencies
|
||||
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp
|
||||
|
||||
case "${backend}" in
|
||||
x11)
|
||||
xvfb-run -a -s "-screen 0 1024x768x24" \
|
||||
meson test -C ${builddir} \
|
||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||
export GDK_BACKEND=x11
|
||||
xvfb-run -a -s "-screen 0 1024x768x24" \
|
||||
meson test -C ${builddir} \
|
||||
--print-errorlogs \
|
||||
--setup=${backend} \
|
||||
--suite=gtk \
|
||||
--no-suite=gtk:a11y \
|
||||
--no-suite=gsk-compare-broadway
|
||||
--no-suite=gtk:a11y
|
||||
|
||||
# Store the exit code for the CI run, but always
|
||||
# generate the reports
|
||||
exit_code=$?
|
||||
;;
|
||||
|
||||
wayland)
|
||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||
|
||||
weston --backend=headless-backend.so --socket=wayland-5 --idle-time=0 &
|
||||
compositor=$!
|
||||
export WAYLAND_DISPLAY=wayland-5
|
||||
|
||||
meson test -C ${builddir} \
|
||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend} \
|
||||
--suite=gtk \
|
||||
--no-suite=gtk:a11y \
|
||||
--no-suite=gsk-compare-broadway
|
||||
|
||||
exit_code=$?
|
||||
kill ${compositor}
|
||||
;;
|
||||
|
||||
broadway)
|
||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||
|
||||
${builddir}/gdk/broadway/gtk4-broadwayd :5 &
|
||||
server=$!
|
||||
export BROADWAY_DISPLAY=:5
|
||||
|
||||
meson test -C ${builddir} \
|
||||
--timeout-multiplier "${MESON_TEST_TIMEOUT_MULTIPLIER}" \
|
||||
--print-errorlogs \
|
||||
--setup=${backend} \
|
||||
--suite=gtk \
|
||||
--no-suite=gtk:a11y \
|
||||
--no-suite=gsk-compare-opengl
|
||||
|
||||
# don't let Broadway failures fail the run, for now
|
||||
exit_code=0
|
||||
kill ${server}
|
||||
;;
|
||||
esac
|
||||
# Store the exit code for the CI run, but always
|
||||
# generate the reports
|
||||
exit_code=$?
|
||||
|
||||
cd ${builddir}
|
||||
|
||||
$srcdir/.gitlab-ci/meson-junit-report.py \
|
||||
--project-name=gtk \
|
||||
--backend=${backend} \
|
||||
--job-id="${CI_JOB_NAME}" \
|
||||
--output=report-${backend}.xml \
|
||||
meson-logs/testlog-${backend}.json
|
||||
--output=report.xml \
|
||||
meson-logs/testlog.json
|
||||
$srcdir/.gitlab-ci/meson-html-report.py \
|
||||
--project-name=gtk \
|
||||
--backend=${backend} \
|
||||
--job-id="${CI_JOB_NAME}" \
|
||||
--reftest-output-dir="testsuite/reftests/output/${backend}" \
|
||||
--output=report-${backend}.html \
|
||||
meson-logs/testlog-${backend}.json
|
||||
--reftest-output-dir="testsuite/reftests/output" \
|
||||
--output=report.html \
|
||||
meson-logs/testlog.json
|
||||
|
||||
exit $exit_code
|
||||
|
@@ -34,11 +34,8 @@ pacman --noconfirm -S --needed \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info
|
||||
|
||||
# https://gitlab.gnome.org/GNOME/gtk/issues/2243
|
||||
wget "https://gitlab.gnome.org/creiter/gitlab-ci-win32-runner-v2/raw/master/pango/mingw-w64-$MSYS2_ARCH-pango-git-1.44.7.90.ge48ae523-1-any.pkg.tar.zst"
|
||||
pacman --noconfirm -U "mingw-w64-$MSYS2_ARCH-pango-git-1.44.7.90.ge48ae523-1-any.pkg.tar.zst"
|
||||
|
||||
# https://github.com/msys2/MINGW-packages/pull/6465
|
||||
pacman --noconfirm -S --needed mingw-w64-$MSYS2_ARCH-brotli
|
||||
wget "https://gitlab.gnome.org/creiter/gitlab-ci-win32-runner/raw/master/pango/mingw-w64-$MSYS2_ARCH-pango-1.44.7-1-any.pkg.tar.xz"
|
||||
pacman --noconfirm -U "mingw-w64-$MSYS2_ARCH-pango-1.44.7-1-any.pkg.tar.xz"
|
||||
|
||||
mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
@@ -48,14 +45,11 @@ export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
|
||||
ccache --zero-stats
|
||||
ccache --show-stats
|
||||
export CCACHE_DISABLE=true
|
||||
# FIXME: introspection disabled for now because of
|
||||
# https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/340
|
||||
meson \
|
||||
-Dx11-backend=false \
|
||||
-Dwayland-backend=false \
|
||||
-Dwin32-backend=true \
|
||||
-Dvulkan=no \
|
||||
-Dintrospection=false \
|
||||
--werror \
|
||||
_build
|
||||
unset CCACHE_DISABLE
|
||||
|
@@ -22,7 +22,12 @@ Please, do not use the issue tracker for support questions. If you have
|
||||
questions on how to use GTK effectively, you can use:
|
||||
|
||||
- the `#gtk` IRC channel on irc.gnome.org
|
||||
- the [gtk tag on the GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
|
||||
- the [gtk](https://mail.gnome.org/mailman/listinfo/gtk-list) mailing list,
|
||||
for general questions on GTK
|
||||
- the [gtk-app-devel](https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list)
|
||||
mailing list, for questions on application development with GTK
|
||||
- the [gtk-devel](https://mail.gnome.org/mailman/listinfo/gtk-devel-list)
|
||||
mailing list, for questions on developing GTK itself
|
||||
|
||||
You can also look at the GTK tag on [Stack
|
||||
Overflow](https://stackoverflow.com/questions/tagged/gtk).
|
||||
|
277
NEWS
277
NEWS
@@ -1,258 +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
|
||||
|
||||
* 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
|
||||
|
||||
* 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
|
||||
=================================
|
||||
|
||||
@@ -268,33 +13,15 @@ Overview of Changes in GTK 3.98.3
|
||||
* GtkEmojiChooser:
|
||||
- Improve keyboard navigation
|
||||
|
||||
* GtkLabel:
|
||||
- Remove pattern API
|
||||
|
||||
* GtkAspectFrame:
|
||||
- Modernize and simplify
|
||||
|
||||
* Chooser buttons:
|
||||
- Make dialogs modal by default
|
||||
|
||||
* Various widgets:
|
||||
- Replace shadow-type and relief properties by
|
||||
a simpler has-frame
|
||||
|
||||
* CSS:
|
||||
- Use :focus-visible instead of :focus(visible)
|
||||
- Add support for :focus-within
|
||||
|
||||
* Focus handling
|
||||
- Fix crossing event generation
|
||||
- Fix focus handling in various widgets
|
||||
- Change :can-focus to be recursive
|
||||
- Fix GtkWindow:is-active setting
|
||||
|
||||
* Scrolling
|
||||
- gtk_container_set_focus_[hv]adjustment has been removed
|
||||
- gtk_viewport_set_scroll_to_focus has been added
|
||||
|
||||
* Accessibility:
|
||||
- Add a cursor-aspect-ratio setting
|
||||
- Set focus-related states properly
|
||||
@@ -306,7 +33,6 @@ Overview of Changes in GTK 3.98.3
|
||||
* Wayland:
|
||||
- Fix .Compose file loading
|
||||
- Support popup repositioning
|
||||
- Fix problems with autohide popovers
|
||||
|
||||
* GDK:
|
||||
- Remove GdkKeymap from public API, replaced by
|
||||
@@ -315,13 +41,10 @@ Overview of Changes in GTK 3.98.3
|
||||
- Simplify modifier support, drop GdkModifierIntent
|
||||
- Move key event matching to GDK
|
||||
- Add GdkSurface::enter/leave-monitor signals
|
||||
- Turn GskEvent into a derivable type, and make
|
||||
it introspectable
|
||||
|
||||
* GSK:
|
||||
- Turn GskRenderNode into a derivable type, and make
|
||||
it introspectable
|
||||
- Fall back to cairo if compiling shaders fails
|
||||
|
||||
* Translation updates:
|
||||
- Japanese
|
||||
|
12
README.md
12
README.md
@@ -27,9 +27,9 @@ The official developers blog
|
||||
|
||||
- https://blog.gtk.org
|
||||
|
||||
Discussion forum
|
||||
Information about mailing lists can be found at
|
||||
|
||||
- https://discourse.gnome.org/c/platform/core/
|
||||
- http://www.gtk.org/mailing-lists.php
|
||||
|
||||
Nightly documentation can be found at
|
||||
- Gtk: https://gnome.pages.gitlab.gnome.org/gtk/gtk/
|
||||
@@ -140,12 +140,6 @@ In the bug report please include:
|
||||
* Further information such as stack traces may be useful, but
|
||||
is not necessary.
|
||||
|
||||
Contributing to GTK
|
||||
-------------------
|
||||
|
||||
Please, follow the [contribution guide](./CONTRIBUTING.md) to know how to
|
||||
start contributing to GTK.
|
||||
|
||||
Release notes
|
||||
-------------
|
||||
|
||||
@@ -162,4 +156,4 @@ GTK is released under the terms of the GNU Lesser General Public License,
|
||||
version 2.1 or, at your option, any later version, as published by the Free
|
||||
Software Foundation.
|
||||
|
||||
Please, see the [`COPYING`](./COPYING) file for further information.
|
||||
Please, see the `COPYING` file for further information.
|
||||
|
@@ -1,38 +1,29 @@
|
||||
{
|
||||
"app-id" : "org.gtk.WidgetFactory4",
|
||||
"runtime" : "org.gnome.Platform",
|
||||
"runtime-version" : "master",
|
||||
"sdk" : "org.gnome.Sdk",
|
||||
"command" : "gtk4-widget-factory",
|
||||
"tags" : [
|
||||
"devel",
|
||||
"development",
|
||||
"nightly"
|
||||
],
|
||||
"desktop-file-name-prefix" : "(Development) ",
|
||||
"finish-args" : [
|
||||
"app-id": "org.gtk.WidgetFactory4",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "master",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "gtk4-widget-factory",
|
||||
"tags": ["devel", "development", "nightly"],
|
||||
"desktop-file-name-prefix": "(Development) ",
|
||||
"finish-args": [
|
||||
"--device=dri",
|
||||
"--share=ipc",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=wayland",
|
||||
"--talk-name=org.gtk.vfs",
|
||||
"--talk-name=org.gtk.vfs.*"
|
||||
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*"
|
||||
],
|
||||
"cleanup" : [
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/pkgconfig",
|
||||
"/share/pkgconfig",
|
||||
"/lib/pkgconfig", "/share/pkgconfig",
|
||||
"/share/aclocal",
|
||||
"/man",
|
||||
"/share/man",
|
||||
"/share/gtk-doc",
|
||||
"*.la",
|
||||
".a",
|
||||
"/man", "/share/man", "/share/gtk-doc",
|
||||
"*.la", ".a",
|
||||
"/lib/girepository-1.0",
|
||||
"/share/gir-1.0",
|
||||
"/share/doc"
|
||||
],
|
||||
"modules" : [
|
||||
"modules": [
|
||||
{
|
||||
"name" : "wayland",
|
||||
"buildsystem" : "autotools",
|
||||
@@ -48,18 +39,18 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "graphene",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"name": "graphene",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false",
|
||||
"-Dbenchmarks=false"
|
||||
],
|
||||
"sources" : [
|
||||
"sources": [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/ebassi/graphene.git"
|
||||
"type": "git",
|
||||
"url": "https://github.com/ebassi/graphene.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -67,7 +58,7 @@
|
||||
"name" : "libsass",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
@@ -82,7 +73,7 @@
|
||||
"name" : "sassc",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
@@ -94,23 +85,18 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "gtk",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"name": "gtk",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
"sources": [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
"DBUS_SESSION_BUS_ADDRESS" : "''"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -15,13 +15,7 @@ if 'DESTDIR' not in os.environ:
|
||||
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
|
||||
|
||||
print('Compiling GSettings schemas...')
|
||||
glib_compile_schemas = subprocess.check_output(['pkg-config',
|
||||
'--variable=glib_compile_schemas',
|
||||
'gio-2.0']).strip()
|
||||
if not os.path.exists(glib_compile_schemas):
|
||||
# pkg-config variables only available since GLib 2.62.0.
|
||||
glib_compile_schemas = 'glib-compile-schemas'
|
||||
subprocess.call([glib_compile_schemas,
|
||||
subprocess.call(['glib-compile-schemas',
|
||||
os.path.join(gtk_datadir, 'glib-2.0', 'schemas')])
|
||||
|
||||
print('Updating icon cache...')
|
||||
@@ -30,14 +24,8 @@ if 'DESTDIR' not in os.environ:
|
||||
|
||||
print('Updating module cache for print backends...')
|
||||
os.makedirs(gtk_printmodule_dir, exist_ok=True)
|
||||
gio_querymodules = subprocess.check_output(['pkg-config',
|
||||
'--variable=gio_querymodules',
|
||||
'gio-2.0']).strip()
|
||||
if not os.path.exists(gio_querymodules):
|
||||
# pkg-config variables only available since GLib 2.62.0.
|
||||
gio_querymodules = 'gio-querymodules'
|
||||
subprocess.call([gio_querymodules, gtk_printmodule_dir])
|
||||
subprocess.call(['gio-querymodules', gtk_printmodule_dir])
|
||||
|
||||
print('Updating module cache for input methods...')
|
||||
os.makedirs(gtk_immodule_dir, exist_ok=True)
|
||||
subprocess.call([gio_querymodules, gtk_immodule_dir])
|
||||
subprocess.call(['gio-querymodules', gtk_immodule_dir])
|
||||
|
@@ -27,6 +27,14 @@
|
||||
/* Define to 1 if you have the `dcgettext' function. */
|
||||
#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. */
|
||||
#mesondefine HAVE_DLFCN_H
|
||||
|
||||
@@ -72,6 +80,9 @@
|
||||
/* Define to 1 if you have a working `mmap' system call. */
|
||||
#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. */
|
||||
#mesondefine HAVE_POSIX_FALLOCATE
|
||||
|
||||
@@ -81,9 +92,21 @@
|
||||
/* Have the Xrandr 1.5 extension library */
|
||||
#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. */
|
||||
#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. */
|
||||
#mesondefine HAVE_STDINT_H
|
||||
|
||||
@@ -272,6 +295,3 @@
|
||||
#mesondefine HAVE_PANGOFT
|
||||
|
||||
#mesondefine ISO_CODES_PREFIX
|
||||
|
||||
/* Define if tracker3 is available */
|
||||
#mesondefine HAVE_TRACKER3
|
||||
|
@@ -317,7 +317,7 @@ save_response_cb (GtkNativeDialog *dialog,
|
||||
"Saving failed");
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog),
|
||||
"%s", error->message);
|
||||
g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
|
||||
g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
gtk_widget_show (message_dialog);
|
||||
g_error_free (error);
|
||||
}
|
||||
@@ -403,7 +403,7 @@ constraint_editor_done (ConstraintEditor *editor,
|
||||
|
||||
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
|
||||
@@ -426,7 +426,7 @@ edit_constraint (ConstraintEditorWindow *win,
|
||||
|
||||
editor = constraint_editor_new (model, constraint);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), GTK_WIDGET (editor));
|
||||
gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (editor));
|
||||
|
||||
g_signal_connect (editor, "done", G_CALLBACK (constraint_editor_done), win);
|
||||
|
||||
@@ -444,7 +444,7 @@ guide_editor_done (GuideEditor *editor,
|
||||
GtkConstraintGuide *guide,
|
||||
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
|
||||
@@ -460,7 +460,7 @@ edit_guide (ConstraintEditorWindow *win,
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Edit Guide");
|
||||
|
||||
editor = guide_editor_new (guide);
|
||||
gtk_window_set_child (GTK_WINDOW (window), GTK_WIDGET (editor));
|
||||
gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (editor));
|
||||
|
||||
g_signal_connect (editor, "done", G_CALLBACK (guide_editor_done), win);
|
||||
gtk_widget_show (window);
|
||||
@@ -487,6 +487,8 @@ constraint_editor_window_class_init (ConstraintEditorWindowClass *class)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
g_type_ensure (CONSTRAINT_VIEW_TYPE);
|
||||
|
||||
object_class->finalize = constraint_editor_window_finalize;
|
||||
|
||||
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_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), box);
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
gtk_container_add (GTK_CONTAINER (box), label);
|
||||
|
||||
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);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (row_edit), win);
|
||||
g_object_set_data (G_OBJECT (row), "edit", button);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
|
||||
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
}
|
||||
else if (GTK_IS_WIDGET (item))
|
||||
{
|
||||
button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
|
||||
gtk_button_set_has_frame (GTK_BUTTON (button), FALSE);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
}
|
||||
|
||||
g_free (freeme);
|
||||
|
@@ -9,6 +9,8 @@
|
||||
<property name="default-height">768</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="title" translatable="yes">GTK Constraint Editor</property>
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">document-open-symbolic</property>
|
||||
|
@@ -169,7 +169,6 @@ constraint_view_init (ConstraintView *self)
|
||||
GListModel *guides;
|
||||
GListModel *children;
|
||||
GListModel *constraints;
|
||||
GtkFilter *filter;
|
||||
|
||||
manager = gtk_constraint_layout_new ();
|
||||
gtk_widget_set_layout_manager (GTK_WIDGET (self), manager);
|
||||
@@ -177,18 +176,14 @@ constraint_view_init (ConstraintView *self)
|
||||
all_children = gtk_widget_observe_children (GTK_WIDGET (self));
|
||||
all_constraints = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (manager));
|
||||
guides = gtk_constraint_layout_observe_guides (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);
|
||||
filter = gtk_custom_filter_new (omit_internal, NULL, NULL);
|
||||
children = (GListModel *)gtk_filter_list_model_new (all_children, filter);
|
||||
g_object_unref (filter);
|
||||
constraints = (GListModel *)gtk_filter_list_model_new (all_constraints, omit_internal, NULL, NULL);
|
||||
children = (GListModel *)gtk_filter_list_model_new (all_children, omit_internal, NULL, NULL);
|
||||
|
||||
list = g_list_store_new (G_TYPE_LIST_MODEL);
|
||||
g_list_store_append (list, children);
|
||||
g_list_store_append (list, guides);
|
||||
g_list_store_append (list, constraints);
|
||||
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (list)));
|
||||
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list)));
|
||||
g_object_unref (children);
|
||||
g_object_unref (guides);
|
||||
g_object_unref (constraints);
|
||||
@@ -221,7 +216,7 @@ constraint_view_add_child (ConstraintView *view,
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_add_css_class (frame, "child");
|
||||
gtk_widget_set_name (frame, name);
|
||||
gtk_frame_set_child (GTK_FRAME (frame), label);
|
||||
gtk_container_add (GTK_CONTAINER (frame), label);
|
||||
gtk_widget_set_parent (frame, GTK_WIDGET (view));
|
||||
|
||||
update_weak_position (view, frame, 100, 100);
|
||||
@@ -264,7 +259,7 @@ constraint_view_add_guide (ConstraintView *view,
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_add_css_class (frame, "guide");
|
||||
g_object_set_data (G_OBJECT (frame), "internal", (char *)"yes");
|
||||
gtk_frame_set_child (GTK_FRAME (frame), label);
|
||||
gtk_container_add (GTK_CONTAINER (frame), label);
|
||||
gtk_widget_insert_after (frame, GTK_WIDGET (view), NULL);
|
||||
|
||||
g_object_set_data (G_OBJECT (guide), "frame", frame);
|
||||
|
@@ -23,7 +23,6 @@
|
||||
|
||||
#define CONSTRAINT_VIEW_TYPE (constraint_view_get_type ())
|
||||
|
||||
G_MODULE_EXPORT
|
||||
G_DECLARE_FINAL_TYPE (ConstraintView, constraint_view, CONSTRAINT, VIEW, GtkWidget)
|
||||
|
||||
ConstraintView * constraint_view_new (void);
|
||||
|
@@ -184,6 +184,58 @@ max_input (GtkSpinButton *spin_button,
|
||||
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
|
||||
guide_editor_constructed (GObject *object)
|
||||
{
|
||||
@@ -192,12 +244,16 @@ guide_editor_constructed (GObject *object)
|
||||
guide_strength_combo (editor->strength);
|
||||
|
||||
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, "output", G_CALLBACK (min_output), 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, "output", G_CALLBACK (max_output), NULL);
|
||||
|
||||
if (editor->guide)
|
||||
{
|
||||
|
@@ -47,7 +47,7 @@ show_action_dialog (GSimpleAction *action)
|
||||
name);
|
||||
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (gtk_window_destroy), NULL);
|
||||
G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
}
|
||||
@@ -120,7 +120,7 @@ open_response_cb (GtkNativeDialog *dialog,
|
||||
"Error loading file: \"%s\"",
|
||||
error->message);
|
||||
g_signal_connect (message_dialog, "response",
|
||||
G_CALLBACK (gtk_window_destroy), NULL);
|
||||
G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
gtk_widget_show (message_dialog);
|
||||
g_error_free (error);
|
||||
}
|
||||
@@ -234,7 +234,7 @@ activate_quit (GSimpleAction *action,
|
||||
win = list->data;
|
||||
next = list->next;
|
||||
|
||||
gtk_window_destroy (GTK_WINDOW (win));
|
||||
gtk_widget_destroy (GTK_WIDGET (win));
|
||||
|
||||
list = next;
|
||||
}
|
||||
@@ -328,14 +328,19 @@ static void
|
||||
startup (GApplication *app)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GMenuModel *appmenu;
|
||||
GMenuModel *menubar;
|
||||
|
||||
G_APPLICATION_CLASS (demo_application_parent_class)->startup (app);
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_from_resource (builder, "/application_demo/menus.ui", NULL);
|
||||
|
||||
gtk_application_set_menubar (GTK_APPLICATION (app),
|
||||
G_MENU_MODEL (gtk_builder_get_object (builder, "menubar")));
|
||||
appmenu = (GMenuModel *)gtk_builder_get_object (builder, "appmenu");
|
||||
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);
|
||||
}
|
||||
@@ -348,7 +353,6 @@ create_window (GApplication *app,
|
||||
|
||||
window = (DemoApplicationWindow *)g_object_new (demo_application_window_get_type (),
|
||||
"application", app,
|
||||
"show-menubar", TRUE,
|
||||
NULL);
|
||||
if (content)
|
||||
gtk_text_buffer_set_text (window->buffer, content, -1);
|
||||
@@ -499,13 +503,13 @@ demo_application_window_unrealize (GtkWidget *widget)
|
||||
}
|
||||
|
||||
static void
|
||||
demo_application_window_dispose (GObject *object)
|
||||
demo_application_window_destroy (GtkWidget *widget)
|
||||
{
|
||||
DemoApplicationWindow *window = (DemoApplicationWindow *)object;
|
||||
DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
|
||||
|
||||
demo_application_window_store_state (window);
|
||||
|
||||
G_OBJECT_CLASS (demo_application_window_parent_class)->dispose (object);
|
||||
GTK_WIDGET_CLASS (demo_application_window_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -515,11 +519,11 @@ demo_application_window_class_init (DemoApplicationWindowClass *class)
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->constructed = demo_application_window_constructed;
|
||||
object_class->dispose = demo_application_window_dispose;
|
||||
|
||||
widget_class->size_allocate = demo_application_window_size_allocate;
|
||||
widget_class->realize = demo_application_window_realize;
|
||||
widget_class->unrealize = demo_application_window_unrealize;
|
||||
widget_class->destroy = demo_application_window_destroy;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/application_demo/application.ui");
|
||||
gtk_widget_class_bind_template_child (widget_class, DemoApplicationWindow, message);
|
||||
|
@@ -31,7 +31,12 @@ on_name_vanished (GDBusConnection *connection,
|
||||
if (!name_seen)
|
||||
return;
|
||||
|
||||
g_clear_object (&placeholder);
|
||||
if (placeholder)
|
||||
{
|
||||
gtk_widget_destroy (placeholder);
|
||||
g_object_unref (placeholder);
|
||||
placeholder = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
|
18
demos/gtk-demo/appmenu.ui
Normal file
18
demos/gtk-demo/appmenu.ui
Normal 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"><Control>q</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
@@ -26,7 +26,7 @@ apply_changes_gradually (gpointer data)
|
||||
else
|
||||
{
|
||||
/* Close automatically once changes are fully applied. */
|
||||
gtk_window_destroy (GTK_WINDOW (data));
|
||||
gtk_widget_destroy (data);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ on_assistant_apply (GtkWidget *widget, gpointer data)
|
||||
static void
|
||||
on_assistant_close_cancel (GtkWidget *widget, gpointer data)
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (widget));
|
||||
gtk_widget_destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -95,12 +95,12 @@ create_page1 (GtkWidget *assistant)
|
||||
gtk_widget_set_margin_bottom (box, 12);
|
||||
|
||||
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 ();
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
||||
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_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 "
|
||||
"even if you do not check this");
|
||||
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_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_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_page2 (assistant);
|
||||
@@ -198,7 +199,7 @@ do_assistant (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (assistant))
|
||||
gtk_widget_show (assistant);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (assistant));
|
||||
gtk_widget_destroy (assistant);
|
||||
|
||||
return assistant;
|
||||
}
|
||||
|
@@ -39,7 +39,7 @@ enum {
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
static GQuark child_data_quark = 0;
|
||||
|
||||
G_DEFINE_TYPE (BlurOverlay, blur_overlay, GTK_TYPE_WIDGET)
|
||||
G_DEFINE_TYPE (BlurOverlay, blur_overlay, GTK_TYPE_BIN)
|
||||
|
||||
static void
|
||||
blur_overlay_set_overlay_child (GtkWidget *widget,
|
||||
@@ -204,7 +204,7 @@ blur_overlay_size_allocate (GtkWidget *widget,
|
||||
GtkWidget *child;
|
||||
GtkWidget *main_widget;
|
||||
|
||||
main_widget = overlay->main_widget;
|
||||
main_widget = gtk_bin_get_child (GTK_BIN (overlay));
|
||||
if (main_widget && gtk_widget_get_visible (main_widget))
|
||||
gtk_widget_size_allocate (main_widget,
|
||||
&(GtkAllocation) {
|
||||
@@ -290,6 +290,43 @@ blur_overlay_get_child_position (BlurOverlay *overlay,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_add (GtkContainer *container,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
BlurOverlay *overlay = BLUR_OVERLAY (container);
|
||||
gtk_widget_insert_after (widget, GTK_WIDGET (container), NULL);
|
||||
overlay->main_widget = widget;
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_remove (GtkContainer *container,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
BlurOverlay *overlay = BLUR_OVERLAY (container);
|
||||
gtk_widget_unparent (widget);
|
||||
if (overlay->main_widget == widget)
|
||||
overlay->main_widget = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_forall (GtkContainer *overlay,
|
||||
GtkCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
child = gtk_widget_get_first_child (GTK_WIDGET (overlay));
|
||||
while (child != NULL)
|
||||
{
|
||||
GtkWidget *next = gtk_widget_get_next_sibling (child);
|
||||
|
||||
(* callback) (child, callback_data);
|
||||
|
||||
child = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
@@ -383,32 +420,21 @@ blur_overlay_snapshot (GtkWidget *widget,
|
||||
gsk_render_node_unref (main_widget_node);
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_dispose (GObject *object)
|
||||
{
|
||||
BlurOverlay *overlay = BLUR_OVERLAY (object);
|
||||
GtkWidget *child;
|
||||
|
||||
g_clear_pointer (&overlay->main_widget, gtk_widget_unparent);
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (overlay))))
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
G_OBJECT_CLASS (blur_overlay_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_class_init (BlurOverlayClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = blur_overlay_dispose;
|
||||
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
|
||||
|
||||
widget_class->measure = blur_overlay_measure;
|
||||
widget_class->size_allocate = blur_overlay_size_allocate;
|
||||
widget_class->snapshot = blur_overlay_snapshot;
|
||||
|
||||
container_class->add = blur_overlay_add;
|
||||
container_class->remove = blur_overlay_remove;
|
||||
container_class->forall = blur_overlay_forall;
|
||||
|
||||
klass->get_child_position = blur_overlay_get_child_position;
|
||||
|
||||
signals[GET_CHILD_POSITION] =
|
||||
@@ -451,11 +477,3 @@ blur_overlay_add_overlay (BlurOverlay *overlay,
|
||||
|
||||
blur_overlay_set_overlay_child (widget, child);
|
||||
}
|
||||
|
||||
void
|
||||
blur_overlay_set_child (BlurOverlay *overlay,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
gtk_widget_insert_after (widget, GTK_WIDGET (overlay), NULL);
|
||||
overlay->main_widget = widget;
|
||||
}
|
||||
|
@@ -37,14 +37,14 @@ typedef struct _BlurOverlayClass BlurOverlayClass;
|
||||
|
||||
struct _BlurOverlay
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
GtkBin parent_instance;
|
||||
|
||||
GtkWidget *main_widget;
|
||||
};
|
||||
|
||||
struct _BlurOverlayClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
GtkBinClass parent_class;
|
||||
|
||||
gboolean (*get_child_position) (BlurOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
@@ -59,9 +59,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
void blur_overlay_add_overlay (BlurOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
double blur);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void blur_overlay_set_child (BlurOverlay *overlay,
|
||||
GtkWidget *widget);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -12,7 +12,7 @@ quit_activate (GSimpleAction *action,
|
||||
{
|
||||
GtkWidget *window = user_data;
|
||||
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -26,10 +26,8 @@ about_activate (GSimpleAction *action,
|
||||
|
||||
builder = g_object_get_data (G_OBJECT (window), "builder");
|
||||
about_dlg = GTK_WIDGET (gtk_builder_get_object (builder, "aboutdialog1"));
|
||||
gtk_window_set_transient_for (GTK_WINDOW (about_dlg), GTK_WINDOW (window));
|
||||
gtk_window_set_hide_on_close (GTK_WINDOW (about_dlg), TRUE);
|
||||
g_signal_connect (about_dlg, "response", G_CALLBACK (gtk_widget_hide), NULL);
|
||||
gtk_widget_show (about_dlg);
|
||||
gtk_dialog_run (GTK_DIALOG (about_dlg));
|
||||
gtk_widget_hide (about_dlg);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -76,20 +74,21 @@ do_builder (GtkWidget *do_widget)
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
actions = (GActionGroup*)g_simple_action_group_new ();
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions),
|
||||
win_entries, G_N_ELEMENTS (win_entries),
|
||||
window);
|
||||
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))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -12,7 +12,6 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
#include "demoimage.h"
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
@@ -69,7 +68,7 @@ paste_received (GObject *source_object,
|
||||
"Could not paste text: %s",
|
||||
error->message);
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (gtk_window_destroy), NULL);
|
||||
G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
gtk_widget_show (dialog);
|
||||
|
||||
g_error_free (error);
|
||||
@@ -94,6 +93,147 @@ paste_button_clicked (GtkWidget *button,
|
||||
gdk_clipboard_read_text_async (clipboard, NULL, paste_received, entry);
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
get_image_paintable (GtkImage *image)
|
||||
{
|
||||
const gchar *icon_name;
|
||||
GtkIconTheme *icon_theme;
|
||||
GtkIconPaintable *icon;
|
||||
|
||||
switch (gtk_image_get_storage_type (image))
|
||||
{
|
||||
case GTK_IMAGE_PAINTABLE:
|
||||
return g_object_ref (gtk_image_get_paintable (image));
|
||||
case GTK_IMAGE_ICON_NAME:
|
||||
icon_name = gtk_image_get_icon_name (image);
|
||||
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image)));
|
||||
icon = gtk_icon_theme_lookup_icon (icon_theme,
|
||||
icon_name,
|
||||
NULL,
|
||||
48, 1,
|
||||
gtk_widget_get_direction (GTK_WIDGET (image)),
|
||||
0);
|
||||
if (icon == NULL)
|
||||
return NULL;
|
||||
return GDK_PAINTABLE (icon);
|
||||
|
||||
case GTK_IMAGE_EMPTY:
|
||||
case GTK_IMAGE_GICON:
|
||||
default:
|
||||
g_warning ("Image storage type %d not handled",
|
||||
gtk_image_get_storage_type (image));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin (GtkDragSource *source,
|
||||
GdkDrag *drag,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
|
||||
paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
if (paintable)
|
||||
{
|
||||
gtk_drag_source_set_icon (source, paintable, -2, -2);
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
prepare_drag (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *image)
|
||||
{
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (image));
|
||||
|
||||
if (!GDK_IS_TEXTURE (paintable))
|
||||
return NULL;
|
||||
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, paintable);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drag_drop (GtkDropTarget *dest,
|
||||
const GValue *value,
|
||||
double x,
|
||||
double y,
|
||||
GtkImage *image)
|
||||
{
|
||||
GdkTexture *texture = g_value_get_object (value);
|
||||
gtk_image_set_from_paintable (GTK_IMAGE (image), GDK_PAINTABLE (texture));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_image (GSimpleAction *action,
|
||||
GVariant *value,
|
||||
gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (data));
|
||||
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
gdk_clipboard_set_texture (clipboard, GDK_TEXTURE (paintable));
|
||||
|
||||
if (paintable)
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
|
||||
static void
|
||||
paste_image_received (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
|
||||
texture = gdk_clipboard_read_texture_finish (GDK_CLIPBOARD (source), result, NULL);
|
||||
if (texture == NULL)
|
||||
return;
|
||||
|
||||
gtk_image_set_from_paintable (GTK_IMAGE (data), GDK_PAINTABLE (texture));
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
static void
|
||||
paste_image (GSimpleAction *action,
|
||||
GVariant *value,
|
||||
gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||
gdk_clipboard_read_texture_async (clipboard, NULL, paste_image_received, data);
|
||||
}
|
||||
|
||||
static void
|
||||
pressed_cb (GtkGesture *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *image)
|
||||
{
|
||||
GtkWidget *popover;
|
||||
GMenu *menu;
|
||||
GMenuItem *item;
|
||||
|
||||
menu = g_menu_new ();
|
||||
item = g_menu_item_new (_("_Copy"), "clipboard.copy");
|
||||
g_menu_append_item (menu, item);
|
||||
|
||||
item = g_menu_item_new (_("_Paste"), "clipboard.paste");
|
||||
g_menu_append_item (menu, item);
|
||||
|
||||
popover = gtk_popover_menu_new_from_model (G_MENU_MODEL (menu));
|
||||
gtk_widget_set_parent (popover, image);
|
||||
|
||||
gtk_popover_set_pointing_to (GTK_POPOVER (popover), &(GdkRectangle) { x, y, 1, 1});
|
||||
gtk_popover_popup (GTK_POPOVER (popover));
|
||||
|
||||
g_object_unref (menu);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_clipboard (GtkWidget *do_widget)
|
||||
{
|
||||
@@ -103,12 +243,22 @@ do_clipboard (GtkWidget *do_widget)
|
||||
GtkWidget *label;
|
||||
GtkWidget *entry, *button;
|
||||
GtkWidget *image;
|
||||
GtkGesture *gesture;
|
||||
GActionEntry entries[] = {
|
||||
{ "copy", copy_image, NULL, NULL, NULL },
|
||||
{ "paste", paste_image, NULL, NULL, NULL },
|
||||
};
|
||||
GActionGroup *actions;
|
||||
GtkDragSource *source;
|
||||
GtkDropTarget *dest;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
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);
|
||||
gtk_widget_set_margin_start (vbox, 8);
|
||||
@@ -116,76 +266,122 @@ do_clipboard (GtkWidget *do_widget)
|
||||
gtk_widget_set_margin_top (vbox, 8);
|
||||
gtk_widget_set_margin_bottom (vbox, 8);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
label = gtk_label_new ("\"Copy\" will copy the text\nin the entry to the clipboard");
|
||||
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
gtk_widget_set_margin_start (hbox, 8);
|
||||
gtk_widget_set_margin_end (hbox, 8);
|
||||
gtk_widget_set_margin_top (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 */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_box_append (GTK_BOX (hbox), entry);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), entry);
|
||||
|
||||
/* Create the button */
|
||||
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_CALLBACK (copy_button_clicked), 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);
|
||||
gtk_widget_set_margin_start (hbox, 8);
|
||||
gtk_widget_set_margin_end (hbox, 8);
|
||||
gtk_widget_set_margin_top (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 */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_box_append (GTK_BOX (hbox), entry);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), entry);
|
||||
|
||||
/* Create the button */
|
||||
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_CALLBACK (paste_button_clicked), entry);
|
||||
|
||||
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);
|
||||
gtk_widget_set_margin_start (hbox, 8);
|
||||
gtk_widget_set_margin_end (hbox, 8);
|
||||
gtk_widget_set_margin_top (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 */
|
||||
image = demo_image_new ("dialog-warning");
|
||||
gtk_box_append (GTK_BOX (hbox), image);
|
||||
image = gtk_image_new_from_icon_name ("dialog-warning");
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), 48);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), image);
|
||||
|
||||
/* make image a drag source */
|
||||
source = gtk_drag_source_new ();
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (prepare_drag), NULL);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
/* accept drops on image */
|
||||
dest = gtk_drop_target_new (GDK_TYPE_TEXTURE, GDK_ACTION_COPY);
|
||||
g_signal_connect (dest, "drop", G_CALLBACK (drag_drop), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (dest));
|
||||
|
||||
/* context menu on image */
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), image);
|
||||
|
||||
gtk_widget_insert_action_group (image, "clipboard", actions);
|
||||
|
||||
g_object_unref (actions);
|
||||
|
||||
/* Create the second image */
|
||||
image = demo_image_new ("process-stop");
|
||||
gtk_box_append (GTK_BOX (hbox), image);
|
||||
image = gtk_image_new_from_icon_name ("process-stop");
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), 48);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), image);
|
||||
|
||||
/* Create the third image */
|
||||
image = demo_image_new ("weather-clear");
|
||||
gtk_box_append (GTK_BOX (hbox), image);
|
||||
/* make image a drag source */
|
||||
source = gtk_drag_source_new ();
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (prepare_drag), NULL);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
/* accept drops on image */
|
||||
dest = gtk_drop_target_new (GDK_TYPE_TEXTURE, GDK_ACTION_COPY);
|
||||
g_signal_connect (dest, "drop", G_CALLBACK (drag_drop), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (dest));
|
||||
|
||||
/* context menu on image */
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), image);
|
||||
|
||||
gtk_widget_insert_action_group (image, "clipboard", actions);
|
||||
|
||||
g_object_unref (actions);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
118
demos/gtk-demo/colorsel.c
Normal file
118
demos/gtk-demo/colorsel.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/* Color Chooser
|
||||
*
|
||||
* A GtkColorChooser lets the user choose a color. There are several
|
||||
* implementations of the GtkColorChooser interface in GTK. The
|
||||
* GtkColorChooserDialog is a prebuilt dialog containing a
|
||||
* GtkColorChooserWidget.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkWidget *da;
|
||||
static GdkRGBA color;
|
||||
static GtkWidget *frame;
|
||||
|
||||
/* draw callback for the drawing area
|
||||
*/
|
||||
static void
|
||||
draw_function (GtkDrawingArea *drawing_area,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data)
|
||||
{
|
||||
gdk_cairo_set_source_rgba (cr, &color);
|
||||
cairo_paint (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
response_cb (GtkDialog *dialog,
|
||||
gint response_id,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (response_id == GTK_RESPONSE_OK)
|
||||
{
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (dialog), &color);
|
||||
gtk_widget_queue_draw (da);
|
||||
}
|
||||
|
||||
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
change_color_callback (GtkWidget *button,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_color_chooser_dialog_new ("Changing color", GTK_WINDOW (window));
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (dialog), &color);
|
||||
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (response_cb), NULL);
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_colorsel (GtkWidget *do_widget)
|
||||
{
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *button;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
color.red = 0;
|
||||
color.blue = 1;
|
||||
color.green = 0;
|
||||
color.alpha = 1;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Color Chooser");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
|
||||
gtk_widget_set_margin_start (vbox, 12);
|
||||
gtk_widget_set_margin_end (vbox, 12);
|
||||
gtk_widget_set_margin_top (vbox, 12);
|
||||
gtk_widget_set_margin_bottom (vbox, 12);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
/*
|
||||
* Create the color swatch area
|
||||
*/
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
|
||||
da = gtk_drawing_area_new ();
|
||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 200);
|
||||
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 200);
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), draw_function, NULL, NULL);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (frame), da);
|
||||
|
||||
button = gtk_button_new_with_mnemonic ("_Change the above color");
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox), button);
|
||||
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (change_color_callback), NULL);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
@@ -315,32 +315,34 @@ do_combobox (GtkWidget *do_widget)
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
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);
|
||||
gtk_widget_set_margin_start (vbox, 10);
|
||||
gtk_widget_set_margin_end (vbox, 10);
|
||||
gtk_widget_set_margin_top (vbox, 10);
|
||||
gtk_widget_set_margin_bottom (vbox, 10);
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
/* A combobox demonstrating cell renderers, separators and
|
||||
* insensitive rows
|
||||
*/
|
||||
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);
|
||||
gtk_widget_set_margin_start (box, 5);
|
||||
gtk_widget_set_margin_end (box, 5);
|
||||
gtk_widget_set_margin_top (box, 5);
|
||||
gtk_widget_set_margin_bottom (box, 5);
|
||||
gtk_frame_set_child (GTK_FRAME (frame), box);
|
||||
gtk_container_add (GTK_CONTAINER (frame), box);
|
||||
|
||||
model = create_icon_store ();
|
||||
combo = gtk_combo_box_new_with_model (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 ();
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
|
||||
@@ -372,19 +374,19 @@ do_combobox (GtkWidget *do_widget)
|
||||
/* A combobox demonstrating trees.
|
||||
*/
|
||||
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);
|
||||
gtk_widget_set_margin_start (box, 5);
|
||||
gtk_widget_set_margin_end (box, 5);
|
||||
gtk_widget_set_margin_top (box, 5);
|
||||
gtk_widget_set_margin_bottom (box, 5);
|
||||
gtk_frame_set_child (GTK_FRAME (frame), box);
|
||||
gtk_container_add (GTK_CONTAINER (frame), box);
|
||||
|
||||
model = create_capital_store ();
|
||||
combo = gtk_combo_box_new_with_model (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 ();
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
|
||||
@@ -403,52 +405,53 @@ do_combobox (GtkWidget *do_widget)
|
||||
|
||||
/* A GtkComboBoxEntry with validation */
|
||||
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);
|
||||
gtk_widget_set_margin_start (box, 5);
|
||||
gtk_widget_set_margin_end (box, 5);
|
||||
gtk_widget_set_margin_top (box, 5);
|
||||
gtk_widget_set_margin_bottom (box, 5);
|
||||
gtk_frame_set_child (GTK_FRAME (frame), box);
|
||||
gtk_container_add (GTK_CONTAINER (frame), box);
|
||||
|
||||
combo = gtk_combo_box_text_new_with_entry ();
|
||||
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);
|
||||
MASK_ENTRY (entry)->mask = "^([0-9]*|One|Two|2\302\275|Three)$";
|
||||
|
||||
gtk_combo_box_set_child (GTK_COMBO_BOX (combo), entry);
|
||||
gtk_container_remove (GTK_CONTAINER (combo), gtk_bin_get_child (GTK_BIN (combo)));
|
||||
gtk_container_add (GTK_CONTAINER (combo), entry);
|
||||
|
||||
/* A combobox with string IDs */
|
||||
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);
|
||||
gtk_widget_set_margin_start (box, 5);
|
||||
gtk_widget_set_margin_end (box, 5);
|
||||
gtk_widget_set_margin_top (box, 5);
|
||||
gtk_widget_set_margin_bottom (box, 5);
|
||||
gtk_frame_set_child (GTK_FRAME (frame), box);
|
||||
gtk_container_add (GTK_CONTAINER (frame), box);
|
||||
|
||||
combo = gtk_combo_box_text_new ();
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "never", "Not visible");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "when-active", "Visible when active");
|
||||
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 ();
|
||||
g_object_bind_property (combo, "active-id",
|
||||
entry, "text",
|
||||
G_BINDING_BIDIRECTIONAL);
|
||||
gtk_box_append (GTK_BOX (box), entry);
|
||||
gtk_container_add (GTK_CONTAINER (box), entry);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -21,24 +21,23 @@ struct _SimpleGrid
|
||||
G_DEFINE_TYPE (SimpleGrid, simple_grid, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
simple_grid_dispose (GObject *object)
|
||||
simple_grid_destroy (GtkWidget *widget)
|
||||
{
|
||||
SimpleGrid *self = SIMPLE_GRID (object);
|
||||
SimpleGrid *self = SIMPLE_GRID (widget);
|
||||
|
||||
g_clear_pointer (&self->button1, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->button2, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->button3, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->button1, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button2, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button3, gtk_widget_destroy);
|
||||
|
||||
G_OBJECT_CLASS (simple_grid_parent_class)->dispose (object);
|
||||
GTK_WIDGET_CLASS (simple_grid_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
simple_grid_class_init (SimpleGridClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = simple_grid_dispose;
|
||||
widget_class->destroy = simple_grid_destroy;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
||||
}
|
||||
@@ -258,32 +257,33 @@ do_constraints (GtkWidget *do_widget)
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
grid = g_object_new (simple_grid_get_type (), NULL);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
gtk_widget_set_vexpand (grid, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), grid);
|
||||
gtk_container_add (GTK_CONTAINER (box), grid);
|
||||
|
||||
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);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gtk_window_destroy), window);
|
||||
G_CALLBACK (gtk_widget_destroy), window);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/* Constraints/Interactive
|
||||
*
|
||||
* Demonstrate how constraints can be updates during user interaction.
|
||||
* The vertical edge between the buttons can be dragged with the mouse.
|
||||
* Demonstrate how constraints can be updates during
|
||||
* user interaction.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
@@ -22,24 +22,23 @@ struct _InteractiveGrid
|
||||
G_DEFINE_TYPE (InteractiveGrid, interactive_grid, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
interactive_grid_dispose (GObject *object)
|
||||
interactive_grid_destroy (GtkWidget *widget)
|
||||
{
|
||||
InteractiveGrid *self = INTERACTIVE_GRID (object);
|
||||
InteractiveGrid *self = INTERACTIVE_GRID (widget);
|
||||
|
||||
g_clear_pointer (&self->button1, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->button2, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->button3, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->button1, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button2, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button3, gtk_widget_destroy);
|
||||
|
||||
G_OBJECT_CLASS (interactive_grid_parent_class)->dispose (object);
|
||||
GTK_WIDGET_CLASS (interactive_grid_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
interactive_grid_class_init (InteractiveGridClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = interactive_grid_dispose;
|
||||
widget_class->destroy = interactive_grid_destroy;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
||||
}
|
||||
@@ -214,32 +213,33 @@ do_constraints2 (GtkWidget *do_widget)
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
grid = g_object_new (interactive_grid_get_type (), NULL);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
gtk_widget_set_vexpand (grid, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), grid);
|
||||
gtk_container_add (GTK_CONTAINER (box), grid);
|
||||
|
||||
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);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gtk_window_destroy), window);
|
||||
G_CALLBACK (gtk_widget_destroy), window);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -20,24 +20,23 @@ struct _VflGrid
|
||||
G_DEFINE_TYPE (VflGrid, vfl_grid, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
vfl_grid_dispose (GObject *object)
|
||||
vfl_grid_destroy (GtkWidget *widget)
|
||||
{
|
||||
VflGrid *self = VFL_GRID (object);
|
||||
VflGrid *self = VFL_GRID (widget);
|
||||
|
||||
g_clear_pointer (&self->button1, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->button2, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->button3, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->button1, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button2, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button3, gtk_widget_destroy);
|
||||
|
||||
G_OBJECT_CLASS (vfl_grid_parent_class)->dispose (object);
|
||||
GTK_WIDGET_CLASS (vfl_grid_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
vfl_grid_class_init (VflGridClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = vfl_grid_dispose;
|
||||
widget_class->destroy = vfl_grid_destroy;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
||||
}
|
||||
@@ -134,32 +133,33 @@ do_constraints3 (GtkWidget *do_widget)
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
grid = g_object_new (vfl_grid_get_type (), NULL);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
gtk_widget_set_vexpand (grid, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), grid);
|
||||
gtk_container_add (GTK_CONTAINER (box), grid);
|
||||
|
||||
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);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gtk_window_destroy), window);
|
||||
G_CALLBACK (gtk_widget_destroy), window);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -9,13 +9,9 @@
|
||||
static void
|
||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
apply_css (child, provider);
|
||||
if (GTK_IS_CONTAINER (widget))
|
||||
gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback) apply_css, provider);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -32,30 +28,31 @@ do_css_accordion (GtkWidget *do_widget)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "CSS Accordion");
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||
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);
|
||||
gtk_widget_set_halign (container, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (container, GTK_ALIGN_CENTER);
|
||||
gtk_window_set_child (GTK_WINDOW (window), container);
|
||||
gtk_container_add (GTK_CONTAINER (window), container);
|
||||
|
||||
child = gtk_button_new_with_label ("This");
|
||||
gtk_box_append (GTK_BOX (container), child);
|
||||
gtk_container_add (GTK_CONTAINER (container), child);
|
||||
|
||||
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");
|
||||
gtk_box_append (GTK_BOX (container), child);
|
||||
gtk_container_add (GTK_CONTAINER (container), child);
|
||||
|
||||
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");
|
||||
gtk_box_append (GTK_BOX (container), child);
|
||||
gtk_container_add (GTK_CONTAINER (container), child);
|
||||
|
||||
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 ());
|
||||
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))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -55,13 +55,9 @@ css_text_changed (GtkTextBuffer *buffer,
|
||||
static void
|
||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
apply_css (child, provider);
|
||||
if (GTK_IS_CONTAINER (widget))
|
||||
gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback) apply_css, provider);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -80,7 +76,8 @@ do_css_basics (GtkWidget *do_widget)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "CSS Basics");
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||
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);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
@@ -94,10 +91,10 @@ do_css_basics (GtkWidget *do_widget)
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
container = gtk_scrolled_window_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), container);
|
||||
container = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), container);
|
||||
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_CALLBACK (css_text_changed), provider);
|
||||
|
||||
@@ -116,7 +113,7 @@ do_css_basics (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@ setup_listbox (GtkBuilder *builder,
|
||||
|
||||
normal_row = NULL;
|
||||
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);
|
||||
|
||||
@@ -95,8 +95,9 @@ setup_listbox (GtkBuilder *builder,
|
||||
"xalign", 0.0,
|
||||
NULL);
|
||||
|
||||
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), label);
|
||||
gtk_list_box_insert (GTK_LIST_BOX (listbox), row, -1);
|
||||
gtk_container_add (GTK_CONTAINER (row), label);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (listbox), row);
|
||||
|
||||
/* The first selected row is "normal" */
|
||||
if (g_strcmp0 (blend_modes[i].id, "normal") == 0)
|
||||
@@ -124,7 +125,7 @@ do_css_blendmodes (GtkWidget *do_widget)
|
||||
|
||||
window = WID ("window");
|
||||
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 */
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
@@ -134,14 +135,12 @@ do_css_blendmodes (GtkWidget *do_widget)
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
setup_listbox (builder, provider);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -69,13 +69,9 @@ drawing_area_draw (GtkDrawingArea *da,
|
||||
static void
|
||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
apply_css (child, provider);
|
||||
if (GTK_IS_CONTAINER (widget))
|
||||
gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback) apply_css, provider);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -85,7 +81,7 @@ do_css_multiplebgs (GtkWidget *do_widget)
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *paned, *overlay, *child, *sw;
|
||||
GtkWidget *paned, *container, *child;
|
||||
GtkStyleProvider *provider;
|
||||
GtkTextBuffer *text;
|
||||
GBytes *bytes;
|
||||
@@ -94,31 +90,32 @@ do_css_multiplebgs (GtkWidget *do_widget)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Multiple Backgrounds");
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||
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 ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), overlay);
|
||||
container = gtk_overlay_new ();
|
||||
gtk_container_add (GTK_CONTAINER (window), container);
|
||||
|
||||
child = gtk_drawing_area_new ();
|
||||
gtk_widget_set_name (child, "canvas");
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (child),
|
||||
drawing_area_draw,
|
||||
NULL, NULL);
|
||||
gtk_overlay_set_child (GTK_OVERLAY (overlay), child);
|
||||
gtk_container_add (GTK_CONTAINER (container), child);
|
||||
|
||||
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_halign (child, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (child, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_size_request (child, 250, 84);
|
||||
|
||||
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 */
|
||||
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);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
@@ -132,10 +129,10 @@ do_css_multiplebgs (GtkWidget *do_widget)
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_paned_set_end_child (GTK_PANED (paned), sw);
|
||||
container = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (paned), container);
|
||||
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,
|
||||
"changed",
|
||||
G_CALLBACK (css_text_changed),
|
||||
@@ -156,7 +153,7 @@ do_css_multiplebgs (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -55,13 +55,9 @@ css_text_changed (GtkTextBuffer *buffer,
|
||||
static void
|
||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
apply_css (child, provider);
|
||||
if (GTK_IS_CONTAINER (widget))
|
||||
gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback) apply_css, provider);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -80,14 +76,15 @@ do_css_pixbufs (GtkWidget *do_widget)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Animated Backgrounds");
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||
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);
|
||||
gtk_window_set_child (GTK_WINDOW (window), paned);
|
||||
gtk_container_add (GTK_CONTAINER (window), paned);
|
||||
|
||||
/* Need a filler so we get a handle */
|
||||
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);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
@@ -101,10 +98,10 @@ do_css_pixbufs (GtkWidget *do_widget)
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
container = gtk_scrolled_window_new ();
|
||||
gtk_paned_set_end_child (GTK_PANED (paned), container);
|
||||
container = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (paned), container);
|
||||
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_CALLBACK (css_text_changed), provider);
|
||||
|
||||
@@ -123,7 +120,7 @@ do_css_pixbufs (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -53,13 +53,9 @@ css_text_changed (GtkTextBuffer *buffer,
|
||||
static void
|
||||
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
apply_css (child, provider);
|
||||
if (GTK_IS_CONTAINER (widget))
|
||||
gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback) apply_css, provider);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
@@ -72,13 +68,13 @@ create_toolbar (void)
|
||||
gtk_widget_set_valign (toolbar, GTK_ALIGN_CENTER);
|
||||
|
||||
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");
|
||||
gtk_box_append (GTK_BOX (toolbar), item);
|
||||
gtk_container_add (GTK_CONTAINER (toolbar), item);
|
||||
|
||||
item = gtk_button_new_with_label ("Hello World");
|
||||
gtk_box_append (GTK_BOX (toolbar), item);
|
||||
gtk_container_add (GTK_CONTAINER (toolbar), item);
|
||||
|
||||
return toolbar;
|
||||
}
|
||||
@@ -99,13 +95,14 @@ do_css_shadows (GtkWidget *do_widget)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Shadows");
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
|
||||
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);
|
||||
gtk_window_set_child (GTK_WINDOW (window), paned);
|
||||
gtk_container_add (GTK_CONTAINER (window), paned);
|
||||
|
||||
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);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
@@ -119,10 +116,10 @@ do_css_shadows (GtkWidget *do_widget)
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
container = gtk_scrolled_window_new ();
|
||||
gtk_paned_set_end_child (GTK_PANED (paned), container);
|
||||
container = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (paned), container);
|
||||
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_CALLBACK (css_text_changed), provider);
|
||||
|
||||
@@ -141,7 +138,7 @@ do_css_shadows (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -1,8 +1,9 @@
|
||||
/* Cursors
|
||||
*
|
||||
* Demonstrates a useful set of available cursors. The cursors shown here are the
|
||||
* ones defined by CSS, which we assume to be available. The example shows creating
|
||||
* cursors by name or from an image, with or without a fallback.
|
||||
* Demonstrates a useful set of available cursors. The cursors shown here are the ones
|
||||
* defined by CSS, which we assume to be available.
|
||||
*
|
||||
* The example shows creating cursors by name or from an image, with or without a fallback.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
@@ -28,14 +29,14 @@ do_cursors (GtkWidget *do_widget)
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_signal_connect (window, "destroy",
|
||||
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))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
}
|
||||
|
||||
return window;
|
||||
|
@@ -1,10 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/">
|
||||
</gresource>
|
||||
<gresource prefix="/ui">
|
||||
<file preprocess="xml-stripblanks">main.ui</file>
|
||||
<file preprocess="xml-stripblanks">main-listitem.ui</file>
|
||||
<file preprocess="xml-stripblanks">appmenu.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/application_demo">
|
||||
<file>application.c</file>
|
||||
@@ -14,10 +12,6 @@
|
||||
<gresource prefix="/builder">
|
||||
<file>demo.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/clipboard">
|
||||
<file>demoimage.c</file>
|
||||
<file>demoimage.h</file>
|
||||
</gresource>
|
||||
<gresource prefix="/css_accordion">
|
||||
<file>css_accordion.css</file>
|
||||
<file>reset.css</file>
|
||||
@@ -105,9 +99,6 @@
|
||||
<file>zoom_in_cursor.png</file>
|
||||
<file>zoom_out_cursor.png</file>
|
||||
</gresource>
|
||||
<gresource prefix="/dnd">
|
||||
<file>dnd.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/fishbowl">
|
||||
<file>fishbowl.ui</file>
|
||||
<file>gtkfishbowl.c</file>
|
||||
@@ -124,24 +115,6 @@
|
||||
<file>gnome-fs-directory.png</file>
|
||||
<file>gnome-fs-regular.png</file>
|
||||
</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">
|
||||
<file>shortcuts.ui</file>
|
||||
<file>shortcuts-builder.ui</file>
|
||||
@@ -181,6 +154,7 @@
|
||||
<file>assistant.c</file>
|
||||
<file>builder.c</file>
|
||||
<file>clipboard.c</file>
|
||||
<file>colorsel.c</file>
|
||||
<file>combobox.c</file>
|
||||
<file>constraints.c</file>
|
||||
<file>constraints2.c</file>
|
||||
@@ -194,7 +168,6 @@
|
||||
<file>cursors.c</file>
|
||||
<file>dialog.c</file>
|
||||
<file>drawingarea.c</file>
|
||||
<file>dropdown.c</file>
|
||||
<file>dnd.c</file>
|
||||
<file>editable_cells.c</file>
|
||||
<file>entry_completion.c</file>
|
||||
@@ -219,14 +192,6 @@
|
||||
<file>infobar.c</file>
|
||||
<file>links.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>markup.c</file>
|
||||
<file>modelbutton.c</file>
|
||||
@@ -301,7 +266,6 @@
|
||||
</gresource>
|
||||
<gresource prefix="/transparent">
|
||||
<file>portland-rose.jpg</file>
|
||||
<file>bluroverlay.h</file>
|
||||
<file>bluroverlay.c</file>
|
||||
</gresource>
|
||||
<gresource prefix="/markup">
|
||||
@@ -313,6 +277,9 @@
|
||||
<gresource prefix="/modelbutton">
|
||||
<file>modelbutton.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/dnd">
|
||||
<file>dnd.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/tagged_entry">
|
||||
<file>demotaggedentry.c</file>
|
||||
<file>demotaggedentry.h</file>
|
||||
@@ -342,7 +309,4 @@
|
||||
<file>icons/16x16/status/battery-caution-charging-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/categories/applications-other.png</file>
|
||||
</gresource>
|
||||
<gresource prefix="/org/gtk/Demo4/gtk">
|
||||
<file preprocess="xml-stripblanks">help-overlay.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
@@ -94,7 +94,6 @@
|
||||
<object class="GtkAboutDialog" id="aboutdialog1">
|
||||
<property name="program-name" translatable="yes">Builder demo</property>
|
||||
<property name="logo-icon-name" translatable="yes">gtk3-demo</property>
|
||||
<property name="modal">True</property>
|
||||
<accessibility>
|
||||
<relation target="window1" type="subwindow-of"/>
|
||||
</accessibility>
|
||||
|
@@ -1,259 +0,0 @@
|
||||
#include "demoimage.h"
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
struct _DemoImage {
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *image;
|
||||
GtkWidget *popover;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_ICON_NAME = 1
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(DemoImage, demo_image, GTK_TYPE_WIDGET)
|
||||
|
||||
static GdkPaintable *
|
||||
get_image_paintable (GtkImage *image)
|
||||
{
|
||||
const gchar *icon_name;
|
||||
GtkIconTheme *icon_theme;
|
||||
GtkIconPaintable *icon;
|
||||
|
||||
switch (gtk_image_get_storage_type (image))
|
||||
{
|
||||
case GTK_IMAGE_PAINTABLE:
|
||||
return g_object_ref (gtk_image_get_paintable (image));
|
||||
case GTK_IMAGE_ICON_NAME:
|
||||
icon_name = gtk_image_get_icon_name (image);
|
||||
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image)));
|
||||
icon = gtk_icon_theme_lookup_icon (icon_theme,
|
||||
icon_name,
|
||||
NULL,
|
||||
48, 1,
|
||||
gtk_widget_get_direction (GTK_WIDGET (image)),
|
||||
0);
|
||||
if (icon == NULL)
|
||||
return NULL;
|
||||
return GDK_PAINTABLE (icon);
|
||||
|
||||
case GTK_IMAGE_EMPTY:
|
||||
case GTK_IMAGE_GICON:
|
||||
default:
|
||||
g_warning ("Image storage type %d not handled",
|
||||
gtk_image_get_storage_type (image));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin (GtkDragSource *source,
|
||||
GdkDrag *drag,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
||||
DemoImage *demo = DEMO_IMAGE (widget);
|
||||
GdkPaintable *paintable;
|
||||
|
||||
paintable = get_image_paintable (GTK_IMAGE (demo->image));
|
||||
if (paintable)
|
||||
{
|
||||
gtk_drag_icon_set_from_paintable (drag, paintable, -2, -2);
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
prepare_drag (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
|
||||
DemoImage *demo = DEMO_IMAGE (widget);
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (demo->image));
|
||||
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_PAINTABLE, paintable);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drag_drop (GtkDropTarget *dest,
|
||||
const GValue *value,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
|
||||
DemoImage *demo = DEMO_IMAGE (widget);
|
||||
GdkPaintable *paintable = g_value_get_object (value);
|
||||
|
||||
gtk_image_set_from_paintable (GTK_IMAGE (demo->image), paintable);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_image (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
|
||||
DemoImage *demo = DEMO_IMAGE (widget);
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (demo->image));
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
g_value_init (&value, GDK_TYPE_PAINTABLE);
|
||||
g_value_set_object (&value, paintable);
|
||||
gdk_clipboard_set_value (clipboard, &value);
|
||||
g_value_unset (&value);
|
||||
|
||||
if (paintable)
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
|
||||
static void
|
||||
paste_image (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
|
||||
DemoImage *demo = DEMO_IMAGE (widget);
|
||||
GdkContentProvider *content = gdk_clipboard_get_content (clipboard);
|
||||
GValue value = G_VALUE_INIT;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
g_value_init (&value, GDK_TYPE_PAINTABLE);
|
||||
if (!gdk_content_provider_get_value (content, &value, NULL))
|
||||
return;
|
||||
|
||||
paintable = GDK_PAINTABLE (g_value_get_object (&value));
|
||||
gtk_image_set_from_paintable (GTK_IMAGE (demo->image), paintable);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
static void
|
||||
pressed_cb (GtkGesture *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
DemoImage *demo = DEMO_IMAGE (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture)));
|
||||
|
||||
gtk_popover_popup (GTK_POPOVER (demo->popover));
|
||||
}
|
||||
|
||||
static void
|
||||
demo_image_init (DemoImage *demo)
|
||||
{
|
||||
GMenu *menu;
|
||||
GMenuItem *item;
|
||||
GtkDragSource *source;
|
||||
GtkDropTarget *dest;
|
||||
GtkGesture *gesture;
|
||||
|
||||
demo->image = gtk_image_new ();
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (demo->image), 48);
|
||||
gtk_widget_set_parent (demo->image, GTK_WIDGET (demo));
|
||||
|
||||
menu = g_menu_new ();
|
||||
item = g_menu_item_new (_("_Copy"), "clipboard.copy");
|
||||
g_menu_append_item (menu, item);
|
||||
|
||||
item = g_menu_item_new (_("_Paste"), "clipboard.paste");
|
||||
g_menu_append_item (menu, item);
|
||||
|
||||
demo->popover = gtk_popover_menu_new_from_model (G_MENU_MODEL (menu));
|
||||
gtk_widget_set_parent (demo->popover, GTK_WIDGET (demo));
|
||||
|
||||
source = gtk_drag_source_new ();
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (prepare_drag), NULL);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), NULL);
|
||||
gtk_widget_add_controller (GTK_WIDGET (demo), GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
dest = gtk_drop_target_new (GDK_TYPE_PAINTABLE, GDK_ACTION_COPY);
|
||||
g_signal_connect (dest, "drop", G_CALLBACK (drag_drop), NULL);
|
||||
gtk_widget_add_controller (GTK_WIDGET (demo), GTK_EVENT_CONTROLLER (dest));
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), NULL);
|
||||
gtk_widget_add_controller (GTK_WIDGET (demo), GTK_EVENT_CONTROLLER (gesture));
|
||||
}
|
||||
|
||||
static void
|
||||
demo_image_dispose (GObject *object)
|
||||
{
|
||||
DemoImage *demo = DEMO_IMAGE (object);
|
||||
|
||||
g_clear_pointer (&demo->image, gtk_widget_unparent);
|
||||
g_clear_pointer (&demo->popover, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (demo_image_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_image_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
DemoImage *demo = DEMO_IMAGE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ICON_NAME:
|
||||
g_value_set_string (value, gtk_image_get_icon_name (GTK_IMAGE (demo->image)));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
demo_image_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
DemoImage *demo = DEMO_IMAGE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ICON_NAME:
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (demo->image),
|
||||
g_value_get_string (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
demo_image_class_init (DemoImageClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->dispose = demo_image_dispose;
|
||||
object_class->get_property = demo_image_get_property;
|
||||
object_class->set_property = demo_image_set_property;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_ICON_NAME,
|
||||
g_param_spec_string ("icon-name", "Icon name", "Icon name",
|
||||
NULL, G_PARAM_READWRITE));
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.copy", NULL, copy_image);
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.paste", NULL, paste_image);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
demo_image_new (const char *icon_name)
|
||||
{
|
||||
return g_object_new (DEMO_TYPE_IMAGE, "icon-name", icon_name, NULL);
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define DEMO_TYPE_IMAGE (demo_image_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE(DemoImage, demo_image, DEMO, IMAGE, GtkWidget)
|
||||
|
||||
GtkWidget * demo_image_new (const char *icon_name);
|
||||
|
||||
G_END_DECLS
|
@@ -25,36 +25,31 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <gtk/gtk-a11y.h>
|
||||
|
||||
struct _DemoTaggedEntry
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
typedef struct {
|
||||
GtkWidget *box;
|
||||
GtkWidget *entry;
|
||||
};
|
||||
|
||||
struct _DemoTaggedEntryClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
} DemoTaggedEntryPrivate;
|
||||
|
||||
static void demo_tagged_entry_editable_init (GtkEditableInterface *iface);
|
||||
|
||||
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))
|
||||
|
||||
static void
|
||||
demo_tagged_entry_init (DemoTaggedEntry *entry)
|
||||
{
|
||||
entry->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_parent (entry->box, GTK_WIDGET (entry));
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
entry->entry = gtk_text_new ();
|
||||
gtk_widget_set_hexpand (entry->entry, TRUE);
|
||||
gtk_widget_set_vexpand (entry->entry, TRUE);
|
||||
gtk_widget_set_hexpand (entry->box, FALSE);
|
||||
gtk_widget_set_vexpand (entry->box, FALSE);
|
||||
gtk_box_append (GTK_BOX (entry->box), entry->entry);
|
||||
priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_parent (priv->box, GTK_WIDGET (entry));
|
||||
|
||||
priv->entry = gtk_text_new ();
|
||||
gtk_widget_set_hexpand (priv->entry, TRUE);
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -62,16 +57,23 @@ static void
|
||||
demo_tagged_entry_dispose (GObject *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));
|
||||
|
||||
g_clear_pointer (&entry->entry, gtk_widget_unparent);
|
||||
g_clear_pointer (&entry->box, gtk_widget_unparent);
|
||||
g_clear_pointer (&priv->entry, gtk_widget_unparent);
|
||||
g_clear_pointer (&priv->box, gtk_widget_unparent);
|
||||
|
||||
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
|
||||
demo_tagged_entry_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -96,12 +98,44 @@ demo_tagged_entry_get_property (GObject *object,
|
||||
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
|
||||
demo_tagged_entry_grab_focus (GtkWidget *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
|
||||
@@ -111,14 +145,16 @@ demo_tagged_entry_class_init (DemoTaggedEntryClass *klass)
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
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->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;
|
||||
|
||||
|
||||
gtk_editable_install_properties (object_class, 1);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_ENTRY_ACCESSIBLE);
|
||||
gtk_widget_class_set_css_name (widget_class, "entry");
|
||||
}
|
||||
@@ -126,7 +162,10 @@ demo_tagged_entry_class_init (DemoTaggedEntryClass *klass)
|
||||
static GtkEditable *
|
||||
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
|
||||
@@ -145,9 +184,11 @@ void
|
||||
demo_tagged_entry_add_tag (DemoTaggedEntry *entry,
|
||||
GtkWidget *tag)
|
||||
{
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (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
|
||||
@@ -155,27 +196,30 @@ demo_tagged_entry_insert_tag_after (DemoTaggedEntry *entry,
|
||||
GtkWidget *tag,
|
||||
GtkWidget *sibling)
|
||||
{
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
|
||||
|
||||
if (sibling == NULL)
|
||||
gtk_box_append (GTK_BOX (entry->box), tag);
|
||||
gtk_container_add (GTK_CONTAINER (priv->box), tag);
|
||||
else
|
||||
gtk_box_insert_child_after (GTK_BOX (entry->box), tag, sibling);
|
||||
gtk_box_insert_child_after (GTK_BOX (priv->box), tag, sibling);
|
||||
}
|
||||
|
||||
void
|
||||
demo_tagged_entry_remove_tag (DemoTaggedEntry *entry,
|
||||
GtkWidget *tag)
|
||||
{
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (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
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkWidget *box;
|
||||
GtkWidget *label;
|
||||
GtkWidget *button;
|
||||
@@ -206,11 +250,11 @@ static guint signals[LAST_SIGNAL] = { 0, };
|
||||
G_DEFINE_TYPE (DemoTaggedEntryTag, demo_tagged_entry_tag, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
on_released (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
DemoTaggedEntryTag *tag)
|
||||
on_released (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
DemoTaggedEntryTag *tag)
|
||||
{
|
||||
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);
|
||||
gtk_widget_set_parent (tag->box, GTK_WIDGET (tag));
|
||||
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 ();
|
||||
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)
|
||||
{
|
||||
gtk_box_remove (GTK_BOX (tag->box), tag->button);
|
||||
gtk_container_remove (GTK_CONTAINER (tag->box), tag->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");
|
||||
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_valign (tag->button, GTK_ALIGN_CENTER);
|
||||
gtk_button_set_has_frame (GTK_BUTTON (tag->button), FALSE);
|
||||
gtk_box_append (GTK_BOX (tag->box), tag->button);
|
||||
gtk_container_add (GTK_CONTAINER (tag->box), tag->button);
|
||||
g_signal_connect (tag->button, "clicked", G_CALLBACK (on_button_clicked), tag);
|
||||
}
|
||||
|
||||
|
@@ -25,11 +25,39 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define DEMO_TYPE_TAGGED_ENTRY (demo_tagged_entry_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (DemoTaggedEntry, demo_tagged_entry, DEMO, TAGGED_ENTRY, GtkWidget)
|
||||
#define DEMO_TYPE_TAGGED_ENTRY (demo_tagged_entry_get_type ())
|
||||
#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 ())
|
||||
G_DECLARE_FINAL_TYPE (DemoTaggedEntryTag, demo_tagged_entry_tag, DEMO, TAGGED_ENTRY_TAG, GtkWidget)
|
||||
typedef struct _DemoTaggedEntry DemoTaggedEntry;
|
||||
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);
|
||||
|
||||
|
@@ -1,7 +1,6 @@
|
||||
/* Dialogs
|
||||
/* Dialogs and Message Boxes
|
||||
*
|
||||
* Dialogs are used to pop up transient windows for information
|
||||
* and user feedback.
|
||||
* Dialog widgets are used to pop up a transient window for user feedback.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
@@ -22,71 +21,51 @@ message_dialog_clicked (GtkButton *button,
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_INFO,
|
||||
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),
|
||||
ngettext ("Has been shown once", "Has been shown %d times", i), i);
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
|
||||
gtk_widget_show (dialog);
|
||||
"%d", i);
|
||||
gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
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
|
||||
interactive_dialog_clicked (GtkButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *content_area;
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *image;
|
||||
GtkWidget *table;
|
||||
GtkWidget *local_entry1;
|
||||
GtkWidget *local_entry2;
|
||||
GtkWidget *label;
|
||||
ResponseData *data;
|
||||
gint response;
|
||||
|
||||
dialog = gtk_dialog_new_with_buttons ("Interactive Dialog",
|
||||
GTK_WINDOW (window),
|
||||
GTK_DIALOG_MODAL| GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_USE_HEADER_BAR,
|
||||
_("_OK"), GTK_RESPONSE_OK,
|
||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||
GTK_DIALOG_MODAL| GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
_("_OK"),
|
||||
GTK_RESPONSE_OK,
|
||||
"_Cancel",
|
||||
GTK_RESPONSE_CANCEL,
|
||||
NULL);
|
||||
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
|
||||
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
|
||||
table = gtk_grid_new ();
|
||||
gtk_widget_set_hexpand (table, TRUE);
|
||||
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);
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
||||
|
||||
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");
|
||||
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
|
||||
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_label_set_mnemonic_widget (GTK_LABEL (label), local_entry2);
|
||||
|
||||
data = g_new (ResponseData, 1);
|
||||
data->local_entry1 = local_entry1;
|
||||
data->local_entry2 = local_entry2;
|
||||
data->global_entry1 = entry1;
|
||||
data->global_entry2 = entry2;
|
||||
response = gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
|
||||
g_signal_connect_data (dialog, "response",
|
||||
G_CALLBACK (on_dialog_response),
|
||||
data, (GClosureNotify) g_free,
|
||||
0);
|
||||
if (response == GTK_RESPONSE_OK)
|
||||
{
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry1), gtk_editable_get_text (GTK_EDITABLE (local_entry1)));
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry2), gtk_editable_get_text (GTK_EDITABLE (local_entry2)));
|
||||
}
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_dialog (GtkWidget *do_widget)
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *vbox2;
|
||||
GtkWidget *hbox;
|
||||
@@ -131,42 +108,50 @@ do_dialog (GtkWidget *do_widget)
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Dialogs");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Dialogs and Message Boxes");
|
||||
|
||||
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_container_add (GTK_CONTAINER (window), frame);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
|
||||
gtk_widget_set_margin_start (vbox, 8);
|
||||
gtk_widget_set_margin_end (vbox, 8);
|
||||
gtk_widget_set_margin_top (vbox, 8);
|
||||
gtk_widget_set_margin_bottom (vbox, 8);
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
gtk_container_add (GTK_CONTAINER (frame), vbox);
|
||||
|
||||
/* Standard message dialog */
|
||||
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");
|
||||
g_signal_connect (button, "clicked",
|
||||
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*/
|
||||
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);
|
||||
|
||||
button = gtk_button_new_with_mnemonic ("_Interactive Dialog");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (interactive_dialog_clicked), NULL);
|
||||
gtk_box_append (GTK_BOX (hbox), vbox2);
|
||||
gtk_box_append (GTK_BOX (vbox2), button);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), vbox2);
|
||||
gtk_container_add (GTK_CONTAINER (vbox2), button);
|
||||
|
||||
table = gtk_grid_new ();
|
||||
gtk_grid_set_row_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");
|
||||
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))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,37 +1,3 @@
|
||||
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); }
|
||||
spinner.demo {
|
||||
opacity: 1;
|
||||
}
|
||||
|
@@ -42,9 +42,7 @@ create_surface (GtkWidget *widget)
|
||||
}
|
||||
|
||||
static void
|
||||
scribble_resize (GtkWidget *widget,
|
||||
int width,
|
||||
int height)
|
||||
scribble_size_allocate (GtkWidget *widget)
|
||||
{
|
||||
create_surface (widget);
|
||||
}
|
||||
@@ -125,164 +123,49 @@ drag_end (GtkGestureDrag *gesture,
|
||||
}
|
||||
|
||||
static void
|
||||
oval_path (cairo_t *cr,
|
||||
double xc, double yc,
|
||||
double xr, double yr)
|
||||
checkerboard_draw (GtkDrawingArea *da,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data)
|
||||
{
|
||||
cairo_save (cr);
|
||||
gint i, j, xcount, ycount;
|
||||
|
||||
cairo_translate (cr, xc, yc);
|
||||
cairo_scale (cr, 1.0, yr / xr);
|
||||
cairo_move_to (cr, xr, 0.0);
|
||||
cairo_arc (cr,
|
||||
0, 0,
|
||||
xr,
|
||||
0, 2 * G_PI);
|
||||
cairo_close_path (cr);
|
||||
#define CHECK_SIZE 10
|
||||
#define SPACING 2
|
||||
|
||||
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
|
||||
* for showing compositing effects.
|
||||
*
|
||||
* 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)
|
||||
xcount = 0;
|
||||
i = SPACING;
|
||||
while (i < width)
|
||||
{
|
||||
i = y & (-CHECK_SIZE);
|
||||
for (; i < width; i += CHECK_SIZE)
|
||||
if ((i / CHECK_SIZE + j / CHECK_SIZE) % 2 == 0)
|
||||
j = SPACING;
|
||||
ycount = xcount % 2; /* start with even/odd depending on row */
|
||||
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_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
|
||||
@@ -319,25 +202,26 @@ do_drawingarea (GtkWidget *do_widget)
|
||||
gtk_widget_set_margin_end (vbox, 16);
|
||||
gtk_widget_set_margin_top (vbox, 16);
|
||||
gtk_widget_set_margin_bottom (vbox, 16);
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
/*
|
||||
* Create the groups area
|
||||
* Create the checkerboard area
|
||||
*/
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>Knockout groups</u>");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
"<u>Checkerboard pattern</u>");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
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 ();
|
||||
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_draw_func (GTK_DRAWING_AREA (da), groups_draw, NULL, NULL);
|
||||
gtk_frame_set_child (GTK_FRAME (frame), da);
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), checkerboard_draw, NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (frame), da);
|
||||
|
||||
/*
|
||||
* Create the scribble area
|
||||
@@ -346,20 +230,20 @@ do_drawingarea (GtkWidget *do_widget)
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>Scribble area</u>");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
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 ();
|
||||
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_draw_func (GTK_DRAWING_AREA (da), scribble_draw, NULL, NULL);
|
||||
gtk_frame_set_child (GTK_FRAME (frame), da);
|
||||
gtk_container_add (GTK_CONTAINER (frame), da);
|
||||
|
||||
g_signal_connect (da, "resize",
|
||||
G_CALLBACK (scribble_resize), NULL);
|
||||
g_signal_connect (da, "size-allocate",
|
||||
G_CALLBACK (scribble_size_allocate), NULL);
|
||||
|
||||
drag = gtk_gesture_drag_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), GDK_BUTTON_PRIMARY);
|
||||
@@ -374,7 +258,7 @@ do_drawingarea (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
@@ -352,24 +352,25 @@ do_editable_cells (GtkWidget *do_widget)
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
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);
|
||||
gtk_widget_set_margin_start (vbox, 5);
|
||||
gtk_widget_set_margin_end (vbox, 5);
|
||||
gtk_widget_set_margin_top (vbox, 5);
|
||||
gtk_widget_set_margin_bottom (vbox, 5);
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
gtk_box_append (GTK_BOX (vbox),
|
||||
gtk_container_add (GTK_CONTAINER (vbox),
|
||||
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_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_box_append (GTK_BOX (vbox), sw);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), sw);
|
||||
|
||||
/* create models */
|
||||
items_model = create_items_model ();
|
||||
@@ -386,22 +387,22 @@ do_editable_cells (GtkWidget *do_widget)
|
||||
g_object_unref (numbers_model);
|
||||
g_object_unref (items_model);
|
||||
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), treeview);
|
||||
gtk_container_add (GTK_CONTAINER (sw), treeview);
|
||||
|
||||
/* some buttons */
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
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");
|
||||
g_signal_connect (button, "clicked",
|
||||
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");
|
||||
g_signal_connect (button, "clicked",
|
||||
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);
|
||||
}
|
||||
@@ -409,7 +410,7 @@ do_editable_cells (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Entry/Completion
|
||||
/* Entry/Entry Completion
|
||||
*
|
||||
* GtkEntryCompletion provides a mechanism for adding support for
|
||||
* completion in GtkEntry.
|
||||
@@ -12,48 +12,22 @@
|
||||
static GtkTreeModel *
|
||||
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;
|
||||
GtkTreeIter iter;
|
||||
|
||||
store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||
|
||||
for (i = 0; strings[i]; i++)
|
||||
{
|
||||
/* Append one word */
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, 0, strings[i], -1);
|
||||
}
|
||||
/* Append one word */
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, 0, "GNOME", -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);
|
||||
}
|
||||
@@ -74,24 +48,26 @@ do_entry_completion (GtkWidget *do_widget)
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Completion");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Entry Completion");
|
||||
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);
|
||||
gtk_widget_set_margin_start (vbox, 5);
|
||||
gtk_widget_set_margin_end (vbox, 5);
|
||||
gtk_widget_set_margin_top (vbox, 5);
|
||||
gtk_widget_set_margin_bottom (vbox, 5);
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label), "Try writing <b>total</b> or <b>gnome</b> for example.");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
gtk_label_set_markup (GTK_LABEL (label), "Completion demo, try writing <b>total</b> or <b>gnome</b> for example.");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
|
||||
/* Create our entry */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_box_append (GTK_BOX (vbox), entry);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), entry);
|
||||
|
||||
/* Create the completion object */
|
||||
completion = gtk_entry_completion_new ();
|
||||
@@ -107,15 +83,12 @@ do_entry_completion (GtkWidget *do_widget)
|
||||
|
||||
/* Use model column 0 as the text column */
|
||||
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))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/* Entry/Undo and Redo
|
||||
/* Entry/Entry Undo
|
||||
*
|
||||
* GtkEntry can provide basic Undo/Redo support using standard keyboard
|
||||
* accelerators such as Control+z to undo and Control+Shift+z to redo.
|
||||
* Additionally, Control+y can be used to redo.
|
||||
* accelerators such as Primary+z to undo and Primary+Shift+z to redo.
|
||||
* Additionally, Primary+y can be used to redo.
|
||||
*
|
||||
* Use gtk_entry_set_enable_undo() to enable undo/redo support.
|
||||
*/
|
||||
@@ -23,32 +23,33 @@ do_entry_undo (GtkWidget *do_widget)
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Undo and Redo");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Entry Undo");
|
||||
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);
|
||||
gtk_widget_set_margin_start (vbox, 5);
|
||||
gtk_widget_set_margin_end (vbox, 5);
|
||||
gtk_widget_set_margin_top (vbox, 5);
|
||||
gtk_widget_set_margin_bottom (vbox, 5);
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"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 */
|
||||
entry = gtk_entry_new ();
|
||||
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))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ static GtkWidget *window = NULL;
|
||||
static void
|
||||
response_cb (GtkDialog *dialog, gint response_id)
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
window = NULL;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ do_expander (GtkWidget *do_widget)
|
||||
|
||||
expander = gtk_expander_new ("Details:");
|
||||
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_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
@@ -78,9 +78,9 @@ do_expander (GtkWidget *do_widget)
|
||||
"A second paragraph will contain even more "
|
||||
"innuendo, just to make you scroll down or "
|
||||
"resize the window. Do it already !", -1);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), tv);
|
||||
gtk_expander_set_child (GTK_EXPANDER (expander), sw);
|
||||
gtk_box_append (GTK_BOX (area), expander);
|
||||
gtk_container_add (GTK_CONTAINER (sw), tv);
|
||||
gtk_container_add (GTK_CONTAINER (expander), sw);
|
||||
gtk_container_add (GTK_CONTAINER (area), expander);
|
||||
g_signal_connect (expander, "notify::expanded",
|
||||
G_CALLBACK (expander_cb), window);
|
||||
|
||||
@@ -90,7 +90,7 @@ do_expander (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -125,7 +125,8 @@ do_filtermodel (GtkWidget *do_widget)
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
store = (GtkListStore*)gtk_builder_get_object (builder, "liststore1");
|
||||
|
||||
@@ -198,7 +199,7 @@ do_filtermodel (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -161,7 +161,7 @@ create_menu_button (void)
|
||||
GtkWidget *w = gtk_menu_button_new ();
|
||||
GtkWidget *popover = gtk_popover_new ();
|
||||
|
||||
gtk_popover_set_child (GTK_POPOVER (popover), gtk_button_new_with_label ("Hey!"));
|
||||
gtk_container_add (GTK_CONTAINER (popover), gtk_button_new_with_label ("Hey!"));
|
||||
gtk_popover_set_autohide (GTK_POPOVER (popover), FALSE);
|
||||
gtk_menu_button_set_popover (GTK_MENU_BUTTON (w), popover);
|
||||
g_signal_connect (w, "map", G_CALLBACK (mapped), NULL);
|
||||
@@ -194,7 +194,7 @@ static void
|
||||
set_widget_type (GtkFishbowl *fishbowl,
|
||||
int widget_type_index)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *window, *headerbar;
|
||||
|
||||
if (widget_type_index == selected_widget_type)
|
||||
return;
|
||||
@@ -205,8 +205,9 @@ set_widget_type (GtkFishbowl *fishbowl,
|
||||
widget_types[selected_widget_type].create_func);
|
||||
|
||||
window = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (fishbowl)));
|
||||
gtk_window_set_title (GTK_WINDOW (window),
|
||||
widget_types[selected_widget_type].name);
|
||||
headerbar = gtk_window_get_titlebar (GTK_WINDOW (window));
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar),
|
||||
widget_types[selected_widget_type].name);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -249,14 +250,6 @@ fishbowl_changes_toggled_cb (GtkToggleButton *button,
|
||||
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 *
|
||||
do_fishbowl (GtkWidget *do_widget)
|
||||
{
|
||||
@@ -281,13 +274,15 @@ do_fishbowl (GtkWidget *do_widget)
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui");
|
||||
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"));
|
||||
selected_widget_type = -1;
|
||||
set_widget_type (GTK_FISHBOWL (bowl), 0);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
gtk_widget_realize (window);
|
||||
g_object_unref (builder);
|
||||
@@ -296,7 +291,7 @@ do_fishbowl (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
@@ -27,12 +28,22 @@
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkLabel">
|
||||
<binding name="label">
|
||||
<closure type="gchararray" function="format_header_cb">
|
||||
<lookup name="count">bowl</lookup>
|
||||
<lookup name="framerate">bowl</lookup>
|
||||
</closure>
|
||||
</binding>
|
||||
<property name="label">fps</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkLabel">
|
||||
<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>
|
||||
</child>
|
||||
<child type="end">
|
||||
@@ -47,7 +58,6 @@
|
||||
<child>
|
||||
<object class="GtkFishbowl" id="bowl">
|
||||
<property name="visible">True</property>
|
||||
<property name="overflow">hidden</property>
|
||||
<property name="animating">True</property>
|
||||
<property name="benchmark" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean | sync-create"/>
|
||||
</object>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Fixed Layout
|
||||
/* Fixed layout
|
||||
*
|
||||
* GtkFixed is a container that allows placing and transforming
|
||||
* widgets manually.
|
||||
@@ -53,7 +53,7 @@ create_faces (void)
|
||||
faces[i].face = gtk_frame_new (NULL);
|
||||
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_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 */
|
||||
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (w, h));
|
||||
@@ -126,20 +126,20 @@ create_demo_window (GtkWidget *do_widget)
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Fixed Layout");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Fixed layout");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), sw);
|
||||
|
||||
fixed = gtk_fixed_new ();
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), fixed);
|
||||
gtk_container_add (GTK_CONTAINER (sw), fixed);
|
||||
gtk_widget_set_halign (GTK_WIDGET (fixed), GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (GTK_WIDGET (fixed), GTK_ALIGN_CENTER);
|
||||
|
||||
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);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
@@ -161,7 +161,7 @@ do_fixed (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (demo_window))
|
||||
gtk_widget_show (demo_window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (demo_window));
|
||||
gtk_widget_destroy (demo_window);
|
||||
|
||||
return demo_window;
|
||||
}
|
||||
|
@@ -1,10 +1,9 @@
|
||||
/* Flow Box
|
||||
*
|
||||
* GtkFlowBox allows flexible and responsive grids which reflow
|
||||
* as needed and support sorting and filtering. The children of
|
||||
* a GtkFlowBox are regular widgets
|
||||
* as needed and support sorting and filtering.
|
||||
*
|
||||
* The dataset used here has 665 colors.
|
||||
* The children of a GtkFlowBox are regular widgets
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
@@ -38,7 +37,7 @@ color_swatch_new (const gchar *color)
|
||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (area), 24);
|
||||
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (area), 24);
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (area), draw_color, (gpointer) color, NULL);
|
||||
gtk_button_set_child (GTK_BUTTON (button), area);
|
||||
gtk_container_add (GTK_CONTAINER (button), area);
|
||||
|
||||
return button;
|
||||
}
|
||||
@@ -725,26 +724,28 @@ do_flowbox (GtkWidget *do_widget)
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Flow Box");
|
||||
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);
|
||||
flowbox = gtk_flow_box_new ();
|
||||
gtk_widget_set_valign (flowbox, GTK_ALIGN_START);
|
||||
gtk_flow_box_set_max_children_per_line (GTK_FLOW_BOX (flowbox), 30);
|
||||
gtk_flow_box_set_selection_mode (GTK_FLOW_BOX (flowbox), GTK_SELECTION_NONE);
|
||||
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled), flowbox);
|
||||
gtk_window_set_child (GTK_WINDOW (window), scrolled);
|
||||
gtk_container_add (GTK_CONTAINER (scrolled), flowbox);
|
||||
gtk_container_add (GTK_CONTAINER (window), scrolled);
|
||||
|
||||
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))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -4,9 +4,10 @@
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="default-width">600</property>
|
||||
<property name="default-height">500</property>
|
||||
<property name="title">Font Explorer</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<property name="title">Font Explorer</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="reset">
|
||||
<property name="receives-default">1</property>
|
||||
|
@@ -194,7 +194,7 @@ add_check_group (GtkWidget *box,
|
||||
pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
|
||||
gtk_label_set_attributes (GTK_LABEL (label), 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++)
|
||||
{
|
||||
@@ -211,7 +211,7 @@ add_check_group (GtkWidget *box,
|
||||
g_signal_connect (feat, "notify::inconsistent", G_CALLBACK (update_display), 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->name = tags[i];
|
||||
@@ -223,7 +223,7 @@ add_check_group (GtkWidget *box,
|
||||
feature_items = g_list_prepend (feature_items, item);
|
||||
}
|
||||
|
||||
gtk_box_append (GTK_BOX (box), group);
|
||||
gtk_container_add (GTK_CONTAINER (box), group);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -248,7 +248,7 @@ add_radio_group (GtkWidget *box,
|
||||
pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
|
||||
gtk_label_set_attributes (GTK_LABEL (label), 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++)
|
||||
{
|
||||
@@ -268,7 +268,7 @@ add_radio_group (GtkWidget *box,
|
||||
g_signal_connect (feat, "notify::active", G_CALLBACK (update_display), NULL);
|
||||
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->name = tags[i];
|
||||
@@ -280,7 +280,7 @@ add_radio_group (GtkWidget *box,
|
||||
feature_items = g_list_prepend (feature_items, item);
|
||||
}
|
||||
|
||||
gtk_box_append (GTK_BOX (box), group);
|
||||
gtk_container_add (GTK_CONTAINER (box), group);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1025,7 +1025,7 @@ denorm_coord (hb_ot_var_axis_info_t *axis, int coord)
|
||||
static void
|
||||
update_font_variations (void)
|
||||
{
|
||||
GtkWidget *child;
|
||||
GtkWidget *child, *next;
|
||||
PangoFont *pango_font = NULL;
|
||||
hb_font_t *hb_font;
|
||||
hb_face_t *hb_face;
|
||||
@@ -1037,8 +1037,12 @@ update_font_variations (void)
|
||||
int i;
|
||||
|
||||
child = gtk_widget_get_first_child (variations_grid);
|
||||
while ((child = gtk_widget_get_first_child (variations_grid)))
|
||||
gtk_grid_remove (GTK_GRID (variations_grid), child);
|
||||
while (child != NULL)
|
||||
{
|
||||
next = gtk_widget_get_next_sibling (child);
|
||||
gtk_widget_destroy (child);
|
||||
child = next;
|
||||
}
|
||||
|
||||
instance_combo = NULL;
|
||||
|
||||
@@ -1329,7 +1333,8 @@ do_font_features (GtkWidget *do_widget)
|
||||
|
||||
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);
|
||||
|
||||
@@ -1339,7 +1344,7 @@ do_font_features (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -281,7 +281,7 @@ do_fontrendering (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -53,7 +53,7 @@ create_axis_slider (GtkGears *gears,
|
||||
}
|
||||
|
||||
label = gtk_label_new (text);
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
gtk_container_add (GTK_CONTAINER (box), 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);
|
||||
@@ -63,7 +63,7 @@ create_axis_slider (GtkGears *gears,
|
||||
gears);
|
||||
slider = gtk_scale_new (GTK_ORIENTATION_VERTICAL, adj);
|
||||
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_show (slider);
|
||||
|
||||
@@ -85,7 +85,7 @@ do_gears (GtkWidget *do_widget)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Gears");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
|
||||
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 ();
|
||||
gtk_widget_set_margin_start (overlay, 12);
|
||||
@@ -93,7 +93,7 @@ do_gears (GtkWidget *do_widget)
|
||||
gtk_widget_set_margin_top (overlay, 12);
|
||||
gtk_widget_set_margin_bottom (overlay, 12);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), overlay);
|
||||
gtk_container_add (GTK_CONTAINER (window), overlay);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_set_halign (frame, GTK_ALIGN_START);
|
||||
@@ -103,27 +103,27 @@ do_gears (GtkWidget *do_widget)
|
||||
|
||||
fps_label = gtk_label_new ("");
|
||||
gtk_widget_set_halign (fps_label, GTK_ALIGN_START);
|
||||
gtk_frame_set_child (GTK_FRAME (frame), fps_label);
|
||||
gtk_container_add (GTK_CONTAINER (frame), fps_label);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE);
|
||||
gtk_box_set_spacing (GTK_BOX (box), 6);
|
||||
gtk_overlay_set_child (GTK_OVERLAY (overlay), box);
|
||||
gtk_container_add (GTK_CONTAINER (overlay), box);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE);
|
||||
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 ();
|
||||
gtk_widget_set_hexpand (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++)
|
||||
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);
|
||||
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));
|
||||
}
|
||||
@@ -131,7 +131,7 @@ do_gears (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -13,16 +13,17 @@ in_files = sys.argv[2:]
|
||||
file_output = """
|
||||
typedef GtkWidget *(*GDoDemoFunc) (GtkWidget *do_widget);
|
||||
|
||||
typedef struct _DemoData DemoData;
|
||||
typedef struct _Demo Demo;
|
||||
|
||||
struct _DemoData
|
||||
struct _Demo
|
||||
{
|
||||
const char *name;
|
||||
const char *title;
|
||||
const char *filename;
|
||||
GDoDemoFunc func;
|
||||
DemoData *children;
|
||||
Demo *children;
|
||||
};
|
||||
|
||||
"""
|
||||
|
||||
# Demo = namedtuple('Demo', ['name', 'title', 'file', 'func'])
|
||||
@@ -66,7 +67,7 @@ for demo in demos:
|
||||
i = 0
|
||||
for parent in parents:
|
||||
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
|
||||
for child in demos:
|
||||
if child[1].startswith(parent + "/"):
|
||||
@@ -81,7 +82,7 @@ for parent in parents:
|
||||
# Sort demos by title
|
||||
demos = sorted(demos, key=lambda x: x[1])
|
||||
|
||||
file_output += "\nDemoData gtk_demos[] = {\n"
|
||||
file_output += "\nDemo gtk_demos[] = {\n"
|
||||
for demo in demos:
|
||||
# Do not generate one of these for demos with a parent demo
|
||||
if "/" not in demo[1]:
|
||||
|
@@ -149,10 +149,11 @@ do_gestures (GtkWidget *do_widget)
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
|
||||
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 ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), drawing_area);
|
||||
gtk_container_add (GTK_CONTAINER (window), drawing_area);
|
||||
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (drawing_area),
|
||||
drawing_area_draw,
|
||||
@@ -209,7 +210,7 @@ do_gestures (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -354,7 +354,7 @@ create_axis_slider (int axis)
|
||||
}
|
||||
|
||||
label = gtk_label_new (text);
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
gtk_container_add (GTK_CONTAINER (box), label);
|
||||
gtk_widget_show (label);
|
||||
|
||||
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),
|
||||
GINT_TO_POINTER (axis));
|
||||
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_show (slider);
|
||||
|
||||
@@ -401,12 +401,12 @@ create_glarea_window (GtkWidget *do_widget)
|
||||
gtk_widget_set_margin_top (box, 12);
|
||||
gtk_widget_set_margin_bottom (box, 12);
|
||||
gtk_box_set_spacing (GTK_BOX (box), 6);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
gl_area = gtk_gl_area_new ();
|
||||
gtk_widget_set_hexpand (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
|
||||
* 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);
|
||||
|
||||
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);
|
||||
|
||||
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");
|
||||
gtk_widget_set_hexpand (button, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window);
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -441,7 +441,7 @@ do_glarea (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (demo_window))
|
||||
gtk_widget_show (demo_window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (demo_window));
|
||||
gtk_widget_destroy (demo_window);
|
||||
|
||||
return demo_window;
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ typedef struct _GtkFishbowlChild GtkFishbowlChild;
|
||||
struct _GtkFishbowlPrivate
|
||||
{
|
||||
GtkFishCreationFunc creation_func;
|
||||
GHashTable *children;
|
||||
GList *children;
|
||||
guint count;
|
||||
|
||||
gint64 last_frame_time;
|
||||
@@ -53,6 +53,7 @@ enum {
|
||||
PROP_BENCHMARK,
|
||||
PROP_COUNT,
|
||||
PROP_FRAMERATE,
|
||||
PROP_FRAMERATE_STRING,
|
||||
PROP_UPDATE_DELAY,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
@@ -67,8 +68,6 @@ gtk_fishbowl_init (GtkFishbowl *fishbowl)
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
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);
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
GtkFishbowlChild *child;
|
||||
GList *children;
|
||||
gint child_min, child_nat;
|
||||
|
||||
*minimum = 0;
|
||||
*natural = 0;
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->children);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
for (children = priv->children; children; children = children->next)
|
||||
{
|
||||
child = value;
|
||||
child = children->data;
|
||||
|
||||
if (!gtk_widget_get_visible (child->widget))
|
||||
continue;
|
||||
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
@@ -136,13 +137,14 @@ gtk_fishbowl_size_allocate (GtkWidget *widget,
|
||||
GtkFishbowlChild *child;
|
||||
GtkAllocation child_allocation;
|
||||
GtkRequisition child_requisition;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
GList *children;
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->children);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
for (children = priv->children; children; children = children->next)
|
||||
{
|
||||
child = value;
|
||||
child = children->data;
|
||||
|
||||
if (!gtk_widget_get_visible (child->widget))
|
||||
continue;
|
||||
|
||||
gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
|
||||
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));
|
||||
|
||||
g_hash_table_insert (priv->children, widget, child_info);
|
||||
priv->children = g_list_prepend (priv->children, child_info);
|
||||
priv->count++;
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
|
||||
}
|
||||
@@ -190,26 +192,34 @@ gtk_fishbowl_remove (GtkFishbowl *fishbowl,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
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--;
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
|
||||
if (child->widget == widget)
|
||||
{
|
||||
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
|
||||
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));
|
||||
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:
|
||||
g_value_set_int64 (value, gtk_fishbowl_get_update_delay (fishbowl));
|
||||
break;
|
||||
@@ -295,7 +313,6 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = gtk_fishbowl_finalize;
|
||||
object_class->dispose = gtk_fishbowl_dispose;
|
||||
object_class->set_property = gtk_fishbowl_set_property;
|
||||
object_class->get_property = gtk_fishbowl_get_property;
|
||||
@@ -333,6 +350,13 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
|
||||
0,
|
||||
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] =
|
||||
g_param_spec_int64 ("update-delay",
|
||||
"Update delay",
|
||||
@@ -484,6 +508,7 @@ gtk_fishbowl_do_update (GtkFishbowl *fishbowl)
|
||||
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_STRING]);
|
||||
|
||||
if (!priv->benchmark)
|
||||
return;
|
||||
@@ -527,9 +552,8 @@ gtk_fishbowl_tick (GtkWidget *widget,
|
||||
GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
GtkFishbowlChild *child;
|
||||
GList *l;
|
||||
gint64 frame_time, elapsed;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
gboolean do_update;
|
||||
|
||||
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)
|
||||
return G_SOURCE_CONTINUE;
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->children);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
for (l = priv->children; l; l = l->next)
|
||||
{
|
||||
child = value;
|
||||
child = l->data;
|
||||
|
||||
child->x += child->dx * ((double) elapsed / G_USEC_PER_SEC);
|
||||
child->y += child->dy * ((double) elapsed / G_USEC_PER_SEC);
|
||||
|
@@ -197,7 +197,7 @@ gtk_gears_class_init (GtkGearsClass *klass)
|
||||
* @param v the vertex to fill
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
* @param z the z coordinate
|
||||
* @param z the z coortinate
|
||||
* @param n pointer to the normal table
|
||||
*
|
||||
* @return the operation error code
|
||||
|
@@ -2,8 +2,9 @@
|
||||
*
|
||||
* GtkHeaderBar is a container that is suitable for implementing
|
||||
* window titlebars. One of its features is that it can position
|
||||
* a title centered with regard to the full width, regardless of
|
||||
* variable-width content at the left or right.
|
||||
* a title (and optional subtitle) centered with regard to the
|
||||
* full width, regardless of variable-width content at the left
|
||||
* or right.
|
||||
*
|
||||
* It is commonly used with gtk_window_set_titlebar()
|
||||
*/
|
||||
@@ -24,40 +25,42 @@ do_headerbar (GtkWidget *do_widget)
|
||||
{
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "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);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Welcome to Facebook - Log in, sign up or learn more");
|
||||
gtk_header_bar_set_has_subtitle (GTK_HEADER_BAR (header), FALSE);
|
||||
|
||||
button = gtk_button_new ();
|
||||
icon = g_themed_icon_new ("mail-send-receive-symbolic");
|
||||
image = gtk_image_new_from_gicon (icon);
|
||||
g_object_unref (icon);
|
||||
gtk_button_set_child (GTK_BUTTON (button), image);
|
||||
gtk_container_add (GTK_CONTAINER (button), image);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_add_css_class (box, "linked");
|
||||
button = gtk_button_new ();
|
||||
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 (button), gtk_image_new_from_icon_name ("pan-start-symbolic"));
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
button = gtk_button_new ();
|
||||
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 (button), gtk_image_new_from_icon_name ("pan-end-symbolic"));
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), box);
|
||||
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), gtk_text_view_new ());
|
||||
gtk_container_add (GTK_CONTAINER (window), gtk_text_view_new ());
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -1,25 +0,0 @@
|
||||
<interface>
|
||||
<object class="GtkShortcutsWindow" id="help_overlay">
|
||||
<child>
|
||||
<object class="GtkShortcutsSection">
|
||||
<child>
|
||||
<object class="GtkShortcutsGroup">
|
||||
<property name="title">General</property>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="accelerator">F1</property>
|
||||
<property name="title">Show About Dialog</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="accelerator"><Control>q</property>
|
||||
<property name="title">Quit</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
@@ -237,7 +237,9 @@ do_hypertext (GtkWidget *do_widget)
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
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 ();
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
|
||||
@@ -260,12 +262,12 @@ do_hypertext (GtkWidget *do_widget)
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
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_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), view);
|
||||
gtk_container_add (GTK_CONTAINER (window), sw);
|
||||
gtk_container_add (GTK_CONTAINER (sw), view);
|
||||
|
||||
show_page (buffer, 1);
|
||||
}
|
||||
@@ -273,7 +275,7 @@ do_hypertext (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@ static GtkWidget *window = NULL;
|
||||
static GtkWidget *scrolledwindow;
|
||||
static int selected;
|
||||
|
||||
#define N_WIDGET_TYPES 6
|
||||
#define N_WIDGET_TYPES 4
|
||||
|
||||
|
||||
static int hincrement = 5;
|
||||
@@ -64,12 +64,11 @@ populate_icons (void)
|
||||
gtk_grid_attach (GTK_GRID (grid), create_icon (), left, top, 1, 1);
|
||||
|
||||
hincrement = 0;
|
||||
vincrement = 5;
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolledwindow), grid);
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (scrolledwindow), grid);
|
||||
}
|
||||
|
||||
static char *content;
|
||||
@@ -101,12 +100,11 @@ populate_text (gboolean hilight)
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
|
||||
|
||||
hincrement = 0;
|
||||
vincrement = 5;
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolledwindow), textview);
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (scrolledwindow), textview);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -126,48 +124,11 @@ populate_image (void)
|
||||
gtk_picture_set_can_shrink (GTK_PICTURE (image), FALSE);
|
||||
|
||||
hincrement = 5;
|
||||
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), 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);
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (scrolledwindow), image);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -176,8 +137,9 @@ set_widget_type (int type)
|
||||
if (tick_cb)
|
||||
gtk_widget_remove_tick_callback (window, tick_cb);
|
||||
|
||||
if (gtk_scrolled_window_get_child (GTK_SCROLLED_WINDOW (scrolledwindow)))
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolledwindow), NULL);
|
||||
if (gtk_bin_get_child (GTK_BIN (scrolledwindow)))
|
||||
gtk_container_remove (GTK_CONTAINER (scrolledwindow),
|
||||
gtk_bin_get_child (GTK_BIN (scrolledwindow)));
|
||||
|
||||
selected = type;
|
||||
|
||||
@@ -203,16 +165,6 @@ set_widget_type (int type)
|
||||
populate_image ();
|
||||
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:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
@@ -258,23 +210,23 @@ do_iconscroll (GtkWidget *do_widget)
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/iconscroll/iconscroll.ui");
|
||||
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_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"));
|
||||
gtk_widget_realize (window);
|
||||
hadjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "hadjustment"));
|
||||
vadjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "vadjustment"));
|
||||
set_widget_type (0);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@
|
||||
<property name="default-height">500</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
|
@@ -228,7 +228,7 @@ home_clicked (GtkButton *item,
|
||||
|
||||
static void close_window(void)
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
window = NULL;
|
||||
|
||||
g_object_unref (file_pixbuf);
|
||||
@@ -263,27 +263,27 @@ do_iconview (GtkWidget *do_widget)
|
||||
load_pixbufs ();
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
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");
|
||||
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");
|
||||
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_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
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 '/' */
|
||||
parent = g_strdup ("/");
|
||||
@@ -312,7 +312,7 @@ do_iconview (GtkWidget *do_widget)
|
||||
/* Connect to the "item-activated" signal */
|
||||
g_signal_connect (icon_view, "item-activated",
|
||||
G_CALLBACK (item_activated), store);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), icon_view);
|
||||
gtk_container_add (GTK_CONTAINER (sw), icon_view);
|
||||
|
||||
gtk_widget_grab_focus (icon_view);
|
||||
}
|
||||
@@ -320,7 +320,7 @@ do_iconview (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -111,7 +111,9 @@ do_iconview_edit (GtkWidget *do_widget)
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
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 ();
|
||||
fill_store (store);
|
||||
@@ -144,13 +146,13 @@ do_iconview_edit (GtkWidget *do_widget)
|
||||
"text", COL_TEXT,
|
||||
NULL);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), icon_view);
|
||||
gtk_container_add (GTK_CONTAINER (window), icon_view);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -91,7 +91,7 @@ progressive_timeout (gpointer data)
|
||||
g_error_free (error);
|
||||
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (gtk_window_destroy), NULL);
|
||||
G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
|
||||
g_object_unref (image_stream);
|
||||
image_stream = NULL;
|
||||
@@ -119,7 +119,7 @@ progressive_timeout (gpointer data)
|
||||
g_error_free (error);
|
||||
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (gtk_window_destroy), NULL);
|
||||
G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
|
||||
g_object_unref (image_stream);
|
||||
image_stream = NULL;
|
||||
@@ -152,7 +152,7 @@ progressive_timeout (gpointer data)
|
||||
g_error_free (error);
|
||||
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (gtk_window_destroy), NULL);
|
||||
G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
|
||||
@@ -189,7 +189,7 @@ progressive_timeout (gpointer data)
|
||||
g_error_free (error);
|
||||
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (gtk_window_destroy), NULL);
|
||||
G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
|
||||
@@ -223,7 +223,7 @@ progressive_timeout (gpointer data)
|
||||
g_error_free (error);
|
||||
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (gtk_window_destroy), NULL);
|
||||
G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
|
||||
@@ -293,16 +293,24 @@ static void
|
||||
toggle_sensitivity_callback (GtkWidget *togglebutton,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *child;
|
||||
GtkContainer *container = user_data;
|
||||
GList *list;
|
||||
GList *tmp;
|
||||
|
||||
for (child = gtk_widget_get_first_child (GTK_WIDGET (user_data));
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
list = gtk_container_get_children (container);
|
||||
|
||||
tmp = list;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
/* don't disable our toggle */
|
||||
if (child != togglebutton)
|
||||
gtk_widget_set_sensitive (child, !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (togglebutton)));
|
||||
if (GTK_WIDGET (tmp->data) != 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_widget_get_display (do_widget));
|
||||
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_CALLBACK (cleanup_callback), NULL);
|
||||
|
||||
@@ -337,28 +346,28 @@ do_images (GtkWidget *do_widget)
|
||||
gtk_widget_set_margin_end (base_vbox, 16);
|
||||
gtk_widget_set_margin_top (base_vbox, 16);
|
||||
gtk_widget_set_margin_bottom (base_vbox, 16);
|
||||
gtk_window_set_child (GTK_WINDOW (window), base_vbox);
|
||||
gtk_container_add (GTK_CONTAINER (window), base_vbox);
|
||||
|
||||
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);
|
||||
gtk_box_append (GTK_BOX (hbox), vbox);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), vbox);
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<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);
|
||||
gtk_widget_set_halign (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");
|
||||
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
|
||||
|
||||
gtk_frame_set_child (GTK_FRAME (frame), image);
|
||||
gtk_container_add (GTK_CONTAINER (frame), image);
|
||||
|
||||
|
||||
/* Animation */
|
||||
@@ -366,94 +375,94 @@ do_images (GtkWidget *do_widget)
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<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);
|
||||
gtk_widget_set_halign (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");
|
||||
|
||||
gtk_frame_set_child (GTK_FRAME (frame), picture);
|
||||
gtk_container_add (GTK_CONTAINER (frame), picture);
|
||||
|
||||
/* Symbolic icon */
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>Symbolic themed icon</u>");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_set_halign (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");
|
||||
image = gtk_image_new_from_gicon (gicon);
|
||||
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
|
||||
|
||||
gtk_frame_set_child (GTK_FRAME (frame), image);
|
||||
gtk_container_add (GTK_CONTAINER (frame), image);
|
||||
|
||||
|
||||
/* Progressive */
|
||||
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);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>Progressive image loading</u>");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_set_halign (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
|
||||
* will create the pixbuf and fill it in.
|
||||
*/
|
||||
picture = gtk_picture_new ();
|
||||
gtk_frame_set_child (GTK_FRAME (frame), picture);
|
||||
gtk_container_add (GTK_CONTAINER (frame), picture);
|
||||
|
||||
start_progressive_loading (picture);
|
||||
|
||||
/* Video */
|
||||
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);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>Displaying video</u>");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_set_halign (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");
|
||||
gtk_media_stream_set_loop (gtk_video_get_media_stream (GTK_VIDEO (video)), TRUE);
|
||||
gtk_frame_set_child (GTK_FRAME (frame), video);
|
||||
gtk_container_add (GTK_CONTAINER (frame), video);
|
||||
|
||||
/* Widget paintables */
|
||||
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);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>GtkWidgetPaintable</u>");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
|
||||
paintable = gtk_widget_paintable_new (do_widget);
|
||||
picture = gtk_picture_new_for_paintable (paintable);
|
||||
gtk_widget_set_size_request (picture, 100, 100);
|
||||
gtk_widget_set_valign (picture, GTK_ALIGN_START);
|
||||
gtk_box_append (GTK_BOX (vbox), picture);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), picture);
|
||||
|
||||
/* Sensitivity control */
|
||||
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_CALLBACK (toggle_sensitivity_callback),
|
||||
@@ -463,7 +472,7 @@ do_images (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -29,8 +29,10 @@ on_bar_response (GtkInfoBar *info_bar,
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||
"Your response has id %d", response_id);
|
||||
|
||||
g_signal_connect_swapped (dialog, "response",
|
||||
G_CALLBACK (gtk_window_destroy), dialog);
|
||||
g_signal_connect_swapped (dialog,
|
||||
"response",
|
||||
G_CALLBACK (gtk_widget_destroy),
|
||||
dialog);
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
}
|
||||
@@ -42,6 +44,7 @@ do_infobar (GtkWidget *do_widget)
|
||||
GtkWidget *frame;
|
||||
GtkWidget *bar;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *vbox2;
|
||||
GtkWidget *label;
|
||||
GtkWidget *actions;
|
||||
GtkWidget *button;
|
||||
@@ -49,104 +52,108 @@ do_infobar (GtkWidget *do_widget)
|
||||
if (!window)
|
||||
{
|
||||
actions = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_add_css_class (actions, "linked");
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Info Bars");
|
||||
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);
|
||||
gtk_widget_set_margin_start (vbox, 8);
|
||||
gtk_widget_set_margin_end (vbox, 8);
|
||||
gtk_widget_set_margin_top (vbox, 8);
|
||||
gtk_widget_set_margin_bottom (vbox, 8);
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
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);
|
||||
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_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");
|
||||
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 ();
|
||||
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);
|
||||
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_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");
|
||||
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);
|
||||
gtk_info_bar_set_show_close_button (GTK_INFO_BAR (bar), TRUE);
|
||||
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);
|
||||
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_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);
|
||||
|
||||
button = gtk_toggle_button_new_with_label ("Question");
|
||||
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 ();
|
||||
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);
|
||||
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_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");
|
||||
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 ();
|
||||
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);
|
||||
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_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");
|
||||
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 ("Info bars");
|
||||
gtk_widget_set_margin_top (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);
|
||||
vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
|
||||
gtk_widget_set_margin_start (vbox2, 8);
|
||||
gtk_widget_set_margin_end (vbox2, 8);
|
||||
gtk_widget_set_margin_top (vbox2, 8);
|
||||
gtk_widget_set_margin_bottom (vbox2, 8);
|
||||
gtk_container_add (GTK_CONTAINER (frame), vbox2);
|
||||
|
||||
gtk_widget_set_margin_start (actions, 8);
|
||||
gtk_widget_set_margin_end (actions, 8);
|
||||
gtk_widget_set_margin_top (actions, 8);
|
||||
gtk_widget_set_margin_bottom (actions, 8);
|
||||
gtk_frame_set_child (GTK_FRAME (frame), actions);
|
||||
/* Standard message dialog */
|
||||
label = gtk_label_new ("An example of different info bars");
|
||||
gtk_container_add (GTK_CONTAINER (vbox2), label);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox2), actions);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/* Links
|
||||
*
|
||||
* GtkLabel can show hyperlinks. The default action is to call
|
||||
* gtk_show_uri() on their URI, but it is possible to override
|
||||
* gtk_show_uri_on_window() on their URI, but it is possible to override
|
||||
* this with a custom handler.
|
||||
*/
|
||||
|
||||
@@ -12,7 +12,7 @@ response_cb (GtkWidget *dialog,
|
||||
gint response_id,
|
||||
gpointer data)
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (dialog));
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -30,8 +30,6 @@ activate_link (GtkWidget *label,
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_BUTTONS_OK,
|
||||
"Keyboard navigation");
|
||||
gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog),
|
||||
"The term <i>keynav</i> is a shorthand for "
|
||||
"keyboard navigation and refers to the process of using "
|
||||
"a program (exclusively) via keyboard input.");
|
||||
@@ -58,36 +56,29 @@ do_links (GtkWidget *do_widget)
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Links");
|
||||
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\""
|
||||
"title=\"plain text\">text</a> may be marked up "
|
||||
"as hyperlinks, which can be clicked "
|
||||
"or activated via <a href=\"keynav\">keynav</a> "
|
||||
"and they work fine with other markup, like when "
|
||||
"title=\"plain text\">text</a> may be marked up\n"
|
||||
"as hyperlinks, which can be clicked\n"
|
||||
"or activated via <a href=\"keynav\">keynav</a>\n"
|
||||
"and they work fine with other markup, like when\n"
|
||||
"searching on <a href=\"http://www.google.com/\">"
|
||||
"<span color=\"#0266C8\">G</span><span color=\"#F90101\">o</span>"
|
||||
"<span color=\"#F2B50F\">o</span><span color=\"#0266C8\">g</span>"
|
||||
"<span color=\"#00933B\">l</span><span color=\"#F90101\">e</span>"
|
||||
"</a>.");
|
||||
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_max_width_chars (GTK_LABEL (label), 40);
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD);
|
||||
g_signal_connect (label, "activate-link", G_CALLBACK (activate_link), NULL);
|
||||
gtk_widget_set_margin_start (label, 20);
|
||||
gtk_widget_set_margin_end (label, 20);
|
||||
gtk_widget_set_margin_top (label, 20);
|
||||
gtk_widget_set_margin_bottom (label, 20);
|
||||
gtk_window_set_child (GTK_WINDOW (window), label);
|
||||
gtk_container_add (GTK_CONTAINER (window), label);
|
||||
gtk_widget_show (label);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -257,24 +257,26 @@ do_list_store (GtkWidget *do_widget)
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
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);
|
||||
gtk_widget_set_margin_start (vbox, 8);
|
||||
gtk_widget_set_margin_end (vbox, 8);
|
||||
gtk_widget_set_margin_top (vbox, 8);
|
||||
gtk_widget_set_margin_bottom (vbox, 8);
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
label = gtk_label_new ("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_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_box_append (GTK_BOX (vbox), sw);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), sw);
|
||||
|
||||
/* create tree model */
|
||||
model = create_model ();
|
||||
@@ -287,7 +289,7 @@ do_list_store (GtkWidget *do_widget)
|
||||
|
||||
g_object_unref (model);
|
||||
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), treeview);
|
||||
gtk_container_add (GTK_CONTAINER (sw), treeview);
|
||||
|
||||
/* add columns to the tree view */
|
||||
add_columns (GTK_TREE_VIEW (treeview));
|
||||
@@ -307,7 +309,7 @@ do_list_store (GtkWidget *do_widget)
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
window = NULL;
|
||||
if (timeout != 0)
|
||||
{
|
||||
|
@@ -236,6 +236,7 @@ reshare_clicked (GtkMessageRow *row,
|
||||
|
||||
priv->message->n_reshares++;
|
||||
gtk_message_row_update (row);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -254,12 +255,11 @@ gtk_message_row_state_flags_changed (GtkWidget *widget,
|
||||
{
|
||||
GtkMessageRowPrivate *priv = GTK_MESSAGE_ROW (widget)->priv;
|
||||
GtkStateFlags flags;
|
||||
gboolean visible;
|
||||
|
||||
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, visible);
|
||||
gtk_widget_set_visible (priv->extra_buttons_box,
|
||||
flags & (GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_SELECTED));
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_message_row_parent_class)->state_flags_changed (widget, previous_state_flags);
|
||||
}
|
||||
@@ -351,19 +351,24 @@ do_listbox (GtkWidget *do_widget)
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "List Box");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
gtk_window_set_default_size (GTK_WINDOW (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);
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
label = gtk_label_new ("Messages from GTK and friends");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
scrolled = gtk_scrolled_window_new ();
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
scrolled = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||
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 ();
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled), listbox);
|
||||
gtk_container_add (GTK_CONTAINER (scrolled), listbox);
|
||||
|
||||
gtk_list_box_set_sort_func (GTK_LIST_BOX (listbox), (GtkListBoxSortFunc)gtk_message_row_sort, listbox, NULL);
|
||||
gtk_list_box_set_activate_on_single_click (GTK_LIST_BOX (listbox), FALSE);
|
||||
@@ -377,7 +382,7 @@ do_listbox (GtkWidget *do_widget)
|
||||
message = gtk_message_new (lines[i]);
|
||||
row = gtk_message_row_new (message);
|
||||
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);
|
||||
@@ -387,7 +392,7 @@ do_listbox (GtkWidget *do_widget)
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -150,7 +150,7 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="favorite-button">
|
||||
<object class="GtkButton" id="favorite-buttton">
|
||||
<property name="label" translatable="yes">Favorite</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="has-frame">0</property>
|
||||
|
@@ -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;
|
||||
}
|
@@ -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
@@ -1,3 +0,0 @@
|
||||
.view.compact > child {
|
||||
padding: 1px;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
listview.viewswitcher {
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
listview.viewswitcher > row {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
listview.viewswitcher row:selected {
|
||||
background: gray;
|
||||
}
|
@@ -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>
|
@@ -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;
|
||||
}
|
@@ -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>
|
@@ -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>
|
@@ -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 (¤t_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;
|
||||
}
|
@@ -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>
|
@@ -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 70 000 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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user