Compare commits
4 Commits
selection
...
shader-cac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8d497b83a | ||
|
|
37767e056f | ||
|
|
c7e1ab67c6 | ||
|
|
4a2e73a07c |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/subprojects/*/
|
||||
@@ -1,82 +1,43 @@
|
||||
stages:
|
||||
- build
|
||||
- flatpak
|
||||
- deploy
|
||||
|
||||
.cache-paths: &cache-paths
|
||||
paths:
|
||||
- _ccache/
|
||||
- subprojects/gdk-pixbuf/
|
||||
- subprojects/glib/
|
||||
- subprojects/graphene/
|
||||
- subprojects/libepoxy/
|
||||
- subprojects/pango/
|
||||
|
||||
fedora-x86_64:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v2
|
||||
gtk:
|
||||
image: ebassi/gitlab-gtk:latest
|
||||
stage: build
|
||||
before_script:
|
||||
- export CCACHE_DISABLE=true_
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/test-docker.sh
|
||||
cache:
|
||||
paths:
|
||||
- subprojects/gdk-pixbuf/
|
||||
- subprojects/glib/
|
||||
- subprojects/graphene/
|
||||
- subprojects/libepoxy/
|
||||
- subprojects/pango/
|
||||
artifacts:
|
||||
when: on_failure
|
||||
name: "gtk-${CI_COMMIT_REF_NAME}"
|
||||
paths:
|
||||
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
||||
cache:
|
||||
key: "$CI_JOB_NAME"
|
||||
<<: *cache-paths
|
||||
|
||||
.mingw-defaults: &mingw-defaults
|
||||
stage: build
|
||||
tags:
|
||||
- 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%"
|
||||
<<: *cache-paths
|
||||
|
||||
msys2-mingw32:
|
||||
variables:
|
||||
MSYSTEM: "MINGW32"
|
||||
CHERE_INVOKING: "yes"
|
||||
<<: *mingw-defaults
|
||||
|
||||
.flatpak-defaults: &flatpak-defaults
|
||||
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master
|
||||
stage: flatpak
|
||||
artifacts:
|
||||
paths:
|
||||
- "${APPID}-dev.flatpak"
|
||||
expire_in: 1 day
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
|
||||
|
||||
flatpak:demo:
|
||||
variables:
|
||||
APPID: org.gtk.Demo
|
||||
<<: *flatpak-defaults
|
||||
|
||||
flatpak:widget-factory:
|
||||
variables:
|
||||
APPID: org.gtk.WidgetFactory
|
||||
<<: *flatpak-defaults
|
||||
|
||||
pages:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v2
|
||||
stage: deploy
|
||||
image: registry.gitlab.com/alatiera/gnome-nightly-oci/gnome-master:latest
|
||||
stage: flatpak
|
||||
script:
|
||||
- meson -Ddocumentation=true _build .
|
||||
- ninja -C _build
|
||||
- ninja -C _build gdk4-doc gsk4-doc gtk4-doc
|
||||
|
||||
- mkdir -p public/
|
||||
- mv _build/docs/reference/gtk/html/ public/gtk/
|
||||
- mv _build/docs/reference/gdk/html/ public/gdk/
|
||||
- mv _build/docs/reference/gsk/html/ public/gsk/
|
||||
- bash -x ./.gitlab-ci/flatpak-build.sh org.gtk.Demo
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
only:
|
||||
- master
|
||||
- org.gtk.Demo-dev.flatpak
|
||||
expire_in: 1 day
|
||||
|
||||
flatpak:widget-factory:
|
||||
image: registry.gitlab.com/alatiera/gnome-nightly-oci/gnome-master:latest
|
||||
stage: flatpak
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/flatpak-build.sh org.gtk.WidgetFactory
|
||||
artifacts:
|
||||
paths:
|
||||
- org.gtk.WidgetFactory-dev.flatpak
|
||||
expire_in: 1 day
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
FROM fedora:29
|
||||
FROM fedora:27
|
||||
|
||||
RUN dnf -y install \
|
||||
hicolor-icon-theme \
|
||||
adwaita-icon-theme \
|
||||
atk-devel \
|
||||
at-spi2-atk-devel \
|
||||
@@ -29,11 +28,9 @@ RUN dnf -y install \
|
||||
gstreamer1-plugins-good \
|
||||
gstreamer1-plugins-bad-free-devel \
|
||||
gstreamer1-plugins-base-devel \
|
||||
gtk-doc \
|
||||
iso-codes \
|
||||
itstool \
|
||||
json-glib-devel \
|
||||
lcov \
|
||||
libattr-devel \
|
||||
libepoxy-devel \
|
||||
libffi-devel \
|
||||
@@ -70,7 +67,7 @@ RUN dnf -y install \
|
||||
xorg-x11-server-Xvfb \
|
||||
&& dnf clean all
|
||||
|
||||
RUN pip3 install meson==0.49.0
|
||||
RUN pip3 install meson
|
||||
|
||||
ARG HOST_USER_ID=5555
|
||||
ENV HOST_USER_ID ${HOST_USER_ID}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v2"
|
||||
TAG="ebassi/gitlab-gtk:latest"
|
||||
|
||||
sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \
|
||||
--file "Dockerfile" .
|
||||
|
||||
@@ -4,25 +4,16 @@ set -e
|
||||
|
||||
srcdir=$(pwd)
|
||||
|
||||
mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
|
||||
|
||||
ccache --zero-stats
|
||||
ccache --show-stats
|
||||
export CCACHE_DISABLE=true
|
||||
meson \
|
||||
-Dx11-backend=true \
|
||||
-Dwayland-backend=true \
|
||||
-Dbroadway-backend=true \
|
||||
-Dvulkan=yes \
|
||||
_build $srcdir
|
||||
unset CCACHE_DISABLE
|
||||
|
||||
cd _build
|
||||
|
||||
ninja
|
||||
ccache --show-stats
|
||||
|
||||
xvfb-run -a -s "-screen 0 1024x768x24" \
|
||||
meson test \
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
if [[ "$MSYSTEM" == "MINGW32" ]]; then
|
||||
export MSYS2_ARCH="i686"
|
||||
else
|
||||
export MSYS2_ARCH="x86_64"
|
||||
fi
|
||||
|
||||
# Update everything
|
||||
pacman --noconfirm -Suy
|
||||
|
||||
# Install the required packages
|
||||
pacman --noconfirm -S --needed \
|
||||
base-devel \
|
||||
git \
|
||||
mingw-w64-$MSYS2_ARCH-toolchain \
|
||||
mingw-w64-$MSYS2_ARCH-ccache \
|
||||
mingw-w64-$MSYS2_ARCH-pkg-config \
|
||||
mingw-w64-$MSYS2_ARCH-gobject-introspection \
|
||||
mingw-w64-$MSYS2_ARCH-meson \
|
||||
mingw-w64-$MSYS2_ARCH-adwaita-icon-theme \
|
||||
mingw-w64-$MSYS2_ARCH-atk \
|
||||
mingw-w64-$MSYS2_ARCH-cairo \
|
||||
mingw-w64-$MSYS2_ARCH-gdk-pixbuf2 \
|
||||
mingw-w64-$MSYS2_ARCH-glib2 \
|
||||
mingw-w64-$MSYS2_ARCH-graphene \
|
||||
mingw-w64-$MSYS2_ARCH-json-glib \
|
||||
mingw-w64-$MSYS2_ARCH-libepoxy \
|
||||
mingw-w64-$MSYS2_ARCH-pango \
|
||||
mingw-w64-$MSYS2_ARCH-fribidi \
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info
|
||||
|
||||
mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
|
||||
|
||||
# Build
|
||||
ccache --zero-stats
|
||||
ccache --show-stats
|
||||
export CCACHE_DISABLE=true
|
||||
meson \
|
||||
-Denable-x11-backend=false \
|
||||
-Denable-wayland-backend=false \
|
||||
-Denable-win32-backend=true \
|
||||
-Dvulkan=no \
|
||||
_build
|
||||
unset CCACHE_DISABLE
|
||||
|
||||
ninja -C _build
|
||||
ccache --show-stats
|
||||
@@ -23,14 +23,17 @@
|
||||
|
||||
## Version information
|
||||
<!--
|
||||
- Which version of GTK+ you are using
|
||||
- What operating system and version
|
||||
- For Linux, which distribution
|
||||
- If you built GTK+ yourself, the list of options used to configure the build
|
||||
- which version of GTK+ you are using
|
||||
- what operating system and version
|
||||
- for Linux, which distribution
|
||||
- if you built GTK+ yourself, the list of options used to configure the build
|
||||
-->
|
||||
|
||||
## Additional information
|
||||
<!--
|
||||
- Screenshots or screen recordings are useful for visual errors
|
||||
- Please report any warning or message printed on the terminal
|
||||
-->
|
||||
- If the bug was a crash, the exact text that was printed out
|
||||
when the crash occurred.
|
||||
- If the bug was a crash, attaching a stack trace obtained using
|
||||
GDB is appreciated; follow the instructions on the wiki:
|
||||
https://wiki.gnome.org/Community/GettingInTouch/Bugzilla/GettingTraces
|
||||
-->
|
||||
@@ -1,34 +0,0 @@
|
||||
## Steps to reproduce
|
||||
|
||||
1. ...
|
||||
2. ...
|
||||
3. ...
|
||||
|
||||
<!--
|
||||
You should try and reproduce with the demos applications available
|
||||
under the `demos` directory, or the test programs in the `tests` directory.
|
||||
Alternatively, please attach a *small and self-contained* example that
|
||||
exhibits the issue.
|
||||
-->
|
||||
|
||||
## Version information
|
||||
<!--
|
||||
- Which version of GTK+ you are using
|
||||
- What operating system and version
|
||||
- for Linux, which distribution
|
||||
- If you built GTK+ yourself, the list of options used to configure the build
|
||||
-->
|
||||
|
||||
## Warnings
|
||||
<!--
|
||||
- If the application generates warning messages before crashing please
|
||||
report them here
|
||||
-->
|
||||
|
||||
## Backtrace
|
||||
<!--
|
||||
- Attaching a stack trace obtained using GDB is appreciated; follow the
|
||||
instructions on the wiki:
|
||||
|
||||
https://wiki.gnome.org/Community/GettingInTouch/Bugzilla/GettingTraces
|
||||
-->
|
||||
241
CONTRIBUTING.md
241
CONTRIBUTING.md
@@ -1,144 +1,31 @@
|
||||
# Contribution guidelines
|
||||
|
||||
Thank you for considering contributing to the GTK project!
|
||||
|
||||
These guidelines are meant for new contributors, regardless of their level
|
||||
of proficiency; following them allows the maintainers of the GTK project to
|
||||
more effectively evaluate your contribution, and provide prompt feedback to
|
||||
you. Additionally, by following these guidelines you clearly communicate
|
||||
that you respect the time and effort that the people developing GTK put into
|
||||
managing the project.
|
||||
|
||||
GTK is a complex free software GUI toolkit, and it would not exist without
|
||||
contributions from the free and open source software community. There are
|
||||
many things that we value:
|
||||
|
||||
- bug reporting and fixing
|
||||
- documentation and examples
|
||||
- tests
|
||||
- new features
|
||||
|
||||
Please, do not use the issue tracker for support questions. If you have
|
||||
questions on how to use GTK effectively, you can use:
|
||||
|
||||
- the `#gtk` IRC channel on irc.gnome.org
|
||||
- the [gtk](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).
|
||||
|
||||
The issue tracker is meant to be used for actionable issues only.
|
||||
|
||||
## How to report bugs
|
||||
|
||||
### Security issues
|
||||
|
||||
You should not open a new issue for security related questions.
|
||||
|
||||
When in doubt, send an email to the [security](mailto:security@gnome.org)
|
||||
mailing list.
|
||||
|
||||
### Bug reports
|
||||
|
||||
If you're reporting a bug make sure to list:
|
||||
|
||||
0. which version of GTK are you using?
|
||||
0. which operating system are you using?
|
||||
0. the necessary steps to reproduce the issue
|
||||
0. the expected outcome
|
||||
0. a description of the behavior; screenshots are also welcome
|
||||
0. a small, self-contained example exhibiting the behavior; if this
|
||||
is not available, try reproducing the issue using the GTK examples
|
||||
or interactive tests
|
||||
|
||||
If the issue includes a crash, you should also include:
|
||||
|
||||
0. the eventual warnings printed on the terminal
|
||||
0. a backtrace, obtained with tools such as GDB or LLDB
|
||||
|
||||
For small issues, such as:
|
||||
|
||||
- spelling/grammar fixes in the documentation
|
||||
- typo correction
|
||||
- comment clean ups
|
||||
- changes to metadata files (CI, `.gitignore`)
|
||||
- build system changes
|
||||
- source tree clean ups and reorganizations
|
||||
|
||||
You should directly open a merge request instead of filing a new issue.
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
Feature discussion can be open ended and require high bandwidth channels; if
|
||||
you are proposing a new feature on the issue tracker, make sure to make
|
||||
an actionable proposal, and list:
|
||||
|
||||
0. what you're trying to achieve
|
||||
0. prior art, in other toolkits or applications
|
||||
0. design and theming changes
|
||||
|
||||
If you're proposing the integration of new features it helps to have
|
||||
multiple applications using shared or similar code, especially if they have
|
||||
iterated over it various times.
|
||||
|
||||
Each feature should also come fully documented, and with tests.
|
||||
|
||||
## Your first contribution
|
||||
|
||||
### Prerequisites
|
||||
|
||||
If you want to contribute to the GTK project, you will need to have the
|
||||
development tools appropriate for your operating system, including:
|
||||
If you want to hack on the GTK+ project, you'll need to have the development
|
||||
tools appropriate for your operating system, including:
|
||||
|
||||
- Python 3.x
|
||||
- Meson
|
||||
- Ninja
|
||||
- Gettext (19.7 or newer)
|
||||
- a [C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
|
||||
- a C99 compatible compiler
|
||||
|
||||
Up-to-date instructions about developing GNOME applications and libraries
|
||||
can be found on [the GNOME Developer Center](https://developer.gnome.org).
|
||||
can be found here:
|
||||
|
||||
The GTK project uses GitLab for code hosting and for tracking issues. More
|
||||
information about using GitLab can be found [on the GNOME
|
||||
wiki](https://wiki.gnome.org/GitLab).
|
||||
* https://developer.gnome.org
|
||||
|
||||
### Dependencies
|
||||
Information about using GitLab with GNOME can be found here:
|
||||
|
||||
In order to get GTK from Git installed on your system, you need to have the
|
||||
required versions of all the software dependencies required by GTK; typically,
|
||||
this means a recent version of GLib, Cairo, Pango, and ATK, as well as the
|
||||
platform-specific dependencies for the windowing system you are using (Wayland,
|
||||
X11, Windows, or macOS).
|
||||
* https://wiki.gnome.org/GitLab
|
||||
|
||||
The core dependencies for GTK are:
|
||||
|
||||
- [GLib, GObject, and GIO](https://gitlab.gnome.org/GNOME/glib)
|
||||
- [Cairo](http://cairographics.org)
|
||||
- [Pango](https://gitlab.gnome.org/GNOME/pango)
|
||||
- [GdkPixbuf](https://gitlab.gnome.org/GNOME/gdk-pixbuf)
|
||||
- [Epoxy](https://github.com/anholt/libepoxy)
|
||||
- [ATK](https://gitlab.gnome.org/GNOME/atk)
|
||||
- [Graphene](https://github.com/ebassi/graphene)
|
||||
|
||||
GTK will attempt to download and build some of these dependencies if it
|
||||
cannot find them on your system.
|
||||
|
||||
Additionally, you may want to look at projects that create a development
|
||||
environment for you, like [jhbuild](https://wiki.gnome.org/HowDoI/Jhbuild)
|
||||
and [gvsbuild](https://github.com/wingtk/gvsbuild).
|
||||
|
||||
### Getting started
|
||||
In order to get Git GTK+ installed on your system, you need to have the
|
||||
required versions of all the GTK+ dependencies; typically, this means a
|
||||
recent version of GLib, Cairo, Pango, and ATK, as well as the platform
|
||||
specific dependencies for the windowing system you are using (Wayland, X11,
|
||||
Windows, or macOS).
|
||||
|
||||
You should start by forking the GTK repository from the GitLab web UI, and
|
||||
cloning from your fork:
|
||||
|
||||
```sh
|
||||
```ssh
|
||||
$ git clone https://gitlab.gnome.org/yourusername/gtk.git
|
||||
$ cd gtk
|
||||
```
|
||||
@@ -151,7 +38,7 @@ $ git clone git@gitlab.gnome.org:GNOME/gtk.git
|
||||
$ cd gtk
|
||||
```
|
||||
|
||||
To compile the Git version of GTK on your system, you will need to
|
||||
To compile the Git version of GTK+ on your system, you will need to
|
||||
configure your build using Meson:
|
||||
|
||||
```sh
|
||||
@@ -160,6 +47,11 @@ $ cd _builddir
|
||||
$ ninja
|
||||
```
|
||||
|
||||
**Note**: For information about submitting patches and pushing changes
|
||||
to Git, see the `README.md` and `README.commits` files. In particular,
|
||||
don't, under any circumstances, push anything to Git before reading and
|
||||
understanding `README.commmits`.
|
||||
|
||||
Typically, you should work on your own branch:
|
||||
|
||||
```sh
|
||||
@@ -169,98 +61,3 @@ $ git checkout -b your-branch
|
||||
Once you've finished working on the bug fix or feature, push the branch
|
||||
to the Git repository and open a new merge request, to let the GTK
|
||||
maintainers review your contribution.
|
||||
|
||||
### Code reviews
|
||||
|
||||
Each contribution is reviewed by the core developers of the GTK project.
|
||||
|
||||
The [CODE-OWNERS](./docs/CODE-OWNERS) document contains the list of core
|
||||
contributors to GTK and the areas for which they are responsible; you
|
||||
should ensure to receive their review and signoff on your changes.
|
||||
|
||||
### Commit messages
|
||||
|
||||
The expected format for git commit messages is as follows:
|
||||
|
||||
```plain
|
||||
Short explanation of the commit
|
||||
|
||||
Longer explanation explaining exactly what's changed, whether any
|
||||
external or private interfaces changed, what bugs were fixed (with bug
|
||||
tracker reference if applicable) and so forth. Be concise but not too
|
||||
brief.
|
||||
|
||||
Closes #1234
|
||||
```
|
||||
|
||||
- Always add a brief description of the commit to the _first_ line of
|
||||
the commit and terminate by two newlines (it will work without the
|
||||
second newline, but that is not nice for the interfaces).
|
||||
|
||||
- First line (the brief description) must only be one sentence and
|
||||
should start with a capital letter unless it starts with a lowercase
|
||||
symbol or identifier. Don't use a trailing period either. Don't exceed
|
||||
72 characters.
|
||||
|
||||
- The main description (the body) is normal prose and should use normal
|
||||
punctuation and capital letters where appropriate. Consider the commit
|
||||
message as an email sent to the developers (or yourself, six months
|
||||
down the line) detailing **why** you changed something. There's no need
|
||||
to specify the **how**: the changes can be inlined.
|
||||
|
||||
- When committing code on behalf of others use the `--author` option, e.g.
|
||||
`git commit -a --author "Joe Coder <joe@coder.org>"` and `--signoff`.
|
||||
|
||||
- If your commit is addressing an issue, use the
|
||||
[GitLab syntax](https://docs.gitlab.com/ce/user/project/issues/automatic_issue_closing.html)
|
||||
to automatically close the issue when merging the commit with the upstream
|
||||
repository:
|
||||
|
||||
```plain
|
||||
Closes #1234
|
||||
Fixes #1234
|
||||
Closes: https://gitlab.gnome.org/GNOME/gtk/issues/1234
|
||||
```
|
||||
|
||||
- If you have a merge request with multiple commits and none of them
|
||||
completely fixes an issue, you should add a reference to the issue in
|
||||
the commit message, e.g. `Bug: #1234`, and use the automatic issue
|
||||
closing syntax in the description of the merge request.
|
||||
|
||||
### Commit access to the GTK repository
|
||||
|
||||
GTK is part of the GNOME infrastructure. At the current time, any
|
||||
person with write access to the GNOME repository can merge changes to
|
||||
GTK. This is a good thing, in that it encourages many people to work
|
||||
on GTK, and progress can be made quickly. However, GTK is a fairly
|
||||
large and complicated project on which many other things depend, so to
|
||||
avoid unnecessary breakage, and to take advantage of the knowledge
|
||||
about GTK that has been built up over the years, we'd like to ask
|
||||
people committing to GTK to follow a few rules:
|
||||
|
||||
0. Ask first. If your changes are major, or could possibly break existing
|
||||
code, you should always ask. If your change is minor and you've been
|
||||
working on GTK for a while it probably isn't necessary to ask. But when
|
||||
in doubt, ask. Even if your change is correct, somebody may know a
|
||||
better way to do things. If you are making changes to GTK, you should
|
||||
be subscribed to the [gtk-devel](https://mail.gnome.org/mailman/listinfo/gtk-devel-list)
|
||||
mailing list; this is a good place to ask about intended changes.
|
||||
The `#gtk` IRC channel on irc.gnome.org is also a good place to find GTK
|
||||
developers to discuss changes, but if you live outside of the EU/US time
|
||||
zones, an email to the gtk-devel mailing list is the most certain and
|
||||
preferred method.
|
||||
|
||||
0. Ask _first_.
|
||||
|
||||
0. Always write a meaningful commit message. Changes without a sufficient
|
||||
commit message will be reverted.
|
||||
|
||||
0. Never push to the `master` branch, or any stable branches, directly; you
|
||||
should always go through a merge request, to ensure that the code is
|
||||
tested on the CI infrastructure at the very least. A merge request is
|
||||
also the proper place to get a comprehensive code review from the core
|
||||
developers of GTK.
|
||||
|
||||
If you have been contributing to GTK for a while and you don't have commit
|
||||
access to the repository, you may ask to obtain it following the [GNOME account
|
||||
process](https://wiki.gnome.org/AccountsTeam/NewAccounts).
|
||||
|
||||
88
NEWS
88
NEWS
@@ -1,91 +1,3 @@
|
||||
Overview of Changes in GTK+ 3.94.0
|
||||
==================================
|
||||
|
||||
* GdkPaintable is a new, powerful abstraction for drawable content.
|
||||
gtk4-demo has a new "Paint" demo to show some of its capabilities.
|
||||
|
||||
* There is support for displaying media, with
|
||||
GtkVideo
|
||||
GtkMediaFile
|
||||
GtkMediaStream
|
||||
GtkMediaControls
|
||||
|
||||
* GtkFontChooser now supports OpenType font variations and features.
|
||||
|
||||
* The Ctrl-Shift-E support in the simple IM context has been replaced
|
||||
by an optional completion popup for Emoji alpha codes. This can be
|
||||
enabled with the GtkEntry::enable-emoji-completion property.
|
||||
|
||||
* Wayland has an input method based on the text protocol now
|
||||
|
||||
* Input methods, print backends and media backends have been converted
|
||||
to GIOModules and extension points, and support for generic loadable
|
||||
modules has been dropped. Platform im modules are always included.
|
||||
|
||||
* GdkWindow has been renamed to GdkSurface.
|
||||
|
||||
* Applications can now create their own GtkSnapshot objects for
|
||||
intermediate rendering.
|
||||
|
||||
* Widget event signals have been replaced by event controllers,
|
||||
and some new event controllers have been introduced for this:
|
||||
GtkEventControllerMotion
|
||||
GtkEventControllerKey
|
||||
GtkGestureStylus
|
||||
|
||||
* Event controllers can now be created in .ui files.
|
||||
|
||||
* Invalidation tracking has been changed, only gtk_widget_queue_draw is left.
|
||||
|
||||
* Observing widget contents and size is now done by using the
|
||||
GtkWidgetPaintable object instead of connecting to widget signals.
|
||||
|
||||
* The GtkWidget::draw signal has been removed, widgets need
|
||||
to implement GtkWidget::snapshot.
|
||||
|
||||
* GdkTexture now has GdkMemoryTexture and GdkGLTexture subclasses.
|
||||
|
||||
* The Vulkan support in GDK can now use a particular device that is
|
||||
specified by the GDK_VULKAN_DEVICE environment variable. use
|
||||
GDK_VULKAN_DEVICE=list to see them all.
|
||||
|
||||
* GTK+ Inspector
|
||||
- has logging support, and the logging settings have been cleaned up
|
||||
- has an fps overlay
|
||||
|
||||
* Removed APIs and features:
|
||||
Individual event signals such as ::proximity-in-event
|
||||
The ::draw signal
|
||||
threading support
|
||||
non-platform IM modules
|
||||
papi and test print backends
|
||||
GtkPlacesSidebar
|
||||
GtkRecentChooser
|
||||
GtkToolPalette
|
||||
GdkStatus
|
||||
gtk_true, gtk_false
|
||||
gtk_widget_show_now
|
||||
gtk_widget_draw
|
||||
gtk_render_icon_surface
|
||||
|
||||
* Incomplete transitions:
|
||||
The ::event signal is not still there, but it will be removed
|
||||
The DND apis are not finalized yet
|
||||
|
||||
* Translation updates:
|
||||
Croatian
|
||||
Esperanto
|
||||
Estonian
|
||||
French
|
||||
Friulian
|
||||
Icelandic
|
||||
Latvian
|
||||
Polish
|
||||
Russian
|
||||
Scottish Gaelic
|
||||
Spanish
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.93.0
|
||||
==================================
|
||||
|
||||
|
||||
72
README.commits
Normal file
72
README.commits
Normal file
@@ -0,0 +1,72 @@
|
||||
GTK+ is part of the GNOME git repository. At the current time, any
|
||||
person with write access to the GNOME repository, can make changes to
|
||||
GTK+. This is a good thing, in that it encourages many people to work
|
||||
on GTK+, and progress can be made quickly. However, GTK+ is a fairly
|
||||
large and complicated package that many other things depend on, so to
|
||||
avoid unnecessary breakage, and to take advantage of the knowledge
|
||||
about GTK+ that has been built up over the years, we'd like to ask
|
||||
people committing to GTK+ to follow a few rules:
|
||||
|
||||
0) Ask first. If your changes are major, or could possibly break existing
|
||||
code, you should always ask. If your change is minor and you've
|
||||
been working on GTK+ for a while it probably isn't necessary
|
||||
to ask. But when in doubt, ask. Even if your change is correct,
|
||||
somebody may know a better way to do things.
|
||||
|
||||
If you are making changes to GTK+, you should be subscribed
|
||||
to gtk-devel-list@gnome.org. (Subscription address:
|
||||
gtk-devel-list-request@gnome.org.) This is a good place to ask
|
||||
about intended changes.
|
||||
|
||||
#gtk+ on GIMPNet (irc.gimp.org, irc.us.gimp.org, irc.eu.gimp.org, ...)
|
||||
is also a good place to find GTK+ developers to discuss changes with,
|
||||
however, email to gtk-devel-list is the most certain and preferred
|
||||
method.
|
||||
|
||||
1) Ask _first_.
|
||||
|
||||
2) With git, we no longer maintain a ChangeLog file, but you are expected
|
||||
to produce a meaningful commit message. Changes without a sufficient
|
||||
commit message will be reverted. See below for the expected format
|
||||
of commit messages.
|
||||
|
||||
Notes:
|
||||
|
||||
* When developing larger features or complicated bug fixes, it is
|
||||
advisable to work in a branch in your own cloned GTK+ repository.
|
||||
You may even consider making your repository publically available
|
||||
so that others can easily test and review your changes.
|
||||
|
||||
* The expected format for git commit messages is as follows:
|
||||
|
||||
=== begin example commit ===
|
||||
Short explanation of the commit
|
||||
|
||||
Longer explanation explaining exactly what's changed, whether any
|
||||
external or private interfaces changed, what bugs were fixed (with bug
|
||||
tracker reference if applicable) and so forth. Be concise but not too brief.
|
||||
=== end example commit ===
|
||||
|
||||
- Always add a brief description of the commit to the _first_ line of
|
||||
the commit and terminate by two newlines (it will work without the
|
||||
second newline, but that is not nice for the interfaces).
|
||||
|
||||
- First line (the brief description) must only be one sentence and
|
||||
should start with a capital letter unless it starts with a lowercase
|
||||
symbol or identifier. Don't use a trailing period either. Don't exceed
|
||||
72 characters.
|
||||
|
||||
- The main description (the body) is normal prose and should use normal
|
||||
punctuation and capital letters where appropriate. Normally, for patches
|
||||
sent to a mailing list it's copied from there.
|
||||
|
||||
- When committing code on behalf of others use the --author option, e.g.
|
||||
git commit -a --author "Joe Coder <joe@coder.org>" and --signoff.
|
||||
|
||||
|
||||
Owen Taylor
|
||||
13 Aug 1998
|
||||
17 Apr 2001
|
||||
|
||||
Matthias Clasen
|
||||
31 Mar 2009
|
||||
31
README.md
31
README.md
@@ -1,17 +1,17 @@
|
||||
GTK — The GTK toolkit
|
||||
=====================
|
||||
GTK+ — The GTK toolkit
|
||||
======================
|
||||
|
||||
[](https://gitlab.gnome.org/GNOME/gtk/pipelines)
|
||||
|
||||
General information
|
||||
-------------------
|
||||
|
||||
GTK is a multi-platform toolkit for creating graphical user interfaces.
|
||||
Offering a complete set of widgets, GTK is suitable for projects ranging
|
||||
GTK+ is a multi-platform toolkit for creating graphical user interfaces.
|
||||
Offering a complete set of widgets, GTK+ is suitable for projects ranging
|
||||
from small one-off projects to complete application suites.
|
||||
|
||||
GTK is free software and part of the GNU Project. However, the
|
||||
licensing terms for GTK, the GNU LGPL, allow it to be used by all
|
||||
GTK+ is free software and part of the GNU Project. However, the
|
||||
licensing terms for GTK+, the GNU LGPL, allow it to be used by all
|
||||
developers, including those developing proprietary software, without any
|
||||
license fees or royalties.
|
||||
|
||||
@@ -31,15 +31,10 @@ Information about mailing lists can be found at
|
||||
|
||||
- http://www.gtk.org/mailing-lists.php
|
||||
|
||||
Nightly documentation can be found at
|
||||
- Gtk: https://gnome.pages.gitlab.gnome.org/gtk/gtk/
|
||||
- Gdk: https://gnome.pages.gitlab.gnome.org/gtk/gdk/
|
||||
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk/
|
||||
|
||||
Building and installing
|
||||
-----------------------
|
||||
|
||||
In order to build GTK you will need:
|
||||
In order to build GTK+ you will need:
|
||||
|
||||
- [a C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
|
||||
- [Python 3](https://www.python.org/)
|
||||
@@ -79,7 +74,7 @@ If you are building the Wayland backend, you will also need:
|
||||
- Wayland-cursor
|
||||
- Wayland-EGL
|
||||
|
||||
Once you have all the necessary dependencies, you can build GTK by using
|
||||
Once you have all the necessary dependencies, you can build GTK+ by using
|
||||
Meson:
|
||||
|
||||
```sh
|
||||
@@ -94,7 +89,7 @@ You can run the test suite using:
|
||||
$ meson test
|
||||
```
|
||||
|
||||
And, finally, you can install GTK using:
|
||||
And, finally, you can install GTK+ using:
|
||||
|
||||
```
|
||||
$ sudo ninja install
|
||||
@@ -118,10 +113,10 @@ In the bug report please include:
|
||||
|
||||
* Information about your system. For instance:
|
||||
|
||||
- which version of GTK you are using
|
||||
- which version of GTK+ you are using
|
||||
- what operating system and version
|
||||
- for Linux, which distribution
|
||||
- if you built GTK, the list of options used to configure the build
|
||||
- if you built GTK+, the list of options used to configure the build
|
||||
|
||||
And anything else you think is relevant.
|
||||
|
||||
@@ -143,7 +138,7 @@ In the bug report please include:
|
||||
Release notes
|
||||
-------------
|
||||
|
||||
The release notes for GTK are part of the migration guide in the API
|
||||
The release notes for GTK+ are part of the migration guide in the API
|
||||
reference. See:
|
||||
|
||||
- [3.x release notes](https://developer.gnome.org/gtk3/unstable/gtk-migrating-2-to-3.html)
|
||||
@@ -152,7 +147,7 @@ reference. See:
|
||||
Licensing terms
|
||||
---------------
|
||||
|
||||
GTK is released under the terms of the GNU Lesser General Public License,
|
||||
GTK+ is released under the terms of the GNU Lesser General Public License,
|
||||
version 2.1 or, at your option, any later version, as published by the Free
|
||||
Software Foundation.
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "gtk4-demo",
|
||||
"tags": ["devel", "development", "nightly"],
|
||||
"rename-desktop-file": "gtk4-demo.desktop",
|
||||
"rename-icon": "gtk4-demo",
|
||||
"desktop-file-name-prefix": "(Development) ",
|
||||
"finish-args": [
|
||||
@@ -26,28 +27,12 @@
|
||||
"/share/doc"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name" : "wayland",
|
||||
"buildsystem" : "autotools",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--disable-documentation"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/wayland-project/wayland.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "graphene",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false",
|
||||
"-Dbenchmarks=false"
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "gtk4-widget-factory",
|
||||
"tags": ["devel", "development", "nightly"],
|
||||
"rename-desktop-file": "gtk4-widget-factory.desktop",
|
||||
"rename-icon": "gtk4-widget-factory",
|
||||
"desktop-file-name-prefix": "(Development) ",
|
||||
"finish-args": [
|
||||
@@ -26,28 +27,12 @@
|
||||
"/share/doc"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name" : "wayland",
|
||||
"buildsystem" : "autotools",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--disable-documentation"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/wayland-project/wayland.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "graphene",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false",
|
||||
"-Dbenchmarks=false"
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
|
||||
@@ -286,10 +286,6 @@
|
||||
/* Define to 1 if linux/memfd.h exists */
|
||||
#mesondefine HAVE_LINUX_MEMFD_H
|
||||
|
||||
#mesondefine HAVE_LINUX_INPUT_H
|
||||
|
||||
#mesondefine HAVE_DEV_EVDEV_INPUT_H
|
||||
|
||||
#mesondefine GTK_SYSCONFDIR
|
||||
|
||||
#mesondefine GTK_LOCALEDIR
|
||||
@@ -305,13 +301,3 @@
|
||||
#mesondefine HAVE_PANGOFT
|
||||
|
||||
#mesondefine ISO_CODES_PREFIX
|
||||
|
||||
#mesondefine MALLOC_IS_ALIGNED16
|
||||
|
||||
#mesondefine HAVE_POSIX_MEMALIGN
|
||||
|
||||
#mesondefine HAVE_MEMALIGN
|
||||
|
||||
#mesondefine HAVE_ALIGNED_ALLOC
|
||||
|
||||
#mesondefine HAVE__ALIGNED_MALLOC
|
||||
|
||||
@@ -200,20 +200,20 @@ activate_about (GSimpleAction *action,
|
||||
};
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (window),
|
||||
"program-name", "GTK Code Demos",
|
||||
"version", g_strdup_printf ("%s,\nRunning against GTK %d.%d.%d",
|
||||
"program-name", "GTK+ Code Demos",
|
||||
"version", g_strdup_printf ("%s,\nRunning against GTK+ %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ()),
|
||||
"copyright", "(C) 1997-2013 The GTK Team",
|
||||
"copyright", "(C) 1997-2013 The GTK+ Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK functions.",
|
||||
"comments", "Program to demonstrate GTK+ functions.",
|
||||
"authors", authors,
|
||||
"documenters", documentors,
|
||||
"logo-icon-name", "gtk4-demo",
|
||||
"title", "About GTK Code Demos",
|
||||
"title", "About GTK+ Code Demos",
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -455,17 +455,15 @@ demo_application_window_constructed (GObject *object)
|
||||
}
|
||||
|
||||
static void
|
||||
demo_application_window_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
demo_application_window_size_allocate (GtkWidget *widget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip)
|
||||
{
|
||||
DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
|
||||
|
||||
GTK_WIDGET_CLASS (demo_application_window_parent_class)->size_allocate (widget,
|
||||
width,
|
||||
height,
|
||||
baseline);
|
||||
GTK_WIDGET_CLASS (demo_application_window_parent_class)->size_allocate (widget, allocation,
|
||||
baseline, out_clip);
|
||||
|
||||
if (!window->maximized && !window->fullscreen)
|
||||
gtk_window_get_size (GTK_WINDOW (window), &window->width, &window->height);
|
||||
|
||||
@@ -96,12 +96,12 @@ create_page1 (GtkWidget *assistant)
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
||||
|
||||
label = gtk_label_new ("You must fill out this entry to continue:");
|
||||
gtk_container_add (GTK_CONTAINER (box), label);
|
||||
gtk_box_pack_start (GTK_BOX (box), label);
|
||||
|
||||
entry = gtk_entry_new ();
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
||||
gtk_widget_set_valign (entry, GTK_ALIGN_CENTER);
|
||||
gtk_container_add (GTK_CONTAINER (box), entry);
|
||||
gtk_box_pack_start (GTK_BOX (box), entry);
|
||||
g_signal_connect (G_OBJECT (entry), "changed",
|
||||
G_CALLBACK (on_entry_changed), assistant);
|
||||
|
||||
@@ -119,7 +119,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_container_add (GTK_CONTAINER (box), checkbutton);
|
||||
gtk_box_pack_start (GTK_BOX (box), checkbutton);
|
||||
|
||||
gtk_assistant_append_page (GTK_ASSISTANT (assistant), box);
|
||||
gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), box, TRUE);
|
||||
|
||||
127
demos/gtk-demo/button_box.c
Normal file
127
demos/gtk-demo/button_box.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/* Button Boxes
|
||||
*
|
||||
* The Button Box widgets are used to arrange buttons with padding.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkWidget *
|
||||
create_bbox (gint horizontal,
|
||||
char *title,
|
||||
gint spacing,
|
||||
gint layout)
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *bbox;
|
||||
GtkWidget *button;
|
||||
|
||||
frame = gtk_frame_new (title);
|
||||
|
||||
if (horizontal)
|
||||
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
else
|
||||
bbox = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
g_object_set (bbox, "margin", 5, NULL);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (frame), bbox);
|
||||
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), layout);
|
||||
gtk_box_set_spacing (GTK_BOX (bbox), spacing);
|
||||
|
||||
button = gtk_button_new_with_label (_("OK"));
|
||||
gtk_container_add (GTK_CONTAINER (bbox), button);
|
||||
|
||||
button = gtk_button_new_with_label (_("Cancel"));
|
||||
gtk_container_add (GTK_CONTAINER (bbox), button);
|
||||
|
||||
button = gtk_button_new_with_label (_("Help"));
|
||||
gtk_container_add (GTK_CONTAINER (bbox), button);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_button_box (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *main_vbox;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *frame_horz;
|
||||
GtkWidget *frame_vert;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Button Boxes");
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed),
|
||||
&window);
|
||||
|
||||
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
g_object_set (main_vbox, "margin", 10, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), main_vbox);
|
||||
|
||||
frame_horz = gtk_frame_new ("Horizontal Button Boxes");
|
||||
gtk_widget_set_margin_top (frame_horz, 10);
|
||||
gtk_widget_set_margin_bottom (frame_horz, 10);
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), frame_horz);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
g_object_set (vbox, "margin", 10, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (frame_horz), vbox);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
create_bbox (TRUE, "Spread", 40, GTK_BUTTONBOX_SPREAD));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
create_bbox (TRUE, "Edge", 40, GTK_BUTTONBOX_EDGE));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
create_bbox (TRUE, "Start", 40, GTK_BUTTONBOX_START));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
create_bbox (TRUE, "End", 40, GTK_BUTTONBOX_END));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
create_bbox (TRUE, "Center", 40, GTK_BUTTONBOX_CENTER));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
create_bbox (TRUE, "Expand", 0, GTK_BUTTONBOX_EXPAND));
|
||||
|
||||
frame_vert = gtk_frame_new ("Vertical Button Boxes");
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), frame_vert);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
g_object_set (hbox, "margin", 10, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (frame_vert), hbox);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox),
|
||||
create_bbox (FALSE, "Spread", 10, GTK_BUTTONBOX_SPREAD));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox),
|
||||
create_bbox (FALSE, "Edge", 10, GTK_BUTTONBOX_EDGE));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox),
|
||||
create_bbox (FALSE, "Start", 10, GTK_BUTTONBOX_START));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox),
|
||||
create_bbox (FALSE, "End", 10, GTK_BUTTONBOX_END));
|
||||
gtk_box_pack_start (GTK_BOX (hbox),
|
||||
create_bbox (FALSE, "Center", 10, GTK_BUTTONBOX_CENTER));
|
||||
gtk_box_pack_start (GTK_BOX (hbox),
|
||||
create_bbox (FALSE, "Expand", 0, GTK_BUTTONBOX_EXPAND));
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
* computers, as long as there is a network connection to the
|
||||
* computer where the application is running.
|
||||
*
|
||||
* Only some of the windowing systems where GTK runs have the
|
||||
* Only some of the windowing systems where GTK+ runs have the
|
||||
* concept of multiple displays. (The X Window System is the
|
||||
* main example.) Other windowing systems can only handle one
|
||||
* keyboard and mouse, and combine all monitors into
|
||||
@@ -87,14 +87,14 @@ find_toplevel_at_pointer (GdkDisplay *display)
|
||||
return widget ? gtk_widget_get_toplevel (widget) : NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
released_cb (GtkGestureMultiPress *gesture,
|
||||
guint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gboolean *clicked)
|
||||
static gboolean
|
||||
release_event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
gboolean *clicked)
|
||||
{
|
||||
*clicked = TRUE;
|
||||
if (gdk_event_get_event_type (event) == GDK_BUTTON_RELEASE)
|
||||
*clicked = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Asks the user to click on a window, then waits for them click
|
||||
@@ -132,12 +132,10 @@ query_for_toplevel (GdkDisplay *display,
|
||||
GDK_SEAT_CAPABILITY_ALL_POINTING,
|
||||
FALSE, cursor, NULL, NULL, NULL) == GDK_GRAB_SUCCESS)
|
||||
{
|
||||
GtkGesture *gesture = gtk_gesture_multi_press_new ();
|
||||
gboolean clicked = FALSE;
|
||||
|
||||
g_signal_connect (gesture, "released",
|
||||
G_CALLBACK (released_cb), &clicked);
|
||||
gtk_widget_add_controller (popup, GTK_EVENT_CONTROLLER (gesture));
|
||||
g_signal_connect (popup, "event",
|
||||
G_CALLBACK (release_event_cb), &clicked);
|
||||
|
||||
/* Process events until clicked is set by our button release event handler.
|
||||
* We pass in may_block=TRUE since we want to wait if there
|
||||
@@ -146,8 +144,6 @@ query_for_toplevel (GdkDisplay *display,
|
||||
while (!clicked)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
gdk_seat_ungrab (gdk_device_get_seat (device));
|
||||
|
||||
toplevel = find_toplevel_at_pointer (display);
|
||||
if (toplevel == popup)
|
||||
toplevel = NULL;
|
||||
@@ -315,7 +311,7 @@ create_frame (ChangeDisplayInfo *info,
|
||||
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin),
|
||||
GTK_SHADOW_IN);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), scrollwin);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), scrollwin);
|
||||
|
||||
*tree_view = gtk_tree_view_new ();
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (*tree_view), FALSE);
|
||||
@@ -325,7 +321,7 @@ create_frame (ChangeDisplayInfo *info,
|
||||
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
|
||||
|
||||
*button_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), *button_vbox);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), *button_vbox);
|
||||
|
||||
if (!info->size_group)
|
||||
info->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
||||
@@ -365,11 +361,11 @@ create_display_frame (ChangeDisplayInfo *info)
|
||||
|
||||
button = left_align_button_new ("_Open...");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (open_display_cb), info);
|
||||
gtk_container_add (GTK_CONTAINER (button_vbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (button_vbox), button);
|
||||
|
||||
button = left_align_button_new ("_Close");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (close_display_cb), info);
|
||||
gtk_container_add (GTK_CONTAINER (button_vbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (button_vbox), button);
|
||||
|
||||
info->display_model = (GtkTreeModel *)gtk_list_store_new (DISPLAY_NUM_COLUMNS,
|
||||
G_TYPE_STRING,
|
||||
@@ -542,10 +538,10 @@ do_changedisplay (GtkWidget *do_widget)
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
||||
g_object_set (vbox, "margin", 8, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), vbox);
|
||||
gtk_box_pack_start (GTK_BOX (content_area), vbox);
|
||||
|
||||
frame = create_display_frame (info);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
initialize_displays (info);
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ get_image_paintable (GtkImage *image)
|
||||
|
||||
static void
|
||||
drag_begin (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GdkDragContext *context,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
@@ -128,16 +128,17 @@ drag_begin (GtkWidget *widget,
|
||||
paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
if (paintable)
|
||||
{
|
||||
gtk_drag_set_icon_paintable (drag, paintable, -2, -2);
|
||||
gtk_drag_set_icon_paintable (context, paintable, -2, -2);
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GdkDragContext *context,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
@@ -149,8 +150,9 @@ drag_data_get (GtkWidget *widget,
|
||||
|
||||
static void
|
||||
drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GdkDragContext *context,
|
||||
GtkSelectionData *selection_data,
|
||||
guint32 time,
|
||||
gpointer data)
|
||||
{
|
||||
if (gtk_selection_data_get_length (selection_data) > 0)
|
||||
@@ -259,45 +261,45 @@ do_clipboard (GtkWidget *do_widget)
|
||||
|
||||
label = gtk_label_new ("\"Copy\" will copy the text\nin the entry to the clipboard");
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
g_object_set (hbox, "margin", 8, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||
|
||||
/* Create the first entry */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_container_add (GTK_CONTAINER (hbox), entry);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), entry);
|
||||
|
||||
/* Create the button */
|
||||
button = gtk_button_new_with_mnemonic (_("_Copy"));
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (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_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
g_object_set (hbox, "margin", 8, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||
|
||||
/* Create the second entry */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_container_add (GTK_CONTAINER (hbox), entry);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), entry);
|
||||
|
||||
/* Create the button */
|
||||
button = gtk_button_new_with_mnemonic (_("_Paste"));
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (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_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
g_object_set (hbox, "margin", 8, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||
|
||||
/* Create the first image */
|
||||
image = gtk_image_new_from_icon_name ("dialog-warning");
|
||||
@@ -319,10 +321,10 @@ do_clipboard (GtkWidget *do_widget)
|
||||
G_CALLBACK (drag_data_received), image);
|
||||
|
||||
/* context menu on image */
|
||||
gesture = gtk_gesture_multi_press_new ();
|
||||
gesture = gtk_gesture_multi_press_new (image);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
g_object_set_data_full (G_OBJECT (image), "gesture", gesture, g_object_unref);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
/* Create the second image */
|
||||
image = gtk_image_new_from_icon_name ("process-stop");
|
||||
@@ -344,10 +346,10 @@ do_clipboard (GtkWidget *do_widget)
|
||||
G_CALLBACK (drag_data_received), image);
|
||||
|
||||
/* context menu on image */
|
||||
gesture = gtk_gesture_multi_press_new ();
|
||||
gesture = gtk_gesture_multi_press_new (image);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
g_object_set_data_full (G_OBJECT (image), "gesture", gesture, g_object_unref);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Color Chooser
|
||||
*
|
||||
* A GtkColorChooser lets the user choose a color. There are several
|
||||
* implementations of the GtkColorChooser interface in GTK. The
|
||||
* implementations of the GtkColorChooser interface in GTK+. The
|
||||
* GtkColorChooserDialog is a prebuilt dialog containing a
|
||||
* GtkColorChooserWidget.
|
||||
*/
|
||||
@@ -88,7 +88,7 @@ do_colorsel (GtkWidget *do_widget)
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
da = gtk_drawing_area_new ();
|
||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 200);
|
||||
@@ -101,7 +101,7 @@ do_colorsel (GtkWidget *do_widget)
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), button);
|
||||
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (change_color_callback), NULL);
|
||||
|
||||
@@ -144,7 +144,7 @@ create_capital_store (void)
|
||||
{ NULL, "Jackson" },
|
||||
{ NULL, "Jefferson City" },
|
||||
{ NULL, "Juneau" },
|
||||
{ "K - O", NULL },
|
||||
{ "K - O" },
|
||||
{ NULL, "Lansing" },
|
||||
{ NULL, "Lincoln" },
|
||||
{ NULL, "Little Rock" },
|
||||
@@ -154,7 +154,7 @@ create_capital_store (void)
|
||||
{ NULL, "Nashville" },
|
||||
{ NULL, "Oklahoma City" },
|
||||
{ NULL, "Olympia" },
|
||||
{ "P - S", NULL },
|
||||
{ NULL, "P - S" },
|
||||
{ NULL, "Phoenix" },
|
||||
{ NULL, "Pierre" },
|
||||
{ NULL, "Providence" },
|
||||
@@ -326,7 +326,7 @@ do_combobox (GtkWidget *do_widget)
|
||||
* insensitive rows
|
||||
*/
|
||||
frame = gtk_frame_new ("Items with icons");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
g_object_set (box, "margin", 5, NULL);
|
||||
@@ -367,7 +367,7 @@ do_combobox (GtkWidget *do_widget)
|
||||
/* A combobox demonstrating trees.
|
||||
*/
|
||||
frame = gtk_frame_new ("Where are we ?");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
g_object_set (box, "margin", 5, NULL);
|
||||
@@ -395,7 +395,7 @@ do_combobox (GtkWidget *do_widget)
|
||||
|
||||
/* A GtkComboBoxEntry with validation */
|
||||
frame = gtk_frame_new ("Editable");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
g_object_set (box, "margin", 5, NULL);
|
||||
@@ -413,7 +413,7 @@ do_combobox (GtkWidget *do_widget)
|
||||
|
||||
/* A combobox with string IDs */
|
||||
frame = gtk_frame_new ("String IDs");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
g_object_set (box, "margin", 5, NULL);
|
||||
|
||||
@@ -105,6 +105,9 @@
|
||||
<file>gnome-fs-directory.png</file>
|
||||
<file>gnome-fs-regular.png</file>
|
||||
</gresource>
|
||||
<gresource prefix="/stack">
|
||||
<file>stack.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/shortcuts">
|
||||
<file>shortcuts.ui</file>
|
||||
<file>shortcuts-builder.ui</file>
|
||||
@@ -112,14 +115,6 @@
|
||||
<file>shortcuts-clocks.ui</file>
|
||||
<file>shortcuts-boxes.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/sliding_puzzle">
|
||||
<file>puzzlepiece.c</file>
|
||||
<file>puzzlepiece.h</file>
|
||||
<file>portland-rose.jpg</file>
|
||||
</gresource>
|
||||
<gresource prefix="/stack">
|
||||
<file>stack.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/revealer">
|
||||
<file>revealer.ui</file>
|
||||
</gresource>
|
||||
@@ -143,6 +138,7 @@
|
||||
<file>application_demo.c</file>
|
||||
<file>assistant.c</file>
|
||||
<file>builder.c</file>
|
||||
<file>button_box.c</file>
|
||||
<file>changedisplay.c</file>
|
||||
<file>clipboard.c</file>
|
||||
<file>colorsel.c</file>
|
||||
@@ -160,9 +156,11 @@
|
||||
<file>editable_cells.c</file>
|
||||
<file>entry_buffer.c</file>
|
||||
<file>entry_completion.c</file>
|
||||
<file>event_axes.c</file>
|
||||
<file>expander.c</file>
|
||||
<file>filtermodel.c</file>
|
||||
<file>fishbowl.c</file>
|
||||
<file>widgetbowl.c</file>
|
||||
<file>flowbox.c</file>
|
||||
<file>foreigndrawing.c</file>
|
||||
<file>font_features.c</file>
|
||||
@@ -183,7 +181,6 @@
|
||||
<file>modelbutton.c</file>
|
||||
<file>overlay.c</file>
|
||||
<file>overlay2.c</file>
|
||||
<file>paint.c</file>
|
||||
<file>pagesetup.c</file>
|
||||
<file>paintable.c</file>
|
||||
<file>paintable_animated.c</file>
|
||||
@@ -201,7 +198,6 @@
|
||||
<file>shortcuts.c</file>
|
||||
<file>sizegroup.c</file>
|
||||
<file>sidebar.c</file>
|
||||
<file>sliding_puzzle.c</file>
|
||||
<file>stack.c</file>
|
||||
<file>spinbutton.c</file>
|
||||
<file>spinner.c</file>
|
||||
|
||||
@@ -199,6 +199,9 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
@@ -252,10 +255,16 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStatusbar" id="statusbar1">
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -56,16 +56,16 @@ interactive_dialog_clicked (GtkButton *button,
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (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);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), image);
|
||||
|
||||
table = gtk_grid_new ();
|
||||
gtk_grid_set_row_spacing (GTK_GRID (table), 4);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (table), 4);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), table);
|
||||
gtk_box_pack_start (GTK_BOX (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 ();
|
||||
@@ -123,29 +123,29 @@ do_dialog (GtkWidget *do_widget)
|
||||
|
||||
/* Standard message dialog */
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||
button = gtk_button_new_with_mnemonic ("_Message Dialog");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (message_dialog_clicked), NULL);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
|
||||
|
||||
/* Interactive dialog*/
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (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_container_add (GTK_CONTAINER (hbox), vbox2);
|
||||
gtk_container_add (GTK_CONTAINER (vbox2), button);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), vbox2);
|
||||
gtk_box_pack_start (GTK_BOX (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_container_add (GTK_CONTAINER (hbox), table);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), table);
|
||||
|
||||
label = gtk_label_new_with_mnemonic ("_Entry 1");
|
||||
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
|
||||
|
||||
@@ -352,15 +352,14 @@ do_dnd (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
fixed = gtk_fixed_new ();
|
||||
gtk_container_add (GTK_CONTAINER (vbox), fixed);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), fixed);
|
||||
gtk_widget_set_hexpand (fixed, TRUE);
|
||||
gtk_widget_set_vexpand (fixed, TRUE);
|
||||
|
||||
multipress = gtk_gesture_multi_press_new ();
|
||||
multipress = gtk_gesture_multi_press_new (fixed);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (multipress), 0);
|
||||
g_signal_connect (multipress, "pressed", G_CALLBACK (pressed_cb), NULL);
|
||||
g_signal_connect (multipress, "released", G_CALLBACK (released_cb), NULL);
|
||||
gtk_widget_add_controller (fixed, GTK_EVENT_CONTROLLER (multipress));
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/dnd/dnd.css");
|
||||
|
||||
@@ -86,7 +86,7 @@ draw_brush (GtkWidget *widget,
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
gtk_widget_queue_draw_area (widget, update_rect.x, update_rect.y, update_rect.width, update_rect.height);
|
||||
}
|
||||
|
||||
static double start_x;
|
||||
@@ -208,12 +208,12 @@ do_drawingarea (GtkWidget *do_widget)
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>Checkerboard pattern</u>");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_widget_set_vexpand (frame, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
da = gtk_drawing_area_new ();
|
||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
|
||||
@@ -228,12 +228,12 @@ do_drawingarea (GtkWidget *do_widget)
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>Scribble area</u>");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_set_vexpand (frame, TRUE);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
da = gtk_drawing_area_new ();
|
||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
|
||||
@@ -244,14 +244,13 @@ do_drawingarea (GtkWidget *do_widget)
|
||||
g_signal_connect (da, "size-allocate",
|
||||
G_CALLBACK (scribble_size_allocate), NULL);
|
||||
|
||||
drag = gtk_gesture_drag_new ();
|
||||
drag = gtk_gesture_drag_new (da);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), GDK_BUTTON_PRIMARY);
|
||||
gtk_widget_add_controller (da, GTK_EVENT_CONTROLLER (drag));
|
||||
g_object_set_data_full (G_OBJECT (da), "drag", drag, g_object_unref);
|
||||
|
||||
g_signal_connect (drag, "drag-begin", G_CALLBACK (drag_begin), da);
|
||||
g_signal_connect (drag, "drag-update", G_CALLBACK (drag_update), da);
|
||||
g_signal_connect (drag, "drag-end", G_CALLBACK (drag_end), da);
|
||||
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -356,7 +356,7 @@ do_editable_cells (GtkWidget *do_widget)
|
||||
g_object_set (vbox, "margin", 5, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox),
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
gtk_label_new ("Shopping list (you can edit the cells!)"));
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
@@ -365,7 +365,7 @@ do_editable_cells (GtkWidget *do_widget)
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), sw);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), sw);
|
||||
|
||||
/* create models */
|
||||
items_model = create_items_model ();
|
||||
@@ -387,17 +387,17 @@ do_editable_cells (GtkWidget *do_widget)
|
||||
/* some buttons */
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||
|
||||
button = gtk_button_new_with_label ("Add item");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (add_item), treeview);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button);
|
||||
|
||||
button = gtk_button_new_with_label ("Remove item");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (remove_item), treeview);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button);
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 320, 200);
|
||||
}
|
||||
|
||||
@@ -34,19 +34,19 @@ do_entry_buffer (GtkWidget *do_widget)
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"Entries share a buffer. Typing in one is reflected in the other.");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
/* Create a buffer */
|
||||
buffer = gtk_entry_buffer_new (NULL, 0);
|
||||
|
||||
/* Create our first entry */
|
||||
entry = gtk_entry_new_with_buffer (buffer);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), entry);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), entry);
|
||||
|
||||
/* Create the second entry */
|
||||
entry = gtk_entry_new_with_buffer (buffer);
|
||||
gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), entry);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), entry);
|
||||
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
|
||||
@@ -60,11 +60,11 @@ do_entry_completion (GtkWidget *do_widget)
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
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);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
/* Create our entry */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_container_add (GTK_CONTAINER (vbox), entry);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), entry);
|
||||
|
||||
/* Create the completion object */
|
||||
completion = gtk_entry_completion_new ();
|
||||
|
||||
668
demos/gtk-demo/event_axes.c
Normal file
668
demos/gtk-demo/event_axes.c
Normal file
@@ -0,0 +1,668 @@
|
||||
/* Touch and Drawing Tablets
|
||||
*
|
||||
* Demonstrates advanced handling of event information from exotic
|
||||
* input devices.
|
||||
*
|
||||
* On one hand, this snippet demonstrates management of drawing tablets,
|
||||
* those contain additional information for the pointer other than
|
||||
* X/Y coordinates. Tablet pads events are mapped to actions, which
|
||||
* are both defined and interpreted by the application.
|
||||
*
|
||||
* Input axes are dependent on hardware devices, on linux/unix you
|
||||
* can see the device axes through xinput list <device>. Each time
|
||||
* a different hardware device is used to move the pointer, the
|
||||
* master device will be updated to match the axes it provides,
|
||||
* these changes can be tracked through GdkDevice::changed, or
|
||||
* checking gdk_event_get_source_device().
|
||||
*
|
||||
* On the other hand, this demo handles basic multitouch events,
|
||||
* each event coming from an specific touchpoint will contain a
|
||||
* GdkEventSequence that's unique for its lifetime, so multiple
|
||||
* touchpoints can be tracked.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
typedef struct {
|
||||
GdkDevice *last_source;
|
||||
GdkDeviceTool *last_tool;
|
||||
gdouble *axes;
|
||||
GdkRGBA color;
|
||||
gdouble x;
|
||||
gdouble y;
|
||||
} AxesInfo;
|
||||
|
||||
typedef struct {
|
||||
GHashTable *pointer_info; /* GdkDevice -> AxesInfo */
|
||||
GHashTable *touch_info; /* GdkEventSequence -> AxesInfo */
|
||||
} EventData;
|
||||
|
||||
const gchar *colors[] = {
|
||||
"black",
|
||||
"orchid",
|
||||
"fuchsia",
|
||||
"indigo",
|
||||
"thistle",
|
||||
"sienna",
|
||||
"azure",
|
||||
"plum",
|
||||
"lime",
|
||||
"navy",
|
||||
"maroon",
|
||||
"burlywood"
|
||||
};
|
||||
|
||||
static GtkPadActionEntry pad_actions[] = {
|
||||
{ GTK_PAD_ACTION_BUTTON, 1, -1, N_("Nuclear strike"), "pad.nuke" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 2, -1, N_("Release siberian methane reserves"), "pad.heat" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 3, -1, N_("Release solar flare"), "pad.fry" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 4, -1, N_("De-stabilize Oort cloud"), "pad.fall" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 5, -1, N_("Ignite WR-104"), "pad.burst" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 6, -1, N_("Lart whoever asks about this button"), "pad.lart" },
|
||||
{ GTK_PAD_ACTION_RING, -1, -1, N_("Earth axial tilt"), "pad.tilt" },
|
||||
{ GTK_PAD_ACTION_STRIP, -1, -1, N_("Extent of weak nuclear force"), "pad.dissolve" },
|
||||
};
|
||||
|
||||
static const gchar *pad_action_results[] = {
|
||||
"☢",
|
||||
"♨",
|
||||
"☼",
|
||||
"☄",
|
||||
"⚡",
|
||||
"💫",
|
||||
"◑",
|
||||
"⚛"
|
||||
};
|
||||
|
||||
static guint cur_color = 0;
|
||||
static guint pad_action_timeout_id = 0;
|
||||
|
||||
static AxesInfo *
|
||||
axes_info_new (void)
|
||||
{
|
||||
AxesInfo *info;
|
||||
|
||||
info = g_new0 (AxesInfo, 1);
|
||||
gdk_rgba_parse (&info->color, colors[cur_color]);
|
||||
|
||||
cur_color = (cur_color + 1) % G_N_ELEMENTS (colors);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static EventData *
|
||||
event_data_new (void)
|
||||
{
|
||||
EventData *data;
|
||||
|
||||
data = g_new0 (EventData, 1);
|
||||
data->pointer_info = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) g_free);
|
||||
data->touch_info = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) g_free);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
event_data_free (EventData *data)
|
||||
{
|
||||
g_hash_table_destroy (data->pointer_info);
|
||||
g_hash_table_destroy (data->touch_info);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
update_axes_from_event (GdkEvent *event,
|
||||
EventData *data)
|
||||
{
|
||||
GdkDevice *device, *source_device;
|
||||
GdkEventSequence *sequence;
|
||||
GdkDeviceTool *tool;
|
||||
GdkEventType type;
|
||||
gdouble x, y;
|
||||
AxesInfo *info;
|
||||
|
||||
device = gdk_event_get_device (event);
|
||||
source_device = gdk_event_get_source_device (event);
|
||||
sequence = gdk_event_get_event_sequence (event);
|
||||
tool = gdk_event_get_device_tool (event);
|
||||
type = gdk_event_get_event_type (event);
|
||||
|
||||
if (type == GDK_TOUCH_END ||
|
||||
type == GDK_TOUCH_CANCEL)
|
||||
{
|
||||
g_hash_table_remove (data->touch_info, sequence);
|
||||
return;
|
||||
}
|
||||
else if (type == GDK_LEAVE_NOTIFY)
|
||||
{
|
||||
g_hash_table_remove (data->pointer_info, device);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!source_device)
|
||||
return;
|
||||
|
||||
if (!sequence)
|
||||
{
|
||||
info = g_hash_table_lookup (data->pointer_info, device);
|
||||
|
||||
if (!info)
|
||||
{
|
||||
info = axes_info_new ();
|
||||
g_hash_table_insert (data->pointer_info, device, info);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info = g_hash_table_lookup (data->touch_info, sequence);
|
||||
|
||||
if (!info)
|
||||
{
|
||||
info = axes_info_new ();
|
||||
g_hash_table_insert (data->touch_info, sequence, info);
|
||||
}
|
||||
}
|
||||
|
||||
if (info->last_source != source_device)
|
||||
info->last_source = source_device;
|
||||
|
||||
if (info->last_tool != tool)
|
||||
info->last_tool = tool;
|
||||
|
||||
g_clear_pointer (&info->axes, g_free);
|
||||
|
||||
if (type == GDK_TOUCH_BEGIN ||
|
||||
type == GDK_TOUCH_UPDATE)
|
||||
{
|
||||
gboolean emulating_pointer;
|
||||
|
||||
gdk_event_get_touch_emulating_pointer (event, &emulating_pointer);
|
||||
if (sequence && emulating_pointer)
|
||||
g_hash_table_remove (data->pointer_info, device);
|
||||
}
|
||||
if (type == GDK_MOTION_NOTIFY ||
|
||||
type == GDK_BUTTON_PRESS ||
|
||||
type == GDK_BUTTON_RELEASE)
|
||||
{
|
||||
gdouble *axes;
|
||||
guint n_axes;
|
||||
|
||||
gdk_event_get_axes (event, &axes, &n_axes);
|
||||
info->axes = g_memdup (axes, sizeof (double) * n_axes);
|
||||
}
|
||||
|
||||
if (gdk_event_get_coords (event, &x, &y))
|
||||
{
|
||||
info->x = x;
|
||||
info->y = y;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
update_axes_from_event (event, user_data);
|
||||
gtk_widget_queue_draw (widget);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
render_arrow (cairo_t *cr,
|
||||
gdouble x_diff,
|
||||
gdouble y_diff,
|
||||
const gchar *label)
|
||||
{
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_new_path (cr);
|
||||
cairo_move_to (cr, 0, 0);
|
||||
cairo_line_to (cr, x_diff, y_diff);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_move_to (cr, x_diff, y_diff);
|
||||
cairo_show_text (cr, label);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_axes_info (cairo_t *cr,
|
||||
AxesInfo *info,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
gdouble pressure, tilt_x, tilt_y, distance, wheel, rotation, slider;
|
||||
GdkAxisFlags axes = gdk_device_get_axes (info->last_source);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_set_line_width (cr, 1);
|
||||
gdk_cairo_set_source_rgba (cr, &info->color);
|
||||
|
||||
cairo_move_to (cr, 0, info->y);
|
||||
cairo_line_to (cr, width, info->y);
|
||||
cairo_move_to (cr, info->x, 0);
|
||||
cairo_line_to (cr, info->x, height);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_translate (cr, info->x, info->y);
|
||||
|
||||
if (!info->axes)
|
||||
{
|
||||
cairo_restore (cr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_PRESSURE)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_PRESSURE,
|
||||
&pressure);
|
||||
|
||||
pattern = cairo_pattern_create_radial (0, 0, 0, 0, 0, 100);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, pressure, 1, 0, 0, pressure);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 1, 0);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
|
||||
cairo_arc (cr, 0, 0, 100, 0, 2 * G_PI);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_pattern_destroy (pattern);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_XTILT &&
|
||||
axes & GDK_AXIS_FLAG_YTILT)
|
||||
{
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_XTILT,
|
||||
&tilt_x);
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_YTILT,
|
||||
&tilt_y);
|
||||
|
||||
render_arrow (cr, tilt_x * 100, tilt_y * 100, "Tilt");
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_DISTANCE)
|
||||
{
|
||||
double dashes[] = { 5.0, 5.0 };
|
||||
cairo_text_extents_t extents;
|
||||
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_DISTANCE,
|
||||
&distance);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_move_to (cr, distance * 100, 0);
|
||||
|
||||
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
|
||||
cairo_set_dash (cr, dashes, 2, 0.0);
|
||||
cairo_arc (cr, 0, 0, distance * 100, 0, 2 * G_PI);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_move_to (cr, 0, -distance * 100);
|
||||
cairo_text_extents (cr, "Distance", &extents);
|
||||
cairo_rel_move_to (cr, -extents.width / 2, 0);
|
||||
cairo_show_text (cr, "Distance");
|
||||
|
||||
cairo_move_to (cr, 0, 0);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_WHEEL)
|
||||
{
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_WHEEL,
|
||||
&wheel);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_set_line_width (cr, 10);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
|
||||
|
||||
cairo_new_sub_path (cr);
|
||||
cairo_arc (cr, 0, 0, 100, 0, wheel * 2 * G_PI);
|
||||
cairo_stroke (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_ROTATION)
|
||||
{
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_ROTATION,
|
||||
&rotation);
|
||||
rotation *= 2 * G_PI;
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_rotate (cr, - G_PI / 2);
|
||||
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
|
||||
cairo_set_line_width (cr, 5);
|
||||
|
||||
cairo_new_sub_path (cr);
|
||||
cairo_arc (cr, 0, 0, 100, 0, rotation);
|
||||
cairo_stroke (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_SLIDER)
|
||||
{
|
||||
cairo_pattern_t *pattern, *mask;
|
||||
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_SLIDER,
|
||||
&slider);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_move_to (cr, 0, -10);
|
||||
cairo_rel_line_to (cr, 0, -50);
|
||||
cairo_rel_line_to (cr, 10, 0);
|
||||
cairo_rel_line_to (cr, -5, 50);
|
||||
cairo_close_path (cr);
|
||||
|
||||
cairo_clip_preserve (cr);
|
||||
|
||||
pattern = cairo_pattern_create_linear (0, -10, 0, -60);
|
||||
cairo_pattern_add_color_stop_rgb (pattern, 0, 0, 1, 0);
|
||||
cairo_pattern_add_color_stop_rgb (pattern, 1, 1, 0, 0);
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
mask = cairo_pattern_create_linear (0, -10, 0, -60);
|
||||
cairo_pattern_add_color_stop_rgba (mask, 0, 0, 0, 0, 1);
|
||||
cairo_pattern_add_color_stop_rgba (mask, slider, 0, 0, 0, 1);
|
||||
cairo_pattern_add_color_stop_rgba (mask, slider, 0, 0, 0, 0);
|
||||
cairo_pattern_add_color_stop_rgba (mask, 1, 0, 0, 0, 0);
|
||||
cairo_mask (cr, mask);
|
||||
cairo_pattern_destroy (mask);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
tool_type_to_string (GdkDeviceToolType tool_type)
|
||||
{
|
||||
switch (tool_type)
|
||||
{
|
||||
case GDK_DEVICE_TOOL_TYPE_PEN:
|
||||
return "Pen";
|
||||
case GDK_DEVICE_TOOL_TYPE_ERASER:
|
||||
return "Eraser";
|
||||
case GDK_DEVICE_TOOL_TYPE_BRUSH:
|
||||
return "Brush";
|
||||
case GDK_DEVICE_TOOL_TYPE_PENCIL:
|
||||
return "Pencil";
|
||||
case GDK_DEVICE_TOOL_TYPE_AIRBRUSH:
|
||||
return "Airbrush";
|
||||
case GDK_DEVICE_TOOL_TYPE_MOUSE:
|
||||
return "Mouse";
|
||||
case GDK_DEVICE_TOOL_TYPE_LENS:
|
||||
return "Lens cursor";
|
||||
case GDK_DEVICE_TOOL_TYPE_UNKNOWN:
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_device_info (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
GdkEventSequence *sequence,
|
||||
gint *y,
|
||||
AxesInfo *info)
|
||||
{
|
||||
PangoLayout *layout;
|
||||
GString *string;
|
||||
gint height;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
g_string_append_printf (string, "Source: %s",
|
||||
gdk_device_get_name (info->last_source));
|
||||
|
||||
if (sequence)
|
||||
g_string_append_printf (string, "\nSequence: %d",
|
||||
GPOINTER_TO_UINT (sequence));
|
||||
|
||||
if (info->last_tool)
|
||||
{
|
||||
const gchar *tool_type;
|
||||
guint64 serial;
|
||||
|
||||
tool_type = tool_type_to_string (gdk_device_tool_get_tool_type (info->last_tool));
|
||||
serial = gdk_device_tool_get_serial (info->last_tool);
|
||||
g_string_append_printf (string, "\nTool: %s", tool_type);
|
||||
|
||||
if (serial != 0)
|
||||
g_string_append_printf (string, ", Serial: %lx", serial);
|
||||
}
|
||||
|
||||
cairo_move_to (cr, 10, *y);
|
||||
layout = gtk_widget_create_pango_layout (widget, string->str);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
cairo_stroke (cr);
|
||||
|
||||
pango_layout_get_pixel_size (layout, NULL, &height);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, &info->color);
|
||||
cairo_set_line_width (cr, 10);
|
||||
cairo_move_to (cr, 0, *y);
|
||||
|
||||
*y = *y + height;
|
||||
cairo_line_to (cr, 0, *y);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
g_object_unref (layout);
|
||||
g_string_free (string, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_cb (GtkDrawingArea *da,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (da);
|
||||
EventData *data = user_data;
|
||||
AxesInfo *info;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
gint y = 0;
|
||||
|
||||
/* Draw Abs info */
|
||||
g_hash_table_iter_init (&iter, data->pointer_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_axes_info (cr, info, width, height);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, data->touch_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_axes_info (cr, info, width, height);
|
||||
}
|
||||
|
||||
/* Draw name, color legend and misc data */
|
||||
g_hash_table_iter_init (&iter, data->pointer_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_device_info (widget, cr, NULL, &y, info);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, data->touch_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_device_info (widget, cr, key, &y, info);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_label_text (GtkWidget *label,
|
||||
const gchar *text)
|
||||
{
|
||||
gchar *markup = NULL;
|
||||
|
||||
if (text)
|
||||
markup = g_strdup_printf ("<span font='48.0'>%s</span>", text);
|
||||
gtk_label_set_markup (GTK_LABEL (label), markup);
|
||||
g_free (markup);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
reset_label_text_timeout_cb (gpointer user_data)
|
||||
{
|
||||
GtkWidget *label = user_data;
|
||||
|
||||
update_label_text (label, NULL);
|
||||
pad_action_timeout_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_label_and_timeout (GtkWidget *label,
|
||||
const gchar *text)
|
||||
{
|
||||
if (pad_action_timeout_id)
|
||||
g_source_remove (pad_action_timeout_id);
|
||||
|
||||
update_label_text (label, text);
|
||||
pad_action_timeout_id = g_timeout_add (200, reset_label_text_timeout_cb, label);
|
||||
}
|
||||
|
||||
static void
|
||||
on_action_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *label = user_data;
|
||||
const gchar *result;
|
||||
gchar *str;
|
||||
|
||||
result = g_object_get_data (G_OBJECT (action), "action-result");
|
||||
|
||||
if (!parameter)
|
||||
update_label_and_timeout (label, result);
|
||||
else
|
||||
{
|
||||
str = g_strdup_printf ("%s %.2f", result, g_variant_get_double (parameter));
|
||||
update_label_and_timeout (label, str);
|
||||
g_free (str);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_pad_controller (GtkWidget *window,
|
||||
GtkWidget *label)
|
||||
{
|
||||
GtkPadController *pad_controller;
|
||||
GSimpleActionGroup *action_group;
|
||||
GSimpleAction *action;
|
||||
gint i;
|
||||
|
||||
action_group = g_simple_action_group_new ();
|
||||
pad_controller = gtk_pad_controller_new (GTK_WINDOW (window),
|
||||
G_ACTION_GROUP (action_group),
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (pad_actions); i++)
|
||||
{
|
||||
if (pad_actions[i].type == GTK_PAD_ACTION_BUTTON)
|
||||
{
|
||||
action = g_simple_action_new (pad_actions[i].action_name, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
action = g_simple_action_new_stateful (pad_actions[i].action_name,
|
||||
G_VARIANT_TYPE_DOUBLE, NULL);
|
||||
}
|
||||
|
||||
g_signal_connect (action, "activate",
|
||||
G_CALLBACK (on_action_activate), label);
|
||||
g_object_set_data (G_OBJECT (action), "action-result",
|
||||
(gpointer) pad_action_results[i]);
|
||||
g_action_map_add_action (G_ACTION_MAP (action_group), G_ACTION (action));
|
||||
g_object_unref (action);
|
||||
}
|
||||
|
||||
gtk_pad_controller_set_action_entries (pad_controller, pad_actions,
|
||||
G_N_ELEMENTS (pad_actions));
|
||||
g_object_set_data_full (G_OBJECT (window), "pad-controller",
|
||||
pad_controller, g_object_unref);
|
||||
|
||||
g_object_unref (action_group);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_event_axes (GtkWidget *toplevel)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
EventData *event_data;
|
||||
GtkWidget *label;
|
||||
GtkWidget *overlay;
|
||||
GtkWidget *da;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Touch and Drawing Tablets");
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
gtk_widget_set_support_multidevice (window, TRUE);
|
||||
|
||||
event_data = event_data_new ();
|
||||
g_object_set_data_full (G_OBJECT (window), "gtk-demo-event-data",
|
||||
event_data, (GDestroyNotify) event_data_free);
|
||||
|
||||
da = gtk_drawing_area_new ();
|
||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 400);
|
||||
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 400);
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), draw_cb, event_data, NULL);
|
||||
gtk_widget_set_can_focus (da, TRUE);
|
||||
gtk_widget_grab_focus (da);
|
||||
|
||||
g_signal_connect (da, "event",
|
||||
G_CALLBACK (event_cb), event_data);
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_START);
|
||||
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
gtk_container_add (GTK_CONTAINER (window), overlay);
|
||||
gtk_container_add (GTK_CONTAINER (overlay), da);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), label);
|
||||
|
||||
init_pad_controller (da, label);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -73,7 +73,7 @@ do_expander (GtkWidget *do_widget)
|
||||
"resize the window. Do it already !", -1);
|
||||
gtk_container_add (GTK_CONTAINER (sw), tv);
|
||||
gtk_container_add (GTK_CONTAINER (expander), sw);
|
||||
gtk_container_add (GTK_CONTAINER (area), expander);
|
||||
gtk_box_pack_end (GTK_BOX (area), expander);
|
||||
g_signal_connect (expander, "notify::expanded",
|
||||
G_CALLBACK (expander_cb), window);
|
||||
|
||||
|
||||
@@ -8,270 +8,165 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "gtkfishbowl.h"
|
||||
#include "gtkgears.h"
|
||||
|
||||
const char *const css =
|
||||
".blurred-button {"
|
||||
" box-shadow: 0px 0px 5px 10px rgba(0, 0, 0, 0.5);"
|
||||
"}"
|
||||
"";
|
||||
GtkWidget *allow_changes;
|
||||
|
||||
char **icon_names = NULL;
|
||||
gsize n_icon_names = 0;
|
||||
#define N_STATS 5
|
||||
|
||||
static void
|
||||
init_icon_names (GtkIconTheme *theme)
|
||||
{
|
||||
GPtrArray *icons;
|
||||
GList *l, *icon_list;
|
||||
#define STATS_UPDATE_TIME G_USEC_PER_SEC
|
||||
|
||||
if (icon_names)
|
||||
return;
|
||||
typedef struct _Stats Stats;
|
||||
struct _Stats {
|
||||
gint64 last_stats;
|
||||
gint64 last_frame;
|
||||
gint last_suggestion;
|
||||
guint frame_counter_max;
|
||||
|
||||
icon_list = gtk_icon_theme_list_icons (theme, NULL);
|
||||
icons = g_ptr_array_new ();
|
||||
|
||||
for (l = icon_list; l; l = l->next)
|
||||
{
|
||||
if (g_str_has_suffix (l->data, "symbolic"))
|
||||
continue;
|
||||
|
||||
g_ptr_array_add (icons, g_strdup (l->data));
|
||||
}
|
||||
|
||||
n_icon_names = icons->len;
|
||||
g_ptr_array_add (icons, NULL); /* NULL-terminate the array */
|
||||
icon_names = (char **) g_ptr_array_free (icons, FALSE);
|
||||
|
||||
/* don't free strings, we assigned them to the array */
|
||||
g_list_free_full (icon_list, g_free);
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_random_icon_name (GtkIconTheme *theme)
|
||||
{
|
||||
init_icon_names (theme);
|
||||
|
||||
return icon_names[g_random_int_range(0, n_icon_names)];
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
create_icon (void)
|
||||
{
|
||||
GtkWidget *image;
|
||||
|
||||
image = gtk_image_new_from_icon_name (get_random_icon_name (gtk_icon_theme_get_default ()));
|
||||
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_button (void)
|
||||
{
|
||||
return gtk_button_new_with_label ("Button");
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_blurred_button (void)
|
||||
{
|
||||
GtkWidget *w = gtk_button_new ();
|
||||
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (w), "blurred-button");
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_font_button (void)
|
||||
{
|
||||
return gtk_font_button_new ();
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_level_bar (void)
|
||||
{
|
||||
GtkWidget *w = gtk_level_bar_new_for_interval (0, 100);
|
||||
|
||||
gtk_level_bar_set_value (GTK_LEVEL_BAR (w), 50);
|
||||
|
||||
/* Force them to be a bit larger */
|
||||
gtk_widget_set_size_request (w, 200, -1);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_spinner (void)
|
||||
{
|
||||
GtkWidget *w = gtk_spinner_new ();
|
||||
|
||||
gtk_spinner_start (GTK_SPINNER (w));
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_spinbutton (void)
|
||||
{
|
||||
GtkWidget *w = gtk_spin_button_new_with_range (0, 10, 1);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_label (void)
|
||||
{
|
||||
GtkWidget *w = gtk_label_new ("pLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.");
|
||||
|
||||
gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
|
||||
gtk_label_set_max_width_chars (GTK_LABEL (w), 100);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_video (void)
|
||||
{
|
||||
GtkMediaStream *stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
|
||||
GtkWidget *w = gtk_picture_new_for_paintable (GDK_PAINTABLE (stream));
|
||||
|
||||
gtk_widget_set_size_request (w, 64, 64);
|
||||
gtk_media_stream_set_loop (stream, TRUE);
|
||||
gtk_media_stream_play (stream);
|
||||
g_object_unref (stream);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_gears (void)
|
||||
{
|
||||
GtkWidget *w = gtk_gears_new ();
|
||||
|
||||
gtk_widget_set_size_request (w, 100, 100);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_switch (void)
|
||||
{
|
||||
GtkWidget *w = gtk_switch_new ();
|
||||
|
||||
gtk_switch_set_state (GTK_SWITCH (w), TRUE);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
GtkWidget * (*create_func) (void);
|
||||
} widget_types[] = {
|
||||
{ "Icon", create_icon },
|
||||
{ "Button", create_button },
|
||||
{ "Blurbutton", create_blurred_button },
|
||||
{ "Fontbutton", create_font_button },
|
||||
{ "Levelbar", create_level_bar },
|
||||
{ "Label", create_label },
|
||||
{ "Spinner", create_spinner },
|
||||
{ "Spinbutton", create_spinbutton },
|
||||
{ "Video", create_video },
|
||||
{ "Gears", create_gears },
|
||||
{ "Switch", create_switch },
|
||||
guint stats_index;
|
||||
guint frame_counter[N_STATS];
|
||||
guint item_counter[N_STATS];
|
||||
};
|
||||
|
||||
static int selected_widget_type = -1;
|
||||
static const int N_WIDGET_TYPES = G_N_ELEMENTS (widget_types);
|
||||
static Stats *
|
||||
get_stats (GtkWidget *widget)
|
||||
{
|
||||
static GQuark stats_quark = 0;
|
||||
Stats *stats;
|
||||
|
||||
if (G_UNLIKELY (stats_quark == 0))
|
||||
stats_quark = g_quark_from_static_string ("stats");
|
||||
|
||||
stats = g_object_get_qdata (G_OBJECT (widget), stats_quark);
|
||||
if (stats == NULL)
|
||||
{
|
||||
stats = g_new0 (Stats, 1);
|
||||
g_object_set_qdata_full (G_OBJECT (widget), stats_quark, stats, g_free);
|
||||
stats->last_frame = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
|
||||
stats->last_stats = stats->last_frame;
|
||||
}
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
static void
|
||||
set_widget_type (GtkFishbowl *fishbowl,
|
||||
int widget_type_index)
|
||||
do_stats (GtkWidget *widget,
|
||||
GtkWidget *info_label,
|
||||
gint *suggested_change)
|
||||
{
|
||||
GtkWidget *window, *headerbar;
|
||||
Stats *stats;
|
||||
gint64 frame_time;
|
||||
|
||||
if (widget_type_index == selected_widget_type)
|
||||
return;
|
||||
stats = get_stats (widget);
|
||||
frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
|
||||
|
||||
selected_widget_type = widget_type_index;
|
||||
if (stats->last_stats + STATS_UPDATE_TIME < frame_time)
|
||||
{
|
||||
char *new_label;
|
||||
guint i, n_frames;
|
||||
|
||||
gtk_fishbowl_set_creation_func (fishbowl,
|
||||
widget_types[selected_widget_type].create_func);
|
||||
n_frames = 0;
|
||||
for (i = 0; i < N_STATS; i++)
|
||||
{
|
||||
n_frames += stats->frame_counter[i];
|
||||
}
|
||||
|
||||
new_label = g_strdup_printf ("icons - %.1f fps",
|
||||
(double) G_USEC_PER_SEC * n_frames
|
||||
/ (N_STATS * STATS_UPDATE_TIME));
|
||||
gtk_label_set_label (GTK_LABEL (info_label), new_label);
|
||||
g_free (new_label);
|
||||
|
||||
window = gtk_widget_get_toplevel (GTK_WIDGET (fishbowl));
|
||||
headerbar = gtk_window_get_titlebar (GTK_WINDOW (window));
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar),
|
||||
widget_types[selected_widget_type].name);
|
||||
}
|
||||
if (stats->frame_counter[stats->stats_index] >= 19 * stats->frame_counter_max / 20)
|
||||
{
|
||||
if (stats->last_suggestion > 0)
|
||||
stats->last_suggestion *= 2;
|
||||
else
|
||||
stats->last_suggestion = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (stats->last_suggestion < 0)
|
||||
stats->last_suggestion--;
|
||||
else
|
||||
stats->last_suggestion = -1;
|
||||
stats->last_suggestion = MAX (stats->last_suggestion, 1 - (int) stats->item_counter[stats->stats_index]);
|
||||
}
|
||||
|
||||
void
|
||||
next_button_clicked_cb (GtkButton *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkFishbowl *fishbowl = user_data;
|
||||
int new_index;
|
||||
|
||||
if (selected_widget_type + 1 >= N_WIDGET_TYPES)
|
||||
new_index = 0;
|
||||
stats->stats_index = (stats->stats_index + 1) % N_STATS;
|
||||
stats->frame_counter[stats->stats_index] = 0;
|
||||
stats->item_counter[stats->stats_index] = stats->item_counter[(stats->stats_index + N_STATS - 1) % N_STATS];
|
||||
stats->last_stats = frame_time;
|
||||
|
||||
if (suggested_change)
|
||||
*suggested_change = stats->last_suggestion;
|
||||
else
|
||||
stats->last_suggestion = 0;
|
||||
}
|
||||
else
|
||||
new_index = selected_widget_type + 1;
|
||||
{
|
||||
if (suggested_change)
|
||||
*suggested_change = 0;
|
||||
}
|
||||
|
||||
set_widget_type (fishbowl, new_index);
|
||||
stats->last_frame = frame_time;
|
||||
stats->frame_counter[stats->stats_index]++;
|
||||
stats->frame_counter_max = MAX (stats->frame_counter_max, stats->frame_counter[stats->stats_index]);
|
||||
}
|
||||
|
||||
void
|
||||
prev_button_clicked_cb (GtkButton *source,
|
||||
gpointer user_data)
|
||||
static void
|
||||
stats_update (GtkWidget *widget)
|
||||
{
|
||||
GtkFishbowl *fishbowl = user_data;
|
||||
int new_index;
|
||||
Stats *stats;
|
||||
|
||||
if (selected_widget_type - 1 < 0)
|
||||
new_index = N_WIDGET_TYPES - 1;
|
||||
else
|
||||
new_index = selected_widget_type - 1;
|
||||
stats = get_stats (widget);
|
||||
|
||||
set_widget_type (fishbowl, new_index);
|
||||
stats->item_counter[stats->stats_index] = gtk_fishbowl_get_count (GTK_FISHBOWL (widget));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
move_fish (GtkWidget *bowl,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer info_label)
|
||||
{
|
||||
gint suggested_change = 0;
|
||||
|
||||
do_stats (bowl,
|
||||
info_label,
|
||||
!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (allow_changes)) ? &suggested_change : NULL);
|
||||
|
||||
gtk_fishbowl_set_count (GTK_FISHBOWL (bowl),
|
||||
gtk_fishbowl_get_count (GTK_FISHBOWL (bowl)) + suggested_change);
|
||||
stats_update (bowl);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_fishbowl (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkCssProvider *provider = NULL;
|
||||
|
||||
if (provider == NULL)
|
||||
{
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, css, -1);
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
}
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *bowl;
|
||||
GtkWidget *bowl, *info_label;
|
||||
|
||||
g_type_ensure (GTK_TYPE_FISHBOWL);
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui");
|
||||
gtk_builder_add_callback_symbols (builder,
|
||||
"next_button_clicked_cb", G_CALLBACK (next_button_clicked_cb),
|
||||
"prev_button_clicked_cb", G_CALLBACK (prev_button_clicked_cb),
|
||||
NULL);
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl"));
|
||||
set_widget_type (GTK_FISHBOWL (bowl), 0);
|
||||
gtk_fishbowl_set_use_icons (GTK_FISHBOWL (bowl), TRUE);
|
||||
info_label = GTK_WIDGET (gtk_builder_get_object (builder, "info_label"));
|
||||
allow_changes = GTK_WIDGET (gtk_builder_get_object (builder, "changes_allow"));
|
||||
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);
|
||||
gtk_widget_add_tick_callback (bowl, move_fish, info_label, NULL);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -7,43 +7,7 @@
|
||||
<object class="GtkHeaderBar" id="">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">pan-start-symbolic</property>
|
||||
<signal name="clicked" handler="prev_button_clicked_cb" object="bowl" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">pan-end-symbolic</property>
|
||||
<signal name="clicked" handler="next_button_clicked_cb" object="bowl" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">fps</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" bind-source="bowl" bind-property="framerate"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Icons, </property>
|
||||
<object class="GtkLabel" id="info_label">
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
@@ -84,7 +48,6 @@
|
||||
<object class="GtkFishbowl" id="bowl">
|
||||
<property name="visible">True</property>
|
||||
<property name="animating">True</property>
|
||||
<property name="benchmark" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
<property name="can-focus">1</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="font">Sans 12</property>
|
||||
<property name="level">family|style|size|variations|features</property>
|
||||
<signal name="font-set" handler="font_changed" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
@@ -133,6 +132,7 @@
|
||||
Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) – вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
|
||||
|
||||
Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
|
||||
<signal name="key-press-event" handler="entry_key_press"/>
|
||||
<signal name="activate" handler="stop_edit"/>
|
||||
<property name="valign">start</property>
|
||||
<property name="width-chars">50</property>
|
||||
|
||||
@@ -1669,12 +1669,12 @@ stop_edit (void)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_key_press (GtkEventController *controller,
|
||||
guint keyval,
|
||||
guint keycode,
|
||||
GdkModifierType modifiers,
|
||||
GtkEntry *entry)
|
||||
entry_key_press (GtkEntry *entry, GdkEventKey *event)
|
||||
{
|
||||
guint keyval;
|
||||
|
||||
gdk_event_get_keyval ((GdkEvent *)event, &keyval);
|
||||
|
||||
if (keyval == GDK_KEY_Escape)
|
||||
{
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), text);
|
||||
@@ -1694,7 +1694,6 @@ do_font_features (GtkWidget *do_widget)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *feature_list;
|
||||
GtkEventController *controller;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/font_features/font-features.ui");
|
||||
|
||||
@@ -1704,6 +1703,7 @@ do_font_features (GtkWidget *do_widget)
|
||||
gtk_builder_add_callback_symbol (builder, "reset", reset_features);
|
||||
gtk_builder_add_callback_symbol (builder, "stop_edit", G_CALLBACK (stop_edit));
|
||||
gtk_builder_add_callback_symbol (builder, "toggle_edit", G_CALLBACK (toggle_edit));
|
||||
gtk_builder_add_callback_symbol (builder, "entry_key_press", G_CALLBACK (entry_key_press));
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
@@ -1718,11 +1718,6 @@ do_font_features (GtkWidget *do_widget)
|
||||
entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
|
||||
edit_toggle = GTK_WIDGET (gtk_builder_get_object (builder, "edit_toggle"));
|
||||
|
||||
controller = gtk_event_controller_key_new ();
|
||||
g_object_set_data_full (G_OBJECT (entry), "controller", controller, g_object_unref);
|
||||
g_signal_connect (controller, "key-pressed", G_CALLBACK (entry_key_press), entry);
|
||||
gtk_widget_add_controller (entry, controller);
|
||||
|
||||
add_check_group (feature_list, _("Kerning"), (const char *[]){ "kern", NULL });
|
||||
add_check_group (feature_list, _("Ligatures"), (const char *[]){ "liga",
|
||||
"dlig",
|
||||
|
||||
@@ -68,7 +68,8 @@ plane_snapshot (GtkWidget *widget,
|
||||
height = gtk_widget_get_allocated_height (widget);
|
||||
|
||||
cr = gtk_snapshot_append_cairo (snapshot,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height),
|
||||
"FontPlane");
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_rectangle (cr, 0, 0, width, height);
|
||||
@@ -207,27 +208,23 @@ plane_drag_gesture_end (GtkGestureDrag *gesture,
|
||||
static void
|
||||
gtk_font_plane_init (GtkFontPlane *plane)
|
||||
{
|
||||
GtkGesture *gesture;
|
||||
|
||||
gtk_widget_set_has_surface (GTK_WIDGET (plane), FALSE);
|
||||
gtk_widget_set_can_focus (GTK_WIDGET (plane), TRUE);
|
||||
|
||||
gesture = gtk_gesture_drag_new ();
|
||||
g_signal_connect (gesture, "drag-begin",
|
||||
plane->drag_gesture = gtk_gesture_drag_new (GTK_WIDGET (plane));
|
||||
g_signal_connect (plane->drag_gesture, "drag-begin",
|
||||
G_CALLBACK (plane_drag_gesture_begin), plane);
|
||||
g_signal_connect (gesture, "drag-update",
|
||||
g_signal_connect (plane->drag_gesture, "drag-update",
|
||||
G_CALLBACK (plane_drag_gesture_update), plane);
|
||||
g_signal_connect (gesture, "drag-end",
|
||||
g_signal_connect (plane->drag_gesture, "drag-end",
|
||||
G_CALLBACK (plane_drag_gesture_end), plane);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), 0);
|
||||
gtk_widget_add_controller (GTK_WIDGET (plane), GTK_EVENT_CONTROLLER (gesture));
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (plane->drag_gesture), 0);
|
||||
|
||||
gesture = gtk_gesture_long_press_new ();
|
||||
g_signal_connect (gesture, "pressed",
|
||||
plane->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (plane));
|
||||
g_signal_connect (plane->long_press_gesture, "pressed",
|
||||
G_CALLBACK (hold_action), plane);
|
||||
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (gesture),
|
||||
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (plane->long_press_gesture),
|
||||
TRUE);
|
||||
gtk_widget_add_controller (GTK_WIDGET (plane), GTK_EVENT_CONTROLLER (gesture));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -238,6 +235,9 @@ plane_finalize (GObject *object)
|
||||
g_clear_object (&plane->weight_adj);
|
||||
g_clear_object (&plane->width_adj);
|
||||
|
||||
g_clear_object (&plane->drag_gesture);
|
||||
g_clear_object (&plane->long_press_gesture);
|
||||
|
||||
G_OBJECT_CLASS (gtk_font_plane_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ struct _GtkFontPlane
|
||||
GtkAdjustment *width_adj;
|
||||
|
||||
GtkGesture *drag_gesture;
|
||||
GtkGesture *long_press_gesture;
|
||||
};
|
||||
|
||||
struct _GtkFontPlaneClass
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* Foreign drawing
|
||||
*
|
||||
* Many applications can't use GTK widgets, for a variety of reasons,
|
||||
* Many applications can't use GTK+ widgets, for a variety of reasons,
|
||||
* but still want their user interface to appear integrated with the
|
||||
* rest of the desktop, and follow GTK themes. This demo shows how to
|
||||
* rest of the desktop, and follow GTK+ themes. This demo shows how to
|
||||
* use GtkStyleContext and the gtk_render_ APIs to achieve this.
|
||||
*
|
||||
* Note that this is a very simple, non-interactive example.
|
||||
|
||||
@@ -157,15 +157,16 @@ do_gestures (GtkWidget *do_widget)
|
||||
NULL, NULL);
|
||||
|
||||
/* Swipe */
|
||||
gesture = gtk_gesture_swipe_new ();
|
||||
gesture = gtk_gesture_swipe_new (drawing_area);
|
||||
g_signal_connect (gesture, "swipe",
|
||||
G_CALLBACK (swipe_gesture_swept), drawing_area);
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
|
||||
GTK_PHASE_BUBBLE);
|
||||
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture));
|
||||
g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
|
||||
|
||||
/* 3fg swipe for touchpads */
|
||||
gesture = g_object_new (GTK_TYPE_GESTURE_SWIPE,
|
||||
"widget", drawing_area,
|
||||
"n-points", 3,
|
||||
NULL);
|
||||
g_signal_connect (gesture, "begin",
|
||||
@@ -174,34 +175,33 @@ do_gestures (GtkWidget *do_widget)
|
||||
G_CALLBACK (swipe_gesture_swept), drawing_area);
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
|
||||
GTK_PHASE_BUBBLE);
|
||||
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
|
||||
|
||||
/* Long press */
|
||||
gesture = gtk_gesture_long_press_new ();
|
||||
gesture = gtk_gesture_long_press_new (drawing_area);
|
||||
g_signal_connect (gesture, "pressed",
|
||||
G_CALLBACK (long_press_gesture_pressed), drawing_area);
|
||||
g_signal_connect (gesture, "end",
|
||||
G_CALLBACK (long_press_gesture_end), drawing_area);
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
|
||||
GTK_PHASE_BUBBLE);
|
||||
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture));
|
||||
g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
|
||||
|
||||
/* Rotate */
|
||||
rotate = gesture = gtk_gesture_rotate_new ();
|
||||
rotate = gesture = gtk_gesture_rotate_new (drawing_area);
|
||||
g_signal_connect (gesture, "angle-changed",
|
||||
G_CALLBACK (rotation_angle_changed), drawing_area);
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
|
||||
GTK_PHASE_BUBBLE);
|
||||
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture));
|
||||
g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
|
||||
|
||||
/* Zoom */
|
||||
zoom = gesture = gtk_gesture_zoom_new ();
|
||||
zoom = gesture = gtk_gesture_zoom_new (drawing_area);
|
||||
g_signal_connect (gesture, "scale-changed",
|
||||
G_CALLBACK (zoom_scale_changed), drawing_area);
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
|
||||
GTK_PHASE_BUBBLE);
|
||||
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture));
|
||||
g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[Desktop Entry]
|
||||
Name=GTK Demo
|
||||
Comment=GTK code examples and demonstrations
|
||||
Name=GTK+ Demo
|
||||
Comment=GTK+ code examples and demonstrations
|
||||
Exec=gtk4-demo
|
||||
Icon=gtk4-demo
|
||||
Terminal=false
|
||||
@@ -24,18 +24,13 @@ typedef struct _GtkFishbowlChild GtkFishbowlChild;
|
||||
|
||||
struct _GtkFishbowlPrivate
|
||||
{
|
||||
GtkFishCreationFunc creation_func;
|
||||
GList *children;
|
||||
guint count;
|
||||
|
||||
gint64 last_frame_time;
|
||||
gint64 update_delay;
|
||||
guint tick_id;
|
||||
|
||||
double framerate;
|
||||
int last_benchmark_change;
|
||||
|
||||
guint benchmark : 1;
|
||||
guint use_icons: 1;
|
||||
};
|
||||
|
||||
struct _GtkFishbowlChild
|
||||
@@ -50,25 +45,18 @@ struct _GtkFishbowlChild
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ANIMATING,
|
||||
PROP_BENCHMARK,
|
||||
PROP_COUNT,
|
||||
PROP_FRAMERATE,
|
||||
PROP_UPDATE_DELAY,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *props[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkFishbowl, gtk_fishbowl, GTK_TYPE_WIDGET)
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkFishbowl, gtk_fishbowl, GTK_TYPE_CONTAINER)
|
||||
|
||||
static void
|
||||
gtk_fishbowl_init (GtkFishbowl *fishbowl)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
gtk_widget_set_has_surface (GTK_WIDGET (fishbowl), FALSE);
|
||||
|
||||
priv->update_delay = G_USEC_PER_SEC;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,6 +72,15 @@ gtk_fishbowl_new (void)
|
||||
return g_object_new (GTK_TYPE_FISHBOWL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_fishbowl_set_use_icons (GtkFishbowl *fishbowl,
|
||||
gboolean use_icons)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
priv->use_icons = use_icons;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
@@ -128,10 +125,10 @@ gtk_fishbowl_measure (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
gtk_fishbowl_size_allocate (GtkWidget *widget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip)
|
||||
{
|
||||
GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
@@ -142,18 +139,20 @@ gtk_fishbowl_size_allocate (GtkWidget *widget,
|
||||
|
||||
for (children = priv->children; children; children = children->next)
|
||||
{
|
||||
GtkAllocation child_clip;
|
||||
|
||||
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));
|
||||
child_allocation.y = round (child->y * (height - child_requisition.height));
|
||||
child_allocation.x = allocation->x + round (child->x * (allocation->width - child_requisition.width));
|
||||
child_allocation.y = allocation->y + round (child->y * (allocation->height - child_requisition.height));
|
||||
child_allocation.width = child_requisition.width;
|
||||
child_allocation.height = child_requisition.height;
|
||||
|
||||
gtk_widget_size_allocate (child->widget, &child_allocation, -1);
|
||||
gtk_widget_size_allocate (child->widget, &child_allocation, -1, &child_clip);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,9 +164,10 @@ new_speed (void)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_add (GtkFishbowl *fishbowl,
|
||||
GtkWidget *widget)
|
||||
gtk_fishbowl_add (GtkContainer *container,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkFishbowl *fishbowl = GTK_FISHBOWL (container);
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
GtkFishbowlChild *child_info;
|
||||
|
||||
@@ -189,12 +189,13 @@ gtk_fishbowl_add (GtkFishbowl *fishbowl,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_remove (GtkFishbowl *fishbowl,
|
||||
GtkWidget *widget)
|
||||
gtk_fishbowl_remove (GtkContainer *container,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkFishbowl *fishbowl = GTK_FISHBOWL (container);
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
GtkFishbowlChild *child;
|
||||
GtkWidget *widget_bowl = GTK_WIDGET (fishbowl);
|
||||
GtkWidget *widget_container = GTK_WIDGET (container);
|
||||
GList *children;
|
||||
|
||||
for (children = priv->children; children; children = children->next)
|
||||
@@ -211,8 +212,8 @@ gtk_fishbowl_remove (GtkFishbowl *fishbowl,
|
||||
g_list_free (children);
|
||||
g_free (child);
|
||||
|
||||
if (was_visible && gtk_widget_get_visible (widget_bowl))
|
||||
gtk_widget_queue_resize (widget_bowl);
|
||||
if (was_visible && gtk_widget_get_visible (widget_container))
|
||||
gtk_widget_queue_resize (widget_container);
|
||||
|
||||
priv->count--;
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
|
||||
@@ -221,6 +222,26 @@ gtk_fishbowl_remove (GtkFishbowl *fishbowl,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_forall (GtkContainer *container,
|
||||
GtkCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
GtkFishbowl *fishbowl = GTK_FISHBOWL (container);
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
GtkFishbowlChild *child;
|
||||
GList *children;
|
||||
|
||||
children = priv->children;
|
||||
while (children)
|
||||
{
|
||||
child = children->data;
|
||||
children = children->next;
|
||||
|
||||
(* callback) (child->widget, callback_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_dispose (GObject *object)
|
||||
{
|
||||
@@ -246,18 +267,10 @@ gtk_fishbowl_set_property (GObject *object,
|
||||
gtk_fishbowl_set_animating (fishbowl, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_BENCHMARK:
|
||||
gtk_fishbowl_set_benchmark (fishbowl, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_COUNT:
|
||||
gtk_fishbowl_set_count (fishbowl, g_value_get_uint (value));
|
||||
break;
|
||||
|
||||
case PROP_UPDATE_DELAY:
|
||||
gtk_fishbowl_set_update_delay (fishbowl, g_value_get_int64 (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -278,22 +291,10 @@ gtk_fishbowl_get_property (GObject *object,
|
||||
g_value_set_boolean (value, gtk_fishbowl_get_animating (fishbowl));
|
||||
break;
|
||||
|
||||
case PROP_BENCHMARK:
|
||||
g_value_set_boolean (value, gtk_fishbowl_get_benchmark (fishbowl));
|
||||
break;
|
||||
|
||||
case PROP_COUNT:
|
||||
g_value_set_uint (value, gtk_fishbowl_get_count (fishbowl));
|
||||
break;
|
||||
|
||||
case PROP_FRAMERATE:
|
||||
g_value_set_double (value, gtk_fishbowl_get_framerate (fishbowl));
|
||||
break;
|
||||
|
||||
case PROP_UPDATE_DELAY:
|
||||
g_value_set_int64 (value, gtk_fishbowl_get_update_delay (fishbowl));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -305,6 +306,7 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
|
||||
|
||||
object_class->dispose = gtk_fishbowl_dispose;
|
||||
object_class->set_property = gtk_fishbowl_set_property;
|
||||
@@ -313,6 +315,10 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
|
||||
widget_class->measure = gtk_fishbowl_measure;
|
||||
widget_class->size_allocate = gtk_fishbowl_size_allocate;
|
||||
|
||||
container_class->add = gtk_fishbowl_add;
|
||||
container_class->remove = gtk_fishbowl_remove;
|
||||
container_class->forall = gtk_fishbowl_forall;
|
||||
|
||||
props[PROP_ANIMATING] =
|
||||
g_param_spec_boolean ("animating",
|
||||
"animating",
|
||||
@@ -320,36 +326,13 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
props[PROP_BENCHMARK] =
|
||||
g_param_spec_boolean ("benchmark",
|
||||
"Benchmark",
|
||||
"Adapt the count property to hit the maximum framerate",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
props[PROP_COUNT] =
|
||||
g_param_spec_uint ("count",
|
||||
"Count",
|
||||
"Number of widgets",
|
||||
0, G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
props[PROP_FRAMERATE] =
|
||||
g_param_spec_double ("framerate",
|
||||
"Framerate",
|
||||
"Framerate of this widget in frames per second",
|
||||
0, G_MAXDOUBLE,
|
||||
0,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
props[PROP_UPDATE_DELAY] =
|
||||
g_param_spec_int64 ("update-delay",
|
||||
"Update delay",
|
||||
"Number of usecs between updates",
|
||||
0, G_MAXINT64,
|
||||
G_USEC_PER_SEC,
|
||||
G_PARAM_READWRITE);
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (object_class, NUM_PROPERTIES, props);
|
||||
}
|
||||
@@ -362,58 +345,96 @@ gtk_fishbowl_get_count (GtkFishbowl *fishbowl)
|
||||
return priv->count;
|
||||
}
|
||||
|
||||
char **icon_names = NULL;
|
||||
gsize n_icon_names = 0;
|
||||
|
||||
static void
|
||||
init_icon_names (GtkIconTheme *theme)
|
||||
{
|
||||
GPtrArray *icons;
|
||||
GList *l, *icon_list;
|
||||
|
||||
if (icon_names)
|
||||
return;
|
||||
|
||||
icon_list = gtk_icon_theme_list_icons (theme, NULL);
|
||||
icons = g_ptr_array_new ();
|
||||
|
||||
for (l = icon_list; l; l = l->next)
|
||||
{
|
||||
if (g_str_has_suffix (l->data, "symbolic"))
|
||||
continue;
|
||||
|
||||
g_ptr_array_add (icons, g_strdup (l->data));
|
||||
}
|
||||
|
||||
n_icon_names = icons->len;
|
||||
g_ptr_array_add (icons, NULL); /* NULL-terminate the array */
|
||||
icon_names = (char **) g_ptr_array_free (icons, FALSE);
|
||||
|
||||
/* don't free strings, we assigned them to the array */
|
||||
g_list_free_full (icon_list, g_free);
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_random_icon_name (GtkIconTheme *theme)
|
||||
{
|
||||
init_icon_names (theme);
|
||||
|
||||
return icon_names[g_random_int_range(0, n_icon_names)];
|
||||
}
|
||||
|
||||
static GType
|
||||
get_random_widget_type ()
|
||||
{
|
||||
GType types[] = {
|
||||
GTK_TYPE_SWITCH,
|
||||
GTK_TYPE_BUTTON,
|
||||
GTK_TYPE_ENTRY,
|
||||
GTK_TYPE_SPIN_BUTTON,
|
||||
GTK_TYPE_FONT_BUTTON,
|
||||
GTK_TYPE_SCROLLBAR,
|
||||
GTK_TYPE_SCALE,
|
||||
GTK_TYPE_LEVEL_BAR,
|
||||
GTK_TYPE_PROGRESS_BAR,
|
||||
GTK_TYPE_RADIO_BUTTON,
|
||||
GTK_TYPE_CHECK_BUTTON
|
||||
};
|
||||
return types[g_random_int_range (0, G_N_ELEMENTS (types))];
|
||||
}
|
||||
|
||||
void
|
||||
gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
|
||||
guint count)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
if (priv->count == count)
|
||||
return;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (fishbowl));
|
||||
|
||||
while (priv->count > count)
|
||||
{
|
||||
gtk_fishbowl_remove (fishbowl, gtk_widget_get_first_child (GTK_WIDGET (fishbowl)));
|
||||
gtk_container_remove (GTK_CONTAINER (fishbowl),
|
||||
((GtkFishbowlChild *) priv->children->data)->widget);
|
||||
}
|
||||
|
||||
while (priv->count < count)
|
||||
{
|
||||
GtkWidget *new_widget;
|
||||
|
||||
new_widget = priv->creation_func ();
|
||||
if (priv->use_icons)
|
||||
{
|
||||
new_widget = gtk_image_new_from_icon_name (get_random_icon_name (gtk_icon_theme_get_default ()));
|
||||
gtk_image_set_icon_size (GTK_IMAGE (new_widget), GTK_ICON_SIZE_LARGE);
|
||||
}
|
||||
else
|
||||
new_widget = g_object_new (get_random_widget_type (), NULL);
|
||||
|
||||
gtk_fishbowl_add (fishbowl, new_widget);
|
||||
gtk_container_add (GTK_CONTAINER (fishbowl), new_widget);
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (fishbowl));
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_fishbowl_get_benchmark (GtkFishbowl *fishbowl)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
return priv->benchmark;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_fishbowl_set_benchmark (GtkFishbowl *fishbowl,
|
||||
gboolean benchmark)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
if (priv->benchmark == benchmark)
|
||||
return;
|
||||
|
||||
priv->benchmark = benchmark;
|
||||
if (!benchmark)
|
||||
priv->last_benchmark_change = 0;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_BENCHMARK]);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_fishbowl_get_animating (GtkFishbowl *fishbowl)
|
||||
{
|
||||
@@ -422,111 +443,6 @@ gtk_fishbowl_get_animating (GtkFishbowl *fishbowl)
|
||||
return priv->tick_id != 0;
|
||||
}
|
||||
|
||||
static gint64
|
||||
guess_refresh_interval (GdkFrameClock *frame_clock)
|
||||
{
|
||||
gint64 interval;
|
||||
gint64 i;
|
||||
|
||||
interval = G_MAXINT64;
|
||||
|
||||
for (i = gdk_frame_clock_get_history_start (frame_clock);
|
||||
i < gdk_frame_clock_get_frame_counter (frame_clock);
|
||||
i++)
|
||||
{
|
||||
GdkFrameTimings *t, *before;
|
||||
gint64 ts, before_ts;
|
||||
|
||||
t = gdk_frame_clock_get_timings (frame_clock, i);
|
||||
before = gdk_frame_clock_get_timings (frame_clock, i - 1);
|
||||
if (t == NULL || before == NULL)
|
||||
continue;
|
||||
|
||||
ts = gdk_frame_timings_get_frame_time (t);
|
||||
before_ts = gdk_frame_timings_get_frame_time (before);
|
||||
if (ts == 0 || before_ts == 0)
|
||||
continue;
|
||||
|
||||
interval = MIN (interval, ts - before_ts);
|
||||
}
|
||||
|
||||
if (interval == G_MAXINT64)
|
||||
return 0;
|
||||
|
||||
return interval;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_do_update (GtkFishbowl *fishbowl)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
GdkFrameClock *frame_clock;
|
||||
GdkFrameTimings *start, *end;
|
||||
gint64 start_counter, end_counter;
|
||||
gint64 n_frames, expected_frames;
|
||||
gint64 start_timestamp, end_timestamp;
|
||||
gint64 interval;
|
||||
|
||||
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (fishbowl));
|
||||
if (frame_clock == NULL)
|
||||
return;
|
||||
|
||||
start_counter = gdk_frame_clock_get_history_start (frame_clock);
|
||||
end_counter = gdk_frame_clock_get_frame_counter (frame_clock);
|
||||
start = gdk_frame_clock_get_timings (frame_clock, start_counter);
|
||||
for (end = gdk_frame_clock_get_timings (frame_clock, end_counter);
|
||||
end_counter > start_counter && end != NULL && !gdk_frame_timings_get_complete (end);
|
||||
end = gdk_frame_clock_get_timings (frame_clock, end_counter))
|
||||
end_counter--;
|
||||
if (end_counter - start_counter < 4)
|
||||
return;
|
||||
|
||||
start_timestamp = gdk_frame_timings_get_presentation_time (start);
|
||||
end_timestamp = gdk_frame_timings_get_presentation_time (end);
|
||||
if (start_timestamp == 0 || end_timestamp == 0)
|
||||
{
|
||||
start_timestamp = gdk_frame_timings_get_frame_time (start);
|
||||
end_timestamp = gdk_frame_timings_get_frame_time (end);
|
||||
}
|
||||
|
||||
n_frames = end_counter - start_counter;
|
||||
priv->framerate = ((double) n_frames) * G_USEC_PER_SEC / (end_timestamp - start_timestamp);
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE]);
|
||||
|
||||
if (!priv->benchmark)
|
||||
return;
|
||||
|
||||
interval = gdk_frame_timings_get_refresh_interval (end);
|
||||
if (interval == 0)
|
||||
{
|
||||
interval = guess_refresh_interval (frame_clock);
|
||||
if (interval == 0)
|
||||
return;
|
||||
}
|
||||
expected_frames = round ((double) (end_timestamp - start_timestamp) / interval);
|
||||
|
||||
if (n_frames >= expected_frames)
|
||||
{
|
||||
if (priv->last_benchmark_change > 0)
|
||||
priv->last_benchmark_change *= 2;
|
||||
else
|
||||
priv->last_benchmark_change = 1;
|
||||
}
|
||||
else if (n_frames + 1 < expected_frames)
|
||||
{
|
||||
if (priv->last_benchmark_change < 0)
|
||||
priv->last_benchmark_change--;
|
||||
else
|
||||
priv->last_benchmark_change = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->last_benchmark_change = 0;
|
||||
}
|
||||
|
||||
gtk_fishbowl_set_count (fishbowl, MAX (1, (int) priv->count + priv->last_benchmark_change));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_fishbowl_tick (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
@@ -537,11 +453,9 @@ gtk_fishbowl_tick (GtkWidget *widget,
|
||||
GtkFishbowlChild *child;
|
||||
GList *l;
|
||||
gint64 frame_time, elapsed;
|
||||
gboolean do_update;
|
||||
|
||||
frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
|
||||
elapsed = frame_time - priv->last_frame_time;
|
||||
do_update = frame_time / priv->update_delay != priv->last_frame_time / priv->update_delay;
|
||||
priv->last_frame_time = frame_time;
|
||||
|
||||
/* last frame was 0, so we're just starting to animate */
|
||||
@@ -580,9 +494,6 @@ gtk_fishbowl_tick (GtkWidget *widget,
|
||||
|
||||
gtk_widget_queue_allocate (widget);
|
||||
|
||||
if (do_update)
|
||||
gtk_fishbowl_do_update (fishbowl);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
@@ -607,57 +518,8 @@ gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
|
||||
priv->last_frame_time = 0;
|
||||
gtk_widget_remove_tick_callback (GTK_WIDGET (fishbowl), priv->tick_id);
|
||||
priv->tick_id = 0;
|
||||
priv->framerate = 0;
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE]);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_ANIMATING]);
|
||||
}
|
||||
|
||||
double
|
||||
gtk_fishbowl_get_framerate (GtkFishbowl *fishbowl)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
return priv->framerate;
|
||||
}
|
||||
|
||||
gint64
|
||||
gtk_fishbowl_get_update_delay (GtkFishbowl *fishbowl)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
return priv->update_delay;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_fishbowl_set_update_delay (GtkFishbowl *fishbowl,
|
||||
gint64 update_delay)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
if (priv->update_delay == update_delay)
|
||||
return;
|
||||
|
||||
priv->update_delay = update_delay;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_UPDATE_DELAY]);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_fishbowl_set_creation_func (GtkFishbowl *fishbowl,
|
||||
GtkFishCreationFunc creation_func)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (fishbowl));
|
||||
|
||||
gtk_fishbowl_set_count (fishbowl, 0);
|
||||
priv->last_benchmark_change = 0;
|
||||
|
||||
priv->creation_func = creation_func;
|
||||
|
||||
gtk_fishbowl_set_count (fishbowl, 1);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (fishbowl));
|
||||
}
|
||||
|
||||
@@ -32,37 +32,29 @@ G_BEGIN_DECLS
|
||||
typedef struct _GtkFishbowl GtkFishbowl;
|
||||
typedef struct _GtkFishbowlClass GtkFishbowlClass;
|
||||
|
||||
typedef GtkWidget * (* GtkFishCreationFunc) (void);
|
||||
|
||||
struct _GtkFishbowl
|
||||
{
|
||||
GtkWidget parent;
|
||||
GtkContainer container;
|
||||
};
|
||||
|
||||
struct _GtkFishbowlClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
GtkContainerClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_fishbowl_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget* gtk_fishbowl_new (void);
|
||||
|
||||
void gtk_fishbowl_set_use_icons (GtkFishbowl *fishbowl,
|
||||
gboolean use_icons);
|
||||
|
||||
guint gtk_fishbowl_get_count (GtkFishbowl *fishbowl);
|
||||
void gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
|
||||
guint count);
|
||||
gboolean gtk_fishbowl_get_animating (GtkFishbowl *fishbowl);
|
||||
void gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
|
||||
gboolean animating);
|
||||
gboolean gtk_fishbowl_get_benchmark (GtkFishbowl *fishbowl);
|
||||
void gtk_fishbowl_set_benchmark (GtkFishbowl *fishbowl,
|
||||
gboolean animating);
|
||||
double gtk_fishbowl_get_framerate (GtkFishbowl *fishbowl);
|
||||
gint64 gtk_fishbowl_get_update_delay (GtkFishbowl *fishbowl);
|
||||
void gtk_fishbowl_set_update_delay (GtkFishbowl *fishbowl,
|
||||
gint64 update_delay);
|
||||
void gtk_fishbowl_set_creation_func (GtkFishbowl *fishbowl,
|
||||
GtkFishCreationFunc creation_func);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -105,14 +105,14 @@ follow_if_link (GtkWidget *text_view,
|
||||
/* Links can be activated by pressing Enter.
|
||||
*/
|
||||
static gboolean
|
||||
key_pressed (GtkEventController *controller,
|
||||
guint keyval,
|
||||
guint keycode,
|
||||
GdkModifierType modifiers,
|
||||
GtkWidget *text_view)
|
||||
key_press_event (GtkWidget *text_view,
|
||||
GdkEventKey *event)
|
||||
{
|
||||
GtkTextIter iter;
|
||||
GtkTextBuffer *buffer;
|
||||
guint keyval;
|
||||
|
||||
gdk_event_get_keyval ((GdkEvent *)event, &keyval);
|
||||
|
||||
switch (keyval)
|
||||
{
|
||||
@@ -128,49 +128,62 @@ key_pressed (GtkEventController *controller,
|
||||
break;
|
||||
}
|
||||
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void set_cursor_if_appropriate (GtkTextView *text_view,
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
static void
|
||||
released_cb (GtkGestureMultiPress *gesture,
|
||||
guint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkWidget *text_view)
|
||||
/* Links can also be activated by clicking or tapping.
|
||||
*/
|
||||
static gboolean
|
||||
event_cb (GtkWidget *text_view,
|
||||
GdkEvent *ev)
|
||||
{
|
||||
GtkTextIter start, end, iter;
|
||||
GtkTextBuffer *buffer;
|
||||
int tx, ty;
|
||||
gdouble ex, ey;
|
||||
int x, y;
|
||||
GdkEventType type;
|
||||
|
||||
if (gtk_gesture_single_get_button (GTK_GESTURE_SINGLE (gesture)) > 1)
|
||||
return;
|
||||
type = gdk_event_get_event_type (ev);
|
||||
|
||||
gdk_event_get_coords (ev, &ex, &ey);
|
||||
gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
|
||||
GTK_TEXT_WINDOW_WIDGET,
|
||||
x, y, &tx, &ty);
|
||||
ex, ey, &x, &y);
|
||||
|
||||
if (type == GDK_BUTTON_RELEASE)
|
||||
{
|
||||
guint button;
|
||||
|
||||
gdk_event_get_button (ev, &button);
|
||||
if (button != GDK_BUTTON_PRIMARY)
|
||||
return FALSE;
|
||||
}
|
||||
else if (type == GDK_MOTION_NOTIFY)
|
||||
{
|
||||
set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y);
|
||||
return FALSE;
|
||||
}
|
||||
else if (type == GDK_TOUCH_END)
|
||||
{
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
|
||||
|
||||
/* we shouldn't follow a link if the user has selected something */
|
||||
gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
|
||||
if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
if (gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y))
|
||||
follow_if_link (text_view, &iter);
|
||||
}
|
||||
|
||||
static void
|
||||
motion_cb (GtkEventControllerMotion *controller,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkTextView *text_view)
|
||||
{
|
||||
set_cursor_if_appropriate (text_view, x, y);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean hovering_over_link = FALSE;
|
||||
@@ -228,7 +241,6 @@ do_hypertext (GtkWidget *do_widget)
|
||||
GtkWidget *view;
|
||||
GtkWidget *sw;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkEventController *controller;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Hypertext");
|
||||
@@ -243,19 +255,10 @@ do_hypertext (GtkWidget *do_widget)
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
|
||||
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 20);
|
||||
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view), 20);
|
||||
controller = gtk_event_controller_key_new ();
|
||||
g_signal_connect (controller, "key-pressed", G_CALLBACK (key_pressed), view);
|
||||
gtk_widget_add_controller (view, controller);
|
||||
|
||||
controller = GTK_EVENT_CONTROLLER (gtk_gesture_multi_press_new ());
|
||||
g_signal_connect (controller, "released",
|
||||
G_CALLBACK (released_cb), view);
|
||||
gtk_widget_add_controller (view, controller);
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "motion",
|
||||
G_CALLBACK (motion_cb), view);
|
||||
gtk_widget_add_controller (view, controller);
|
||||
g_signal_connect (view, "key-press-event",
|
||||
G_CALLBACK (key_press_event), NULL);
|
||||
g_signal_connect (view, "event",
|
||||
G_CALLBACK (event_cb), NULL);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ do_iconview (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
tool_bar = gtk_toolbar_new ();
|
||||
gtk_container_add (GTK_CONTAINER (vbox), tool_bar);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), tool_bar);
|
||||
|
||||
up_button = gtk_tool_button_new (NULL, NULL);
|
||||
gtk_tool_button_set_label (GTK_TOOL_BUTTON (up_button), _("_Up"));
|
||||
@@ -292,7 +292,7 @@ do_iconview (GtkWidget *do_widget)
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_widget_set_vexpand (sw, TRUE);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox), sw);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), sw);
|
||||
|
||||
/* Create the store and fill it with the contents of '/' */
|
||||
parent = g_strdup ("/");
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
/* Images
|
||||
*
|
||||
* GtkImage and GtkPicture are used to display an image; the image can be
|
||||
* in a number of formats.
|
||||
*
|
||||
* GtkImage is the widget used to display icons or images that should be
|
||||
* sized and styled like an icon, while GtkPicture is used for images
|
||||
* that should be displayed as-is.
|
||||
* GtkImage is used to display an image; the image can be in a number of formats.
|
||||
* Typically, you load an image into a GdkPixbuf, then display the pixbuf.
|
||||
*
|
||||
* This demo code shows some of the more obscure cases, in the simple
|
||||
* case a call to gtk_picture_new_for_file() or
|
||||
* gtk_image_new_from_icon_name() is all you need.
|
||||
* case a call to gtk_image_new_from_file() is all you need.
|
||||
*
|
||||
* If you want to put image data in your program as a C variable,
|
||||
* use the make-inline-pixbuf program that comes with GTK+.
|
||||
* This way you won't need to depend on loading external files, your
|
||||
* application binary can be self-contained.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
@@ -27,9 +27,9 @@ progressive_prepared_callback (GdkPixbufLoader *loader,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
GtkWidget *picture;
|
||||
GtkWidget *image;
|
||||
|
||||
picture = GTK_WIDGET (data);
|
||||
image = GTK_WIDGET (data);
|
||||
|
||||
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
|
||||
|
||||
@@ -38,7 +38,7 @@ progressive_prepared_callback (GdkPixbufLoader *loader,
|
||||
*/
|
||||
gdk_pixbuf_fill (pixbuf, 0xaaaaaaff);
|
||||
|
||||
gtk_picture_set_pixbuf (GTK_PICTURE (picture), pixbuf);
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -49,21 +49,21 @@ progressive_updated_callback (GdkPixbufLoader *loader,
|
||||
gint height,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *picture;
|
||||
GtkWidget *image;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
picture = GTK_WIDGET (data);
|
||||
image = GTK_WIDGET (data);
|
||||
|
||||
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
|
||||
gtk_picture_set_pixbuf (GTK_PICTURE (picture), pixbuf);
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
|
||||
}
|
||||
|
||||
static gint
|
||||
progressive_timeout (gpointer data)
|
||||
{
|
||||
GtkWidget *picture;
|
||||
GtkWidget *image;
|
||||
|
||||
picture = GTK_WIDGET (data);
|
||||
image = GTK_WIDGET (data);
|
||||
|
||||
/* This shows off fully-paranoid error handling, so looks scary.
|
||||
* You could factor out the error handling code into a nice separate
|
||||
@@ -241,10 +241,10 @@ progressive_timeout (gpointer data)
|
||||
pixbuf_loader = gdk_pixbuf_loader_new ();
|
||||
|
||||
g_signal_connect (pixbuf_loader, "area-prepared",
|
||||
G_CALLBACK (progressive_prepared_callback), picture);
|
||||
G_CALLBACK (progressive_prepared_callback), image);
|
||||
|
||||
g_signal_connect (pixbuf_loader, "area-updated",
|
||||
G_CALLBACK (progressive_updated_callback), picture);
|
||||
G_CALLBACK (progressive_updated_callback), image);
|
||||
}
|
||||
|
||||
/* leave timeout installed */
|
||||
@@ -252,7 +252,7 @@ progressive_timeout (gpointer data)
|
||||
}
|
||||
|
||||
static void
|
||||
start_progressive_loading (GtkWidget *picture)
|
||||
start_progressive_loading (GtkWidget *image)
|
||||
{
|
||||
/* This is obviously totally contrived (we slow down loading
|
||||
* on purpose to show how incremental loading works).
|
||||
@@ -261,8 +261,8 @@ start_progressive_loading (GtkWidget *picture)
|
||||
* The timeout simply simulates a slow data source by inserting
|
||||
* pauses in the reading process.
|
||||
*/
|
||||
load_timeout = g_timeout_add (150, progressive_timeout, picture);
|
||||
g_source_set_name_by_id (load_timeout, "[gtk] progressive_timeout");
|
||||
load_timeout = g_timeout_add (150, progressive_timeout, image);
|
||||
g_source_set_name_by_id (load_timeout, "[gtk+] progressive_timeout");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -323,10 +323,8 @@ do_images (GtkWidget *do_widget)
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *base_vbox;
|
||||
GtkWidget *image;
|
||||
GtkWidget *picture;
|
||||
GtkWidget *label;
|
||||
GtkWidget *button;
|
||||
GdkPaintable *paintable;
|
||||
GIcon *gicon;
|
||||
|
||||
if (!window)
|
||||
@@ -354,13 +352,13 @@ do_images (GtkWidget *do_widget)
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>Image loaded from a file</u>");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
image = gtk_image_new_from_icon_name ("gtk3-demo");
|
||||
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
|
||||
@@ -373,30 +371,30 @@ 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_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
picture = gtk_picture_new_for_resource ("/images/floppybuddy.gif");
|
||||
image = gtk_image_new_from_resource ("/images/floppybuddy.gif");
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (frame), picture);
|
||||
gtk_container_add (GTK_CONTAINER (frame), image);
|
||||
|
||||
/* Symbolic icon */
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>Symbolic themed icon</u>");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
gicon = g_themed_icon_new_with_default_fallbacks ("battery-caution-charging-symbolic");
|
||||
image = gtk_image_new_from_gicon (gicon);
|
||||
@@ -412,21 +410,21 @@ do_images (GtkWidget *do_widget)
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>Progressive image loading</u>");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
/* Create an empty image for now; the progressive loader
|
||||
* will create the pixbuf and fill it in.
|
||||
*/
|
||||
picture = gtk_picture_new ();
|
||||
gtk_container_add (GTK_CONTAINER (frame), picture);
|
||||
image = gtk_image_new_from_pixbuf (NULL);
|
||||
gtk_container_add (GTK_CONTAINER (frame), image);
|
||||
|
||||
start_progressive_loading (picture);
|
||||
start_progressive_loading (image);
|
||||
|
||||
/* Video */
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
|
||||
@@ -435,36 +433,21 @@ do_images (GtkWidget *do_widget)
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>Displaying video</u>");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (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_container_add (GTK_CONTAINER (frame), video);
|
||||
|
||||
/* Widget paintables */
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), vbox);
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>GtkWidgetPaintable</u>");
|
||||
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_container_add (GTK_CONTAINER (vbox), picture);
|
||||
|
||||
/* Sensitivity control */
|
||||
button = gtk_toggle_button_new_with_mnemonic ("_Insensitive");
|
||||
gtk_container_add (GTK_CONTAINER (base_vbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (base_vbox), button);
|
||||
|
||||
g_signal_connect (button, "toggled",
|
||||
G_CALLBACK (toggle_sensitivity_callback),
|
||||
|
||||
@@ -65,24 +65,24 @@ do_infobar (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
bar = gtk_info_bar_new ();
|
||||
gtk_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_box_pack_start (GTK_BOX (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_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (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_container_add (GTK_CONTAINER (actions), button);
|
||||
|
||||
bar = gtk_info_bar_new ();
|
||||
gtk_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_box_pack_start (GTK_BOX (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_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (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);
|
||||
@@ -91,24 +91,24 @@ do_infobar (GtkWidget *do_widget)
|
||||
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_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_box_pack_start (GTK_BOX (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_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
|
||||
button = gtk_toggle_button_new_with_label ("Question");
|
||||
g_object_bind_property (bar, "revealed", button, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
gtk_container_add (GTK_CONTAINER (actions), button);
|
||||
|
||||
bar = gtk_info_bar_new ();
|
||||
gtk_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_box_pack_start (GTK_BOX (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_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (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);
|
||||
@@ -116,12 +116,12 @@ do_infobar (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (actions), button);
|
||||
|
||||
bar = gtk_info_bar_new ();
|
||||
gtk_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_box_pack_start (GTK_BOX (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_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (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);
|
||||
@@ -130,7 +130,7 @@ do_infobar (GtkWidget *do_widget)
|
||||
frame = gtk_frame_new ("Info bars");
|
||||
gtk_widget_set_margin_top (frame, 8);
|
||||
gtk_widget_set_margin_bottom (frame, 8);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
|
||||
g_object_set (vbox2, "margin", 8, NULL);
|
||||
@@ -138,9 +138,9 @@ do_infobar (GtkWidget *do_widget)
|
||||
|
||||
/* Standard message dialog */
|
||||
label = gtk_label_new ("An example of different info bars");
|
||||
gtk_container_add (GTK_CONTAINER (vbox2), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox2), label);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox2), actions);
|
||||
gtk_box_pack_start (GTK_BOX (vbox2), actions);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <locale.h>
|
||||
#include <langinfo.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <glib.h>
|
||||
@@ -174,9 +173,9 @@ languages_variant_init (const char *variant)
|
||||
{
|
||||
gboolean res;
|
||||
gsize buf_len;
|
||||
char *buf = NULL;
|
||||
char *filename = NULL;
|
||||
GError *error = NULL;
|
||||
g_autofree char *buf = NULL;
|
||||
g_autofree char *filename = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
bindtextdomain (variant, ISO_CODES_LOCALESDIR);
|
||||
bind_textdomain_codeset (variant, "UTF-8");
|
||||
@@ -186,25 +185,19 @@ languages_variant_init (const char *variant)
|
||||
res = g_file_get_contents (filename, &buf, &buf_len, &error);
|
||||
if (res)
|
||||
{
|
||||
GMarkupParseContext *ctx = NULL;
|
||||
g_autoptr (GMarkupParseContext) ctx = NULL;
|
||||
GMarkupParser parser = { languages_parse_start_tag, NULL, NULL, NULL, NULL };
|
||||
|
||||
ctx = g_markup_parse_context_new (&parser, 0, NULL, NULL);
|
||||
|
||||
g_free (error);
|
||||
error = NULL;
|
||||
res = g_markup_parse_context_parse (ctx, buf, buf_len, &error);
|
||||
g_free (ctx);
|
||||
|
||||
if (!res)
|
||||
g_warning ("Failed to parse '%s': %s\n", filename, error->message);
|
||||
}
|
||||
else
|
||||
g_warning ("Failed to load '%s': %s\n", filename, error->message);
|
||||
|
||||
g_free (error);
|
||||
g_free (filename);
|
||||
g_free (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -268,7 +268,7 @@ do_list_store (GtkWidget *do_widget)
|
||||
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_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
|
||||
@@ -276,7 +276,7 @@ do_list_store (GtkWidget *do_widget)
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), sw);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), sw);
|
||||
|
||||
/* create tree model */
|
||||
model = create_model ();
|
||||
|
||||
@@ -361,12 +361,12 @@ do_listbox (GtkWidget *do_widget)
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
label = gtk_label_new ("Messages from GTK and friends");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
label = gtk_label_new ("Messages from Gtk+ and friends");
|
||||
gtk_box_pack_start (GTK_BOX (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_container_add (GTK_CONTAINER (vbox), scrolled);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), scrolled);
|
||||
listbox = gtk_list_box_new ();
|
||||
gtk_container_add (GTK_CONTAINER (scrolled), listbox);
|
||||
|
||||
|
||||
@@ -67,6 +67,9 @@
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="short_time_label">
|
||||
@@ -76,6 +79,10 @@
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
@@ -111,6 +118,9 @@
|
||||
<object class="GtkLabel" id="label4">
|
||||
<property name="label" translatable="yes">Resent by</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLinkButton" id="resent_by_button">
|
||||
@@ -120,6 +130,9 @@
|
||||
<property name="relief">none</property>
|
||||
<property name="uri">http://www.gtk.org</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
@@ -141,7 +154,6 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="extra_buttons_box">
|
||||
<property name="visible">0</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="reply-button">
|
||||
@@ -159,6 +171,9 @@
|
||||
<property name="relief">none</property>
|
||||
<signal name="clicked" handler="reshare_clicked" swapped="yes"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="favorite-buttton">
|
||||
@@ -168,6 +183,9 @@
|
||||
<property name="relief">none</property>
|
||||
<signal name="clicked" handler="favorite_clicked" swapped="yes"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton" id="more-button">
|
||||
@@ -181,8 +199,14 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
@@ -225,8 +249,14 @@ FAVORITES</property>
|
||||
</child>
|
||||
<child type="label_item"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box6">
|
||||
@@ -248,8 +278,14 @@ FAVORITES</property>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -42,24 +42,24 @@ activate_about (GSimpleAction *action,
|
||||
{
|
||||
GtkApplication *app = user_data;
|
||||
const gchar *authors[] = {
|
||||
"The GTK Team",
|
||||
"The GTK+ Team",
|
||||
NULL
|
||||
};
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
|
||||
"program-name", "GTK Demo",
|
||||
"version", g_strdup_printf ("%s,\nRunning against GTK %d.%d.%d",
|
||||
"program-name", "GTK+ Demo",
|
||||
"version", g_strdup_printf ("%s,\nRunning against GTK+ %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ()),
|
||||
"copyright", "(C) 1997-2013 The GTK Team",
|
||||
"copyright", "(C) 1997-2013 The GTK+ Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK widgets",
|
||||
"comments", "Program to demonstrate GTK+ widgets",
|
||||
"authors", authors,
|
||||
"logo-icon-name", "gtk4-demo",
|
||||
"title", "About GTK Demo",
|
||||
"logo-icon-name", "gtk3-demo",
|
||||
"title", "About GTK+ Demo",
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -532,106 +532,7 @@ fontify (GtkTextBuffer *source_buffer)
|
||||
}
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
display_image (const char *resource)
|
||||
{
|
||||
GtkWidget *sw, *image;
|
||||
|
||||
image = gtk_image_new_from_resource (resource);
|
||||
gtk_widget_set_halign (image, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (image, GTK_ALIGN_CENTER);
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (sw), image);
|
||||
|
||||
return sw;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
display_text (const char *resource)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkWidget *textview, *sw;
|
||||
GBytes *bytes;
|
||||
|
||||
bytes = g_resources_lookup_data (resource, 0, NULL);
|
||||
g_assert (bytes);
|
||||
|
||||
g_assert (g_utf8_validate (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL));
|
||||
|
||||
textview = gtk_text_view_new ();
|
||||
g_object_set (textview,
|
||||
"left-margin", 20,
|
||||
"right-margin", 20,
|
||||
"top-margin", 20,
|
||||
"bottom-margin", 20,
|
||||
NULL);
|
||||
gtk_text_view_set_editable (GTK_TEXT_VIEW (textview), FALSE);
|
||||
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (textview), FALSE);
|
||||
/* Make it a bit nicer for text. */
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (textview), GTK_WRAP_WORD);
|
||||
gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (textview), 2);
|
||||
gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (textview), 2);
|
||||
|
||||
buffer = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_set_text (buffer, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
|
||||
if (g_str_has_suffix (resource, ".c"))
|
||||
fontify (buffer);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_SHADOW_NONE);
|
||||
gtk_container_add (GTK_CONTAINER (sw), textview);
|
||||
|
||||
return sw;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
display_video (const char *resource)
|
||||
{
|
||||
GtkWidget *video;
|
||||
|
||||
video = gtk_video_new_for_resource (resource);
|
||||
gtk_video_set_loop (GTK_VIDEO (video), TRUE);
|
||||
|
||||
return video;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
display_nothing (const char *resource)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
char *str;
|
||||
|
||||
str = g_strdup_printf ("The lazy GTK developers forgot to add a way to display the resource '%s'", resource);
|
||||
widget = gtk_label_new (str);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
|
||||
|
||||
g_free (str);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
static struct {
|
||||
const char *extension;
|
||||
GtkWidget * (* display_func) (const char *resource);
|
||||
} display_funcs[] = {
|
||||
{ ".gif", display_image },
|
||||
{ ".jpg", display_image },
|
||||
{ ".png", display_image },
|
||||
{ ".c", display_text },
|
||||
{ ".css", display_text },
|
||||
{ ".glsl", display_text },
|
||||
{ ".h", display_text },
|
||||
{ ".txt", display_text },
|
||||
{ ".ui", display_text },
|
||||
{ ".webm", display_video }
|
||||
};
|
||||
static GtkWidget *create_text (GtkWidget **text_view, gboolean is_source);
|
||||
|
||||
static void
|
||||
add_data_tab (const gchar *demoname)
|
||||
@@ -639,7 +540,7 @@ add_data_tab (const gchar *demoname)
|
||||
gchar *resource_dir, *resource_name;
|
||||
gchar **resources;
|
||||
GtkWidget *widget, *label;
|
||||
guint i, j;
|
||||
guint i;
|
||||
|
||||
resource_dir = g_strconcat ("/", demoname, NULL);
|
||||
resources = g_resources_enumerate_children (resource_dir, 0, NULL);
|
||||
@@ -653,22 +554,58 @@ add_data_tab (const gchar *demoname)
|
||||
{
|
||||
resource_name = g_strconcat (resource_dir, "/", resources[i], NULL);
|
||||
|
||||
for (j = 0; j < G_N_ELEMENTS(display_funcs); j++)
|
||||
widget = gtk_image_new_from_resource (resource_name);
|
||||
if (gtk_image_get_paintable (GTK_IMAGE (widget)) == NULL)
|
||||
{
|
||||
if (g_str_has_suffix (resource_name, display_funcs[j].extension))
|
||||
break;
|
||||
GBytes *bytes;
|
||||
|
||||
/* So we've used the best API available to figure out it's
|
||||
* not an image. Let's try something else then.
|
||||
*/
|
||||
g_object_ref_sink (widget);
|
||||
g_object_unref (widget);
|
||||
|
||||
bytes = g_resources_lookup_data (resource_name, 0, NULL);
|
||||
g_assert (bytes);
|
||||
|
||||
if (g_utf8_validate (g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), NULL))
|
||||
{
|
||||
/* Looks like it parses as text. Dump it into a textview then! */
|
||||
GtkTextBuffer *buffer;
|
||||
GtkWidget *textview;
|
||||
|
||||
widget = create_text (&textview, FALSE);
|
||||
buffer = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_set_text (buffer, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
|
||||
if (g_str_has_suffix (resource_name, ".c"))
|
||||
fontify (buffer);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Don't know how to display resource '%s'", resource_name);
|
||||
widget = NULL;
|
||||
}
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
}
|
||||
|
||||
if (j < G_N_ELEMENTS(display_funcs))
|
||||
widget = display_funcs[j].display_func (resource_name);
|
||||
else
|
||||
widget = display_nothing (resource_name);
|
||||
if (GTK_IS_IMAGE (widget))
|
||||
{
|
||||
GtkWidget *sw;
|
||||
|
||||
gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (sw), widget);
|
||||
widget = sw;
|
||||
}
|
||||
|
||||
label = gtk_label_new (resources[i]);
|
||||
gtk_widget_show (label);
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), widget, label);
|
||||
gtk_container_child_set (GTK_CONTAINER (notebook),
|
||||
widget,
|
||||
GTK_WIDGET (widget),
|
||||
"tab-expand", TRUE,
|
||||
NULL);
|
||||
|
||||
@@ -831,14 +768,15 @@ load_file (const gchar *demoname,
|
||||
/* Skipping blank lines */
|
||||
while (g_ascii_isspace (*p))
|
||||
p++;
|
||||
|
||||
if (!*p)
|
||||
if (*p)
|
||||
{
|
||||
p = lines[i];
|
||||
state++;
|
||||
/* Fall through */
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
p = lines[i];
|
||||
state++;
|
||||
/* Fall through */
|
||||
|
||||
case 3:
|
||||
/* Reading program body */
|
||||
gtk_text_buffer_insert (source_buffer, &start, p, -1);
|
||||
@@ -887,6 +825,49 @@ selection_cb (GtkTreeSelection *selection,
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_text (GtkWidget **view,
|
||||
gboolean is_source)
|
||||
{
|
||||
GtkWidget *scrolled_window;
|
||||
GtkWidget *text_view;
|
||||
|
||||
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
|
||||
GTK_SHADOW_NONE);
|
||||
|
||||
*view = text_view = gtk_text_view_new ();
|
||||
g_object_set (text_view,
|
||||
"left-margin", 20,
|
||||
"right-margin", 20,
|
||||
"top-margin", 20,
|
||||
"bottom-margin", 20,
|
||||
NULL);
|
||||
|
||||
gtk_text_view_set_editable (GTK_TEXT_VIEW (text_view), FALSE);
|
||||
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (text_view), FALSE);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (scrolled_window), text_view);
|
||||
|
||||
if (is_source)
|
||||
{
|
||||
gtk_text_view_set_monospace (GTK_TEXT_VIEW (text_view), TRUE);
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view), GTK_WRAP_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make it a bit nicer for text. */
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view), GTK_WRAP_WORD);
|
||||
gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (text_view), 2);
|
||||
gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (text_view), 2);
|
||||
}
|
||||
|
||||
return scrolled_window;
|
||||
}
|
||||
|
||||
static void
|
||||
populate_model (GtkTreeModel *model)
|
||||
{
|
||||
|
||||
@@ -16,10 +16,9 @@
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="window">
|
||||
<style><class name="devel"/></style>
|
||||
<property name="default-width">800</property>
|
||||
<property name="default-height">600</property>
|
||||
<property name="title">GTK Demo</property>
|
||||
<property name="title">GTK+ Demo</property>
|
||||
<signal name="destroy" handler="gtk_main_quit" swapped="no"/>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="headerbar">
|
||||
@@ -152,6 +151,9 @@
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -115,7 +115,7 @@ do_menus (GtkWidget *do_widget)
|
||||
|
||||
menubar = gtk_menu_bar_new ();
|
||||
gtk_widget_set_hexpand (menubar, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (box1), menubar);
|
||||
gtk_box_pack_start (GTK_BOX (box1), menubar);
|
||||
gtk_widget_show (menubar);
|
||||
|
||||
menu = create_menu (2);
|
||||
@@ -136,19 +136,19 @@ do_menus (GtkWidget *do_widget)
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_container_add (GTK_CONTAINER (box1), box2);
|
||||
gtk_box_pack_start (GTK_BOX (box1), box2);
|
||||
gtk_widget_show (box2);
|
||||
|
||||
button = gtk_button_new_with_label ("Flip");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (change_orientation), menubar);
|
||||
gtk_container_add (GTK_CONTAINER (box2), button);
|
||||
gtk_box_pack_start (GTK_BOX (box2), button);
|
||||
gtk_widget_show (button);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK(gtk_widget_destroy), window);
|
||||
gtk_container_add (GTK_CONTAINER (box2), button);
|
||||
gtk_box_pack_start (GTK_BOX (box2), button);
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
gtk_widget_grab_default (button);
|
||||
gtk_widget_show (button);
|
||||
|
||||
@@ -4,6 +4,7 @@ demos = files([
|
||||
'application_demo.c',
|
||||
'assistant.c',
|
||||
'builder.c',
|
||||
'button_box.c',
|
||||
'changedisplay.c',
|
||||
'clipboard.c',
|
||||
'colorsel.c',
|
||||
@@ -21,9 +22,11 @@ demos = files([
|
||||
'editable_cells.c',
|
||||
'entry_buffer.c',
|
||||
'entry_completion.c',
|
||||
'event_axes.c',
|
||||
'expander.c',
|
||||
'filtermodel.c',
|
||||
'fishbowl.c',
|
||||
'widgetbowl.c',
|
||||
'foreigndrawing.c',
|
||||
'gestures.c',
|
||||
'glarea.c',
|
||||
@@ -42,7 +45,6 @@ demos = files([
|
||||
'modelbutton.c',
|
||||
'overlay.c',
|
||||
'overlay2.c',
|
||||
'paint.c',
|
||||
'paintable.c',
|
||||
'paintable_animated.c',
|
||||
'paintable_mediastream.c',
|
||||
@@ -59,7 +61,6 @@ demos = files([
|
||||
'shortcuts.c',
|
||||
'sidebar.c',
|
||||
'sizegroup.c',
|
||||
'sliding_puzzle.c',
|
||||
'spinbutton.c',
|
||||
'spinner.c',
|
||||
'stack.c',
|
||||
@@ -75,11 +76,8 @@ demos = files([
|
||||
|
||||
gtkdemo_deps = [ libgtk_dep, ]
|
||||
|
||||
extra_demo_sources = files(['main.c', 'gtkfishbowl.c', 'fontplane.c', 'gtkgears.c', 'puzzlepiece.c'])
|
||||
|
||||
if harfbuzz_dep.found() and pangoft_dep.found()
|
||||
demos += files('font_features.c')
|
||||
extra_demo_sources += files(['script-names.c', 'language-names.c'])
|
||||
gtkdemo_deps += [ harfbuzz_dep, ]
|
||||
endif
|
||||
|
||||
@@ -99,12 +97,13 @@ gtkdemo_resources = gnome.compile_resources('gtkdemo_resources',
|
||||
source_dir: '.')
|
||||
|
||||
executable('gtk4-demo',
|
||||
demos, demos_h, extra_demo_sources, gtkdemo_resources,
|
||||
'main.c', 'gtkfishbowl.c', 'fontplane.c', 'script-names.c', 'language-names.c',
|
||||
'gtkgears.c',
|
||||
demos, demos_h, gtkdemo_resources,
|
||||
c_args: gtkdemo_args,
|
||||
dependencies: gtkdemo_deps,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true)
|
||||
|
||||
executable('gtk4-demo-application',
|
||||
@@ -113,7 +112,6 @@ executable('gtk4-demo-application',
|
||||
dependencies: gtkdemo_deps,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true)
|
||||
|
||||
# icons
|
||||
@@ -128,11 +126,11 @@ foreach icon_size: [ '16x16', '22x22', '24x24', '32x32', '48x48', '256x256', ]
|
||||
endforeach
|
||||
|
||||
# desktop file
|
||||
install_data('org.gtk.Demo.desktop', install_dir: gtk_applicationsdir)
|
||||
install_data('gtk4-demo.desktop', install_dir: gtk_applicationsdir)
|
||||
|
||||
# GSettings
|
||||
install_data('org.gtk.Demo.gschema.xml', install_dir: gtk_schemasdir)
|
||||
gnome.compile_schemas()
|
||||
|
||||
# appdata
|
||||
install_data('org.gtk.Demo.appdata.xml', install_dir: gtk_appdatadir)
|
||||
install_data('org.gtk.Demo.appdata.xml', install_dir: gtk_appdatadir)
|
||||
@@ -56,7 +56,6 @@
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="action-name">win.color</property>
|
||||
<property name="action-target">'red'</property>
|
||||
<property name="text">Red</property>
|
||||
<property name="inverted">1</property>
|
||||
</object>
|
||||
@@ -64,7 +63,6 @@
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="action-name">win.color</property>
|
||||
<property name="action-target">'green'</property>
|
||||
<property name="text">Green</property>
|
||||
<property name="inverted">1</property>
|
||||
</object>
|
||||
@@ -72,7 +70,6 @@
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="action-name">win.color</property>
|
||||
<property name="action-target">'blue'</property>
|
||||
<property name="text">Blue</property>
|
||||
<property name="inverted">1</property>
|
||||
</object>
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
<id>org.gtk.Demo.desktop</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<name>GTK Demo</name>
|
||||
<summary>Program to demonstrate GTK functions</summary>
|
||||
<name>GTK+ Demo</name>
|
||||
<summary>Program to demonstrate GTK+ functions</summary>
|
||||
<description>
|
||||
<p>
|
||||
GTK Demo is a collection of examples that demonstrate the major
|
||||
features of the GTK toolkit.
|
||||
GTK+ Demo is a collection of examples that demonstrate the major
|
||||
features of the GTK+ toolkit.
|
||||
</p>
|
||||
</description>
|
||||
<screenshots>
|
||||
@@ -30,4 +30,4 @@
|
||||
<translation type="gettext">gtk-4.0</translation>
|
||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||
<developer_name>Matthias Clasen and others</developer_name>
|
||||
</component>
|
||||
</component>
|
||||
@@ -65,7 +65,7 @@ do_overlay (GtkWidget *do_widget)
|
||||
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
||||
gtk_widget_set_margin_top (label, 8);
|
||||
gtk_widget_set_margin_bottom (label, 50);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), vbox);
|
||||
@@ -74,7 +74,7 @@ do_overlay (GtkWidget *do_widget)
|
||||
gtk_entry_set_placeholder_text (GTK_ENTRY (entry), "Your Lucky Number");
|
||||
gtk_widget_set_margin_top (entry, 50);
|
||||
gtk_widget_set_margin_bottom (entry, 8);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), entry);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), entry);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (window), overlay);
|
||||
|
||||
|
||||
@@ -1,412 +0,0 @@
|
||||
/* Paint
|
||||
*
|
||||
* Demonstrates practical handling of drawing tablets in a real world
|
||||
* usecase.
|
||||
*/
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
enum {
|
||||
COLOR_SET,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
static guint area_signals[N_SIGNALS] = { 0, };
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
GdkRGBA draw_color;
|
||||
GtkPadController *pad_controller;
|
||||
gdouble brush_size;
|
||||
} DrawingArea;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
} DrawingAreaClass;
|
||||
|
||||
static GtkPadActionEntry pad_actions[] = {
|
||||
{ GTK_PAD_ACTION_BUTTON, 1, -1, N_("Black"), "pad.black" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 2, -1, N_("Pink"), "pad.pink" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 3, -1, N_("Green"), "pad.green" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 4, -1, N_("Red"), "pad.red" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 5, -1, N_("Purple"), "pad.purple" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 6, -1, N_("Orange"), "pad.orange" },
|
||||
{ GTK_PAD_ACTION_STRIP, -1, -1, N_("Brush size"), "pad.brush_size" },
|
||||
};
|
||||
|
||||
static const gchar *pad_colors[] = {
|
||||
"black",
|
||||
"pink",
|
||||
"green",
|
||||
"red",
|
||||
"purple",
|
||||
"orange"
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (DrawingArea, drawing_area, GTK_TYPE_WIDGET)
|
||||
|
||||
static void drawing_area_set_color (DrawingArea *area,
|
||||
GdkRGBA *color);
|
||||
|
||||
static void
|
||||
drawing_area_ensure_surface (DrawingArea *area,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
if (!area->surface ||
|
||||
cairo_image_surface_get_width (area->surface) != width ||
|
||||
cairo_image_surface_get_height (area->surface) != height)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
width, height);
|
||||
if (area->surface)
|
||||
{
|
||||
cairo_t *cr;
|
||||
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_source_surface (cr, area->surface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_surface_destroy (area->surface);
|
||||
cairo_destroy (area->cr);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
area->surface = surface;
|
||||
area->cr = cairo_create (surface);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
DrawingArea *area = (DrawingArea *) widget;
|
||||
|
||||
drawing_area_ensure_surface (area, width, height);
|
||||
|
||||
GTK_WIDGET_CLASS (drawing_area_parent_class)->size_allocate (widget, width, height, baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_map (GtkWidget *widget)
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
|
||||
GTK_WIDGET_CLASS (drawing_area_parent_class)->map (widget);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
drawing_area_ensure_surface ((DrawingArea *) widget,
|
||||
allocation.width, allocation.height);
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_unmap (GtkWidget *widget)
|
||||
{
|
||||
DrawingArea *area = (DrawingArea *) widget;
|
||||
|
||||
g_clear_pointer (&area->cr, cairo_destroy);
|
||||
g_clear_pointer (&area->surface, cairo_surface_destroy);
|
||||
|
||||
GTK_WIDGET_CLASS (drawing_area_parent_class)->unmap (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
DrawingArea *area = (DrawingArea *) widget;
|
||||
GtkAllocation allocation;
|
||||
cairo_t *cr;
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
cr = gtk_snapshot_append_cairo (snapshot,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
0, 0,
|
||||
allocation.width,
|
||||
allocation.height
|
||||
));
|
||||
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_set_source_surface (cr, area->surface, 0, 0);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_set_source_rgb (cr, 0.6, 0.6, 0.6);
|
||||
cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
on_pad_button_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
DrawingArea *area)
|
||||
{
|
||||
const gchar *color = g_object_get_data (G_OBJECT (action), "color");
|
||||
GdkRGBA rgba;
|
||||
|
||||
gdk_rgba_parse (&rgba, color);
|
||||
drawing_area_set_color (area, &rgba);
|
||||
}
|
||||
|
||||
static void
|
||||
on_pad_knob_change (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
DrawingArea *area)
|
||||
{
|
||||
gdouble value = g_variant_get_double (parameter);
|
||||
|
||||
area->brush_size = value;
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_hierarchy_changed (GtkWidget *widget,
|
||||
GtkWidget *previous_toplevel)
|
||||
{
|
||||
DrawingArea *area = (DrawingArea *) widget;
|
||||
GSimpleActionGroup *action_group;
|
||||
GSimpleAction *action;
|
||||
GtkWidget *toplevel;
|
||||
gint i;
|
||||
|
||||
if (previous_toplevel && area->pad_controller)
|
||||
{
|
||||
gtk_widget_remove_controller (previous_toplevel,
|
||||
GTK_EVENT_CONTROLLER (area->pad_controller));
|
||||
area->pad_controller = NULL;
|
||||
}
|
||||
|
||||
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (area));
|
||||
if (!GTK_IS_WINDOW (toplevel))
|
||||
return;
|
||||
|
||||
action_group = g_simple_action_group_new ();
|
||||
area->pad_controller = gtk_pad_controller_new (G_ACTION_GROUP (action_group),
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (pad_actions); i++)
|
||||
{
|
||||
if (pad_actions[i].type == GTK_PAD_ACTION_BUTTON)
|
||||
{
|
||||
action = g_simple_action_new (pad_actions[i].action_name, NULL);
|
||||
g_object_set_data (G_OBJECT (action), "color",
|
||||
(gpointer) pad_colors[i]);
|
||||
g_signal_connect (action, "activate",
|
||||
G_CALLBACK (on_pad_button_activate), area);
|
||||
}
|
||||
else
|
||||
{
|
||||
action = g_simple_action_new_stateful (pad_actions[i].action_name,
|
||||
G_VARIANT_TYPE_DOUBLE, NULL);
|
||||
g_signal_connect (action, "activate",
|
||||
G_CALLBACK (on_pad_knob_change), area);
|
||||
}
|
||||
|
||||
g_action_map_add_action (G_ACTION_MAP (action_group), G_ACTION (action));
|
||||
g_object_unref (action);
|
||||
}
|
||||
|
||||
gtk_pad_controller_set_action_entries (area->pad_controller, pad_actions,
|
||||
G_N_ELEMENTS (pad_actions));
|
||||
|
||||
gtk_widget_add_controller (toplevel,
|
||||
GTK_EVENT_CONTROLLER (area->pad_controller));
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_class_init (DrawingAreaClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->size_allocate = drawing_area_size_allocate;
|
||||
widget_class->snapshot = drawing_area_snapshot;
|
||||
widget_class->map = drawing_area_map;
|
||||
widget_class->unmap = drawing_area_unmap;
|
||||
widget_class->hierarchy_changed = drawing_area_hierarchy_changed;
|
||||
|
||||
area_signals[COLOR_SET] =
|
||||
g_signal_new ("color-set",
|
||||
G_TYPE_FROM_CLASS (widget_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, GDK_TYPE_RGBA);
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_apply_stroke (DrawingArea *area,
|
||||
GdkDeviceTool *tool,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gdouble pressure)
|
||||
{
|
||||
if (gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER)
|
||||
{
|
||||
cairo_set_line_width (area->cr, 10 * pressure * area->brush_size);
|
||||
cairo_set_operator (area->cr, CAIRO_OPERATOR_DEST_OUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_set_line_width (area->cr, 4 * pressure * area->brush_size);
|
||||
cairo_set_operator (area->cr, CAIRO_OPERATOR_SATURATE);
|
||||
}
|
||||
|
||||
cairo_set_source_rgba (area->cr, area->draw_color.red,
|
||||
area->draw_color.green, area->draw_color.blue,
|
||||
area->draw_color.alpha * pressure);
|
||||
|
||||
cairo_line_to (area->cr, x, y);
|
||||
cairo_stroke (area->cr);
|
||||
cairo_move_to (area->cr, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
stylus_gesture_down (GtkGestureStylus *gesture,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
DrawingArea *area)
|
||||
{
|
||||
cairo_new_path (area->cr);
|
||||
}
|
||||
|
||||
static void
|
||||
stylus_gesture_motion (GtkGestureStylus *gesture,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
DrawingArea *area)
|
||||
{
|
||||
GdkTimeCoord *backlog;
|
||||
GdkDeviceTool *tool;
|
||||
gdouble pressure;
|
||||
guint n_items;
|
||||
|
||||
tool = gtk_gesture_stylus_get_device_tool (gesture);
|
||||
|
||||
if (gtk_gesture_stylus_get_backlog (gesture, &backlog, &n_items))
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < n_items; i++)
|
||||
{
|
||||
drawing_area_apply_stroke (area, tool,
|
||||
backlog[i].axes[GDK_AXIS_X],
|
||||
backlog[i].axes[GDK_AXIS_Y],
|
||||
backlog[i].axes[GDK_AXIS_PRESSURE]);
|
||||
}
|
||||
|
||||
g_free (backlog);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!gtk_gesture_stylus_get_axis (gesture, GDK_AXIS_PRESSURE, &pressure))
|
||||
pressure = 1;
|
||||
|
||||
drawing_area_apply_stroke (area, tool, x, y, pressure);
|
||||
}
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (area));
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_init (DrawingArea *area)
|
||||
{
|
||||
GtkGesture *gesture;
|
||||
|
||||
gtk_widget_set_has_surface (GTK_WIDGET (area), FALSE);
|
||||
|
||||
gesture = gtk_gesture_stylus_new ();
|
||||
g_signal_connect (gesture, "down",
|
||||
G_CALLBACK (stylus_gesture_down), area);
|
||||
g_signal_connect (gesture, "motion",
|
||||
G_CALLBACK (stylus_gesture_motion), area);
|
||||
gtk_widget_add_controller (GTK_WIDGET (area), GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
area->draw_color = (GdkRGBA) { 0, 0, 0, 1 };
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
drawing_area_new (void)
|
||||
{
|
||||
return g_object_new (drawing_area_get_type (), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_set_color (DrawingArea *area,
|
||||
GdkRGBA *color)
|
||||
{
|
||||
if (gdk_rgba_equal (&area->draw_color, color))
|
||||
return;
|
||||
|
||||
area->draw_color = *color;
|
||||
g_signal_emit (area, area_signals[COLOR_SET], 0, &area->draw_color);
|
||||
}
|
||||
|
||||
static void
|
||||
color_button_color_set (GtkColorButton *button,
|
||||
DrawingArea *draw_area)
|
||||
{
|
||||
GdkRGBA color;
|
||||
|
||||
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (button), &color);
|
||||
drawing_area_set_color (draw_area, &color);
|
||||
}
|
||||
|
||||
static void
|
||||
drawing_area_color_set (DrawingArea *area,
|
||||
GdkRGBA *color,
|
||||
GtkColorButton *button)
|
||||
{
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (button), color);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_paint (GtkWidget *toplevel)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *draw_area, *headerbar, *colorbutton;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
draw_area = drawing_area_new ();
|
||||
gtk_container_add (GTK_CONTAINER (window), draw_area);
|
||||
|
||||
headerbar = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar), "Paint");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (headerbar), TRUE);
|
||||
|
||||
colorbutton = gtk_color_button_new ();
|
||||
g_signal_connect (colorbutton, "color-set",
|
||||
G_CALLBACK (color_button_color_set), draw_area);
|
||||
g_signal_connect (draw_area, "color-set",
|
||||
G_CALLBACK (drawing_area_color_set), colorbutton);
|
||||
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (colorbutton),
|
||||
&(GdkRGBA) { 0, 0, 0, 1 });
|
||||
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (headerbar), colorbutton);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), headerbar);
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -56,13 +56,15 @@ gtk_nuclear_snapshot (GtkSnapshot *snapshot,
|
||||
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
&(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 },
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height),
|
||||
"Yellow background");
|
||||
|
||||
size = MIN (width, height);
|
||||
cr = gtk_snapshot_append_cairo (snapshot,
|
||||
&GRAPHENE_RECT_INIT ((width - size) / 2.0,
|
||||
(height - size) / 2.0,
|
||||
size, size));
|
||||
size, size),
|
||||
"Radioactive Icon");
|
||||
cairo_translate (cr, width / 2.0, height / 2.0);
|
||||
cairo_scale (cr, size, size);
|
||||
cairo_rotate (cr, rotation);
|
||||
|
||||
@@ -148,7 +148,7 @@ do_panes (GtkWidget *do_widget)
|
||||
|
||||
vpaned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
||||
g_object_set (vpaned, "margin", 5, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), vpaned);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), vpaned);
|
||||
|
||||
hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
|
||||
@@ -173,13 +173,13 @@ do_panes (GtkWidget *do_widget)
|
||||
|
||||
/* Now create toggle buttons to control sizing */
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox),
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
create_pane_options (GTK_PANED (hpaned),
|
||||
"Horizontal",
|
||||
"Left",
|
||||
"Right"));
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox),
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
create_pane_options (GTK_PANED (vpaned),
|
||||
"Vertical",
|
||||
"Top",
|
||||
|
||||
@@ -55,11 +55,11 @@ create_complex_popover (GtkWidget *parent,
|
||||
}
|
||||
|
||||
static void
|
||||
entry_size_allocate_cb (GtkEntry *entry,
|
||||
int width,
|
||||
int height,
|
||||
int baseline,
|
||||
gpointer user_data)
|
||||
entry_size_allocate_cb (GtkEntry *entry,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkEntryIconPosition popover_pos;
|
||||
GtkPopover *popover = user_data;
|
||||
@@ -78,6 +78,7 @@ entry_size_allocate_cb (GtkEntry *entry,
|
||||
static void
|
||||
entry_icon_press_cb (GtkEntry *entry,
|
||||
GtkEntryIconPosition icon_pos,
|
||||
GdkEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *popover = user_data;
|
||||
@@ -119,7 +120,7 @@ day_selected_cb (GtkCalendar *calendar,
|
||||
|
||||
gtk_widget_show (popover);
|
||||
|
||||
g_object_unref (event);
|
||||
gdk_event_free (event);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
|
||||
@@ -81,6 +81,9 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -1,220 +0,0 @@
|
||||
/* Paintable/A simple paintable
|
||||
*
|
||||
* GdkPaintable is an interface used by GTK for drawings of any sort
|
||||
* that do not require layouting or positioning.
|
||||
*
|
||||
* This demo code gives a simple example on how a paintable can
|
||||
* be created.
|
||||
*
|
||||
* Paintables can be used in many places inside GTK widgets, but the
|
||||
* most common usage is inside GtkImage and that's what we're going
|
||||
* to do here.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "puzzlepiece.h"
|
||||
|
||||
/* Declare the struct. */
|
||||
struct _GtkPuzzlePiece
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GdkPaintable *puzzle;
|
||||
guint x;
|
||||
guint y;
|
||||
guint width;
|
||||
guint height;
|
||||
};
|
||||
|
||||
struct _GtkPuzzlePieceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
/* This is the function that draws the puzzle piece.
|
||||
* It just draws a rectangular cutout of the puzzle by clipping
|
||||
* away the rest.
|
||||
*/
|
||||
static void
|
||||
gtk_puzzle_piece_snapshot (GdkPaintable *paintable,
|
||||
GdkSnapshot *snapshot,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
GtkPuzzlePiece *self = GTK_PUZZLE_PIECE (paintable);
|
||||
|
||||
gtk_snapshot_push_clip (snapshot,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
|
||||
gtk_snapshot_offset (snapshot,
|
||||
- width * self->x,
|
||||
- height * self->y);
|
||||
gdk_paintable_snapshot (self->puzzle,
|
||||
snapshot,
|
||||
width * self->width,
|
||||
height * self->height);
|
||||
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
static GdkPaintableFlags
|
||||
gtk_puzzle_piece_get_flags (GdkPaintable *paintable)
|
||||
{
|
||||
GtkPuzzlePiece *self = GTK_PUZZLE_PIECE (paintable);
|
||||
|
||||
/* The flags are the same as the ones of the puzzle.
|
||||
* If the puzzle changes in some way, so do the pieces.
|
||||
*/
|
||||
return gdk_paintable_get_flags (self->puzzle);
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_puzzle_piece_get_intrinsic_width (GdkPaintable *paintable)
|
||||
{
|
||||
GtkPuzzlePiece *self = GTK_PUZZLE_PIECE (paintable);
|
||||
|
||||
/* We can compute our width relative to the puzzle.
|
||||
* This logic even works for the case where the puzzle
|
||||
* has no width, because the 0 return value is unchanged.
|
||||
* Round up the value.
|
||||
*/
|
||||
return (gdk_paintable_get_intrinsic_width (self->puzzle) + self->width - 1) / self->width;
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_puzzle_piece_get_intrinsic_height (GdkPaintable *paintable)
|
||||
{
|
||||
GtkPuzzlePiece *self = GTK_PUZZLE_PIECE (paintable);
|
||||
|
||||
/* Do the same thing we did for the width with the height.
|
||||
*/
|
||||
return (gdk_paintable_get_intrinsic_height (self->puzzle) + self->height - 1) / self->height;
|
||||
}
|
||||
|
||||
static double
|
||||
gtk_puzzle_piece_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
|
||||
{
|
||||
GtkPuzzlePiece *self = GTK_PUZZLE_PIECE (paintable);
|
||||
|
||||
/* We can compute our aspect ratio relative to the puzzle.
|
||||
* This logic again works for the case where the puzzle
|
||||
* has no aspect ratio, because the 0 return value is unchanged.
|
||||
*/
|
||||
return gdk_paintable_get_intrinsic_aspect_ratio (self->puzzle) * self->height / self->width;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_puzzle_piece_paintable_init (GdkPaintableInterface *iface)
|
||||
{
|
||||
iface->snapshot = gtk_puzzle_piece_snapshot;
|
||||
iface->get_flags = gtk_puzzle_piece_get_flags;
|
||||
iface->get_intrinsic_width = gtk_puzzle_piece_get_intrinsic_width;
|
||||
iface->get_intrinsic_height = gtk_puzzle_piece_get_intrinsic_height;
|
||||
iface->get_intrinsic_aspect_ratio = gtk_puzzle_piece_get_intrinsic_aspect_ratio;
|
||||
}
|
||||
|
||||
/* When defining the GType, we need to implement the GdkPaintable interface */
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkPuzzlePiece, gtk_puzzle_piece, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
||||
gtk_puzzle_piece_paintable_init))
|
||||
|
||||
/* We need to declare a destructor to release our reference to the
|
||||
* puzzle paintable and disconnect our signal handlers.
|
||||
*/
|
||||
static void
|
||||
gtk_puzzle_piece_dispose (GObject *object)
|
||||
{
|
||||
GtkPuzzlePiece *self = GTK_PUZZLE_PIECE (object);
|
||||
|
||||
if (self->puzzle)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (self->puzzle, gdk_paintable_invalidate_contents, self);
|
||||
g_signal_handlers_disconnect_by_func (self->puzzle, gdk_paintable_invalidate_size, self);
|
||||
g_clear_object (&self->puzzle);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gtk_puzzle_piece_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
/* Here's the boilerplate for the GObject declaration.
|
||||
*/
|
||||
static void
|
||||
gtk_puzzle_piece_class_init (GtkPuzzlePieceClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = gtk_puzzle_piece_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_puzzle_piece_init (GtkPuzzlePiece *self)
|
||||
{
|
||||
}
|
||||
|
||||
/* And finally, we add a constructor.
|
||||
* It is declared in the header so that the other examples
|
||||
* can use it.
|
||||
*/
|
||||
GdkPaintable *
|
||||
gtk_puzzle_piece_new (GdkPaintable *puzzle,
|
||||
guint x,
|
||||
guint y,
|
||||
guint width,
|
||||
guint height)
|
||||
{
|
||||
GtkPuzzlePiece *self;
|
||||
|
||||
/* These are sanity checks, so that we get warnings if we accidentally
|
||||
* do anything stupid. */
|
||||
g_return_val_if_fail (GDK_IS_PAINTABLE (puzzle), NULL);
|
||||
g_return_val_if_fail (width > 0, NULL);
|
||||
g_return_val_if_fail (height > 0, NULL);
|
||||
g_return_val_if_fail (x < width, NULL);
|
||||
g_return_val_if_fail (y < height, NULL);
|
||||
|
||||
self = g_object_new (GTK_TYPE_PUZZLE_PIECE, NULL);
|
||||
|
||||
self->puzzle = g_object_ref (puzzle);
|
||||
g_signal_connect_swapped (puzzle, "invalidate-contents", G_CALLBACK (gdk_paintable_invalidate_contents), self);
|
||||
g_signal_connect_swapped (puzzle, "invalidate-size", G_CALLBACK (gdk_paintable_invalidate_size), self);
|
||||
self->x = x;
|
||||
self->y = y;
|
||||
self->width = width;
|
||||
self->height = height;
|
||||
|
||||
return GDK_PAINTABLE (self);
|
||||
}
|
||||
|
||||
/* Here are the accessors that we need to inspect the puzzle
|
||||
* pieces in other code.
|
||||
*/
|
||||
GdkPaintable *
|
||||
gtk_puzzle_piece_get_puzzle (GtkPuzzlePiece *self)
|
||||
{
|
||||
/* Add sanity checks here, too.
|
||||
* If you make a habit out of this, you can always rely
|
||||
* on your code having sanity checks, which makes it
|
||||
* way easier to debug.
|
||||
*/
|
||||
g_return_val_if_fail (GTK_IS_PUZZLE_PIECE (self), NULL);
|
||||
|
||||
return self->puzzle;
|
||||
}
|
||||
|
||||
guint
|
||||
gtk_puzzle_piece_get_x (GtkPuzzlePiece *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_PUZZLE_PIECE (self), 0);
|
||||
|
||||
return self->x;
|
||||
}
|
||||
|
||||
guint
|
||||
gtk_puzzle_piece_get_y (GtkPuzzlePiece *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_PUZZLE_PIECE (self), 0);
|
||||
|
||||
return self->y;
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#ifndef __PUZZLE_PIECE_H__
|
||||
#define __PUZZLE_PIECE_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* First, add the boilerplate for the object itself.
|
||||
*/
|
||||
#define GTK_TYPE_PUZZLE_PIECE (gtk_puzzle_piece_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GtkPuzzlePiece, gtk_puzzle_piece, GTK, PUZZLE_PIECE, GObject)
|
||||
|
||||
/* Then, declare all constructors */
|
||||
GdkPaintable * gtk_puzzle_piece_new (GdkPaintable *puzzle,
|
||||
guint x,
|
||||
guint y,
|
||||
guint width,
|
||||
guint height);
|
||||
|
||||
/* Next, add the getters and setters for object properties */
|
||||
GdkPaintable * gtk_puzzle_piece_get_puzzle (GtkPuzzlePiece *self);
|
||||
guint gtk_puzzle_piece_get_x (GtkPuzzlePiece *self);
|
||||
guint gtk_puzzle_piece_get_y (GtkPuzzlePiece *self);
|
||||
|
||||
#endif /* __PUZZLE_PIECE_H__ */
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#define HEART "♥"
|
||||
const char text[] = "I ♥ GTK";
|
||||
const char text[] = "I ♥ GTK+";
|
||||
|
||||
static void
|
||||
fancy_shape_renderer (cairo_t *cr,
|
||||
|
||||
@@ -151,10 +151,11 @@ create_search_menu (GtkWidget *entry)
|
||||
static void
|
||||
icon_press_cb (GtkEntry *entry,
|
||||
gint position,
|
||||
GdkEventButton *event,
|
||||
gpointer data)
|
||||
{
|
||||
if (position == GTK_ENTRY_ICON_PRIMARY)
|
||||
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
|
||||
gtk_menu_popup_at_pointer (GTK_MENU (menu), (GdkEvent *) event);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -240,20 +241,20 @@ do_search_entry (GtkWidget *do_widget)
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label), "Search entry demo");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||
|
||||
/* Create our entry */
|
||||
entry = gtk_search_entry_new ();
|
||||
gtk_container_add (GTK_CONTAINER (hbox), entry);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), entry);
|
||||
|
||||
/* Create the find and cancel buttons */
|
||||
notebook = gtk_notebook_new ();
|
||||
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
|
||||
gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), notebook);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), notebook);
|
||||
|
||||
find_button = gtk_button_new_with_label ("Find");
|
||||
g_signal_connect (find_button, "clicked",
|
||||
|
||||
@@ -26,6 +26,14 @@ changed_cb (GtkEditable *editable)
|
||||
g_message ("changed: %s", text);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
window_key_press_event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
GtkSearchBar *bar)
|
||||
{
|
||||
return gtk_search_bar_handle_event (bar, event);
|
||||
}
|
||||
|
||||
static void
|
||||
search_changed (GtkSearchEntry *entry,
|
||||
GtkLabel *label)
|
||||
@@ -83,38 +91,39 @@ do_search_entry2 (GtkWidget *do_widget)
|
||||
entry = gtk_search_entry_new ();
|
||||
container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_widget_set_halign (container, GTK_ALIGN_CENTER);
|
||||
gtk_container_add (GTK_CONTAINER (container), entry);
|
||||
gtk_box_pack_start (GTK_BOX (container), entry);
|
||||
searchbar = gtk_search_bar_new ();
|
||||
gtk_search_bar_connect_entry (GTK_SEARCH_BAR (searchbar), GTK_ENTRY (entry));
|
||||
gtk_search_bar_set_show_close_button (GTK_SEARCH_BAR (searchbar), FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (searchbar), container);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), searchbar);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), searchbar);
|
||||
|
||||
/* Hook the search bar to key presses */
|
||||
gtk_search_bar_set_key_capture_widget (GTK_SEARCH_BAR (searchbar), window);
|
||||
g_signal_connect (window, "key-press-event",
|
||||
G_CALLBACK (window_key_press_event_cb), searchbar);
|
||||
|
||||
/* Help */
|
||||
label = gtk_label_new ("Start Typing to search");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
/* Toggle button */
|
||||
button = gtk_toggle_button_new_with_label ("Search");
|
||||
g_object_bind_property (button, "active",
|
||||
searchbar, "search-mode-enabled",
|
||||
G_BINDING_BIDIRECTIONAL);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), button);
|
||||
|
||||
/* Result */
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||
|
||||
label = gtk_label_new ("Result:");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_widget_set_margin_start (label, 6);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label);
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_container_add (GTK_CONTAINER (hbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label);
|
||||
|
||||
g_signal_connect (entry, "search-changed",
|
||||
G_CALLBACK (search_changed_cb), label);
|
||||
@@ -122,15 +131,15 @@ do_search_entry2 (GtkWidget *do_widget)
|
||||
G_CALLBACK (changed_cb), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||
|
||||
label = gtk_label_new ("Signal:");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_widget_set_margin_start (label, 6);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label);
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_container_add (GTK_CONTAINER (hbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), label);
|
||||
|
||||
g_signal_connect (entry, "search-changed",
|
||||
G_CALLBACK (search_changed), label);
|
||||
|
||||
@@ -19,7 +19,7 @@ do_sidebar (GtkWidget *do_widget)
|
||||
GtkWidget *widget;
|
||||
GtkWidget *header;
|
||||
const gchar* pages[] = {
|
||||
"Welcome to GTK",
|
||||
"Welcome to GTK+",
|
||||
"GtkStackSidebar Widget",
|
||||
"Automatic navigation",
|
||||
"Consistent appearance",
|
||||
@@ -49,7 +49,7 @@ do_sidebar (GtkWidget *do_widget)
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
sidebar = gtk_stack_sidebar_new ();
|
||||
gtk_container_add (GTK_CONTAINER (box), sidebar);
|
||||
gtk_box_pack_start (GTK_BOX (box), sidebar);
|
||||
|
||||
stack = gtk_stack_new ();
|
||||
gtk_stack_set_transition_type (GTK_STACK (stack), GTK_STACK_TRANSITION_TYPE_SLIDE_UP_DOWN);
|
||||
@@ -57,9 +57,9 @@ do_sidebar (GtkWidget *do_widget)
|
||||
|
||||
/* Separator between sidebar and stack */
|
||||
widget = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
|
||||
gtk_container_add (GTK_CONTAINER(box), widget);
|
||||
gtk_box_pack_start (GTK_BOX(box), widget);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (box), stack);
|
||||
gtk_box_pack_start (GTK_BOX (box), stack);
|
||||
|
||||
for (i=0; (c = *(pages+i)) != NULL; i++ )
|
||||
{
|
||||
|
||||
@@ -116,7 +116,7 @@ do_sizegroup (GtkWidget *do_widget)
|
||||
|
||||
/* Create one frame holding color options */
|
||||
frame = gtk_frame_new ("Color Options");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
table = gtk_grid_new ();
|
||||
g_object_set (table, "margin", 5, NULL);
|
||||
@@ -129,7 +129,7 @@ do_sizegroup (GtkWidget *do_widget)
|
||||
|
||||
/* And another frame holding line style options */
|
||||
frame = gtk_frame_new ("Line Options");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
table = gtk_grid_new ();
|
||||
g_object_set (table, "margin", 5, NULL);
|
||||
@@ -142,7 +142,7 @@ do_sizegroup (GtkWidget *do_widget)
|
||||
|
||||
/* And a check button to turn grouping on and off */
|
||||
check_button = gtk_check_button_new_with_mnemonic ("_Enable grouping");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), check_button);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), check_button);
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
|
||||
g_signal_connect (check_button, "toggled",
|
||||
|
||||
@@ -1,486 +0,0 @@
|
||||
/* Sliding puzzle
|
||||
*
|
||||
* This demo demonstrates how to use gestures and paintables to create a
|
||||
* small sliding puzzle game.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* Include the header for the puzzle piece */
|
||||
#include "puzzlepiece.h"
|
||||
#include "paintable.h"
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkWidget *frame = NULL;
|
||||
static GtkWidget *choices = NULL;
|
||||
static GtkWidget *size_spin = NULL;
|
||||
static GdkPaintable *puzzle = NULL;
|
||||
|
||||
static gboolean solved = TRUE;
|
||||
static guint width = 3;
|
||||
static guint height = 3;
|
||||
static guint pos_x;
|
||||
static guint pos_y;
|
||||
|
||||
static gboolean
|
||||
move_puzzle (GtkWidget *grid,
|
||||
int dx,
|
||||
int dy)
|
||||
{
|
||||
GtkWidget *pos, *next;
|
||||
GdkPaintable *piece;
|
||||
guint next_x, next_y;
|
||||
|
||||
/* We don't move anything if the puzzle is solved */
|
||||
if (solved)
|
||||
return FALSE;
|
||||
|
||||
/* Return FALSE if we can't move to where the call
|
||||
* wants us to move.
|
||||
*/
|
||||
if ((dx < 0 && pos_x < -dx) ||
|
||||
dx + pos_x >= width ||
|
||||
(dy < 0 && pos_y < -dy) ||
|
||||
dy + pos_y >= height)
|
||||
return FALSE;
|
||||
|
||||
/* Compute the new position */
|
||||
next_x = pos_x + dx;
|
||||
next_y = pos_y + dy;
|
||||
|
||||
/* Get the current and next image */
|
||||
pos = gtk_grid_get_child_at (GTK_GRID (grid), pos_x, pos_y);
|
||||
next = gtk_grid_get_child_at (GTK_GRID (grid), next_x, next_y);
|
||||
|
||||
/* Move the displayed piece. */
|
||||
piece = gtk_picture_get_paintable (GTK_PICTURE (next));
|
||||
gtk_picture_set_paintable (GTK_PICTURE (pos), piece);
|
||||
gtk_picture_set_paintable (GTK_PICTURE (next), NULL);
|
||||
|
||||
/* Update the current position */
|
||||
pos_x = next_x;
|
||||
pos_y = next_y;
|
||||
|
||||
/* Return TRUE because we successfully moved the piece */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
shuffle_puzzle (GtkWidget *grid)
|
||||
{
|
||||
guint i, n_steps;
|
||||
|
||||
/* Do this many random moves */
|
||||
n_steps = width * height * 50;
|
||||
|
||||
for (i = 0; i < n_steps; i++)
|
||||
{
|
||||
/* Get a random number for the direction to move in */
|
||||
switch (g_random_int_range (0, 4))
|
||||
{
|
||||
case 0:
|
||||
/* left */
|
||||
move_puzzle (grid, -1, 0);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* up */
|
||||
move_puzzle (grid, 0, -1);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* right */
|
||||
move_puzzle (grid, 1, 0);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* down */
|
||||
move_puzzle (grid, 0, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_solved (GtkWidget *grid)
|
||||
{
|
||||
GtkWidget *picture;
|
||||
GdkPaintable *piece;
|
||||
guint x, y;
|
||||
|
||||
/* Nothing to check if the puzzle is already solved */
|
||||
if (solved)
|
||||
return TRUE;
|
||||
|
||||
/* If the empty cell isn't in the bottom right,
|
||||
* the puzzle is obviously not solved */
|
||||
if (pos_x != width - 1 ||
|
||||
pos_y != height - 1)
|
||||
return FALSE;
|
||||
|
||||
/* Check that all pieces are in the right position */
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
picture = gtk_grid_get_child_at (GTK_GRID (grid), x, y);
|
||||
piece = gtk_picture_get_paintable (GTK_PICTURE (picture));
|
||||
|
||||
/* empty cell */
|
||||
if (piece == NULL)
|
||||
continue;
|
||||
|
||||
if (gtk_puzzle_piece_get_x (GTK_PUZZLE_PIECE (piece)) != x ||
|
||||
gtk_puzzle_piece_get_y (GTK_PUZZLE_PIECE (piece)) != y)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* We solved the puzzle!
|
||||
*/
|
||||
solved = TRUE;
|
||||
|
||||
/* Fill the empty cell to show that we're done.
|
||||
*/
|
||||
picture = gtk_grid_get_child_at (GTK_GRID (grid), 0, 0);
|
||||
piece = gtk_picture_get_paintable (GTK_PICTURE (picture));
|
||||
|
||||
piece = gtk_puzzle_piece_new (gtk_puzzle_piece_get_puzzle (GTK_PUZZLE_PIECE (piece)),
|
||||
pos_x, pos_y,
|
||||
width, height);
|
||||
picture = gtk_grid_get_child_at (GTK_GRID (grid), pos_x, pos_y);
|
||||
gtk_picture_set_paintable (GTK_PICTURE (picture), piece);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
puzzle_key_pressed (GtkEventControllerKey *controller,
|
||||
guint keyval,
|
||||
guint keycode,
|
||||
GdkModifierType state,
|
||||
GtkWidget *grid)
|
||||
{
|
||||
int dx, dy;
|
||||
|
||||
dx = 0;
|
||||
dy = 0;
|
||||
|
||||
switch (keyval)
|
||||
{
|
||||
case GDK_KEY_KP_Left:
|
||||
case GDK_KEY_Left:
|
||||
/* left */
|
||||
dx = -1;
|
||||
break;
|
||||
|
||||
case GDK_KEY_KP_Up:
|
||||
case GDK_KEY_Up:
|
||||
/* up */
|
||||
dy = -1;
|
||||
break;
|
||||
|
||||
case GDK_KEY_KP_Right:
|
||||
case GDK_KEY_Right:
|
||||
/* right */
|
||||
dx = 1;
|
||||
break;
|
||||
|
||||
case GDK_KEY_KP_Down:
|
||||
case GDK_KEY_Down:
|
||||
/* down */
|
||||
dy = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* We return FALSE here because we didn't handle the key that was pressed */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!move_puzzle (grid, dx, dy))
|
||||
{
|
||||
/* Make the error sound and then return TRUE.
|
||||
* We handled this key, even though we didn't
|
||||
* do anything to the puzzle.
|
||||
*/
|
||||
gtk_widget_error_bell (grid);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
check_solved (grid);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
puzzle_button_pressed (GtkGestureMultiPress *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *grid)
|
||||
{
|
||||
GtkWidget *child;
|
||||
int l, t, i;
|
||||
int pos;
|
||||
|
||||
child = gtk_widget_pick (grid, x, y);
|
||||
|
||||
if (!child)
|
||||
{
|
||||
gtk_widget_error_bell (grid);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_container_child_get (GTK_CONTAINER (grid), child,
|
||||
"left-attach", &l,
|
||||
"top-attach", &t,
|
||||
NULL);
|
||||
|
||||
if (l == pos_x && t == pos_y)
|
||||
{
|
||||
gtk_widget_error_bell (grid);
|
||||
}
|
||||
else if (l == pos_x)
|
||||
{
|
||||
pos = pos_y;
|
||||
for (i = t; i < pos; i++)
|
||||
{
|
||||
if (!move_puzzle (grid, 0, -1))
|
||||
gtk_widget_error_bell (grid);
|
||||
}
|
||||
for (i = pos; i < t; i++)
|
||||
{
|
||||
if (!move_puzzle (grid, 0, 1))
|
||||
gtk_widget_error_bell (grid);
|
||||
}
|
||||
}
|
||||
else if (t == pos_y)
|
||||
{
|
||||
pos = pos_x;
|
||||
for (i = l; i < pos; i++)
|
||||
{
|
||||
if (!move_puzzle (grid, -1, 0))
|
||||
gtk_widget_error_bell (grid);
|
||||
}
|
||||
for (i = pos; i < l; i++)
|
||||
{
|
||||
if (!move_puzzle (grid, 1, 0))
|
||||
gtk_widget_error_bell (grid);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_error_bell (grid);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
start_puzzle (GdkPaintable *puzzle)
|
||||
{
|
||||
GtkWidget *picture, *grid;
|
||||
GtkEventController *controller;
|
||||
guint x, y;
|
||||
|
||||
/* Remove the old grid (if there is one) */
|
||||
grid = gtk_bin_get_child (GTK_BIN (frame));
|
||||
if (grid)
|
||||
gtk_container_remove (GTK_CONTAINER (frame), grid);
|
||||
|
||||
/* Create a new grid */
|
||||
grid = gtk_grid_new ();
|
||||
gtk_widget_set_can_focus (grid, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (frame), grid);
|
||||
gtk_aspect_frame_set (GTK_ASPECT_FRAME (frame), 0.5, 0.5, (float) gdk_paintable_get_intrinsic_aspect_ratio (puzzle), FALSE);
|
||||
|
||||
/* Add a key event controller so people can use the arrow
|
||||
* keys to move the puzzle */
|
||||
controller = gtk_event_controller_key_new ();
|
||||
g_signal_connect (controller, "key-pressed",
|
||||
G_CALLBACK (puzzle_key_pressed),
|
||||
grid);
|
||||
gtk_widget_add_controller (GTK_WIDGET (grid), controller);
|
||||
|
||||
controller = GTK_EVENT_CONTROLLER (gtk_gesture_multi_press_new ());
|
||||
g_signal_connect (controller, "pressed",
|
||||
G_CALLBACK (puzzle_button_pressed),
|
||||
grid);
|
||||
gtk_widget_add_controller (GTK_WIDGET (grid), controller);
|
||||
|
||||
/* Make sure the cells have equal size */
|
||||
gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
|
||||
gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
|
||||
|
||||
/* Reset the variables */
|
||||
solved = FALSE;
|
||||
pos_x = width - 1;
|
||||
pos_y = height - 1;
|
||||
|
||||
/* add a picture for every cell */
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
GdkPaintable *piece;
|
||||
|
||||
/* Don't paint anything for the lsiding part of the video */
|
||||
if (x == pos_x && y == pos_y)
|
||||
piece = NULL;
|
||||
else
|
||||
piece = gtk_puzzle_piece_new (puzzle,
|
||||
x, y,
|
||||
width, height);
|
||||
picture = gtk_picture_new_for_paintable (piece);
|
||||
gtk_picture_set_keep_aspect_ratio (GTK_PICTURE (picture), FALSE);
|
||||
gtk_grid_attach (GTK_GRID (grid),
|
||||
picture,
|
||||
x, y,
|
||||
1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
shuffle_puzzle (grid);
|
||||
}
|
||||
|
||||
static void
|
||||
reshuffle (void)
|
||||
{
|
||||
GtkWidget *grid;
|
||||
|
||||
grid = gtk_bin_get_child (GTK_BIN (frame));
|
||||
if (solved)
|
||||
start_puzzle (puzzle);
|
||||
else
|
||||
shuffle_puzzle (grid);
|
||||
gtk_widget_grab_focus (grid);
|
||||
}
|
||||
|
||||
static void
|
||||
reconfigure (void)
|
||||
{
|
||||
GtkWidget *popover;
|
||||
GtkWidget *grid;
|
||||
GtkWidget *child;
|
||||
GtkWidget *image;
|
||||
GList *selected;
|
||||
|
||||
width = height = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (size_spin));
|
||||
|
||||
selected = gtk_flow_box_get_selected_children (GTK_FLOW_BOX (choices));
|
||||
if (selected == NULL)
|
||||
child = gtk_widget_get_first_child (choices);
|
||||
else
|
||||
{
|
||||
child = selected->data;
|
||||
g_list_free (selected);
|
||||
}
|
||||
image = gtk_bin_get_child (GTK_BIN (child));
|
||||
puzzle = gtk_image_get_paintable (GTK_IMAGE (image));
|
||||
|
||||
start_puzzle (puzzle);
|
||||
popover = gtk_widget_get_ancestor (size_spin, GTK_TYPE_POPOVER);
|
||||
gtk_popover_popdown (GTK_POPOVER (popover));
|
||||
grid = gtk_bin_get_child (GTK_BIN (frame));
|
||||
gtk_widget_grab_focus (grid);
|
||||
}
|
||||
|
||||
static void
|
||||
add_choice (GtkWidget *choices,
|
||||
GdkPaintable *paintable)
|
||||
{
|
||||
GtkWidget *icon;
|
||||
|
||||
icon = gtk_image_new_from_paintable (paintable);
|
||||
gtk_image_set_icon_size (GTK_IMAGE (icon), GTK_ICON_SIZE_LARGE);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (choices), icon);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_sliding_puzzle (GtkWidget *do_widget)
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *header;
|
||||
GtkWidget *restart;
|
||||
GtkWidget *tweak;
|
||||
GtkWidget *popover;
|
||||
GtkWidget *tweaks;
|
||||
GtkWidget *apply;
|
||||
GtkWidget *label;
|
||||
GtkWidget *sw;
|
||||
GtkMediaStream *media;
|
||||
|
||||
puzzle = GDK_PAINTABLE (gdk_texture_new_from_resource ("/sliding_puzzle/portland-rose.jpg"));
|
||||
|
||||
tweaks = gtk_grid_new ();
|
||||
gtk_grid_set_row_spacing (GTK_GRID (tweaks), 10);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (tweaks), 10);
|
||||
g_object_set (tweaks, "margin", 10, NULL);
|
||||
|
||||
choices = gtk_flow_box_new ();
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (choices), GTK_STYLE_CLASS_VIEW);
|
||||
add_choice (choices, puzzle);
|
||||
add_choice (choices, gtk_nuclear_animation_new ());
|
||||
media = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
|
||||
gtk_media_stream_set_loop (media, TRUE);
|
||||
gtk_media_stream_set_muted (media, TRUE);
|
||||
gtk_media_stream_play (media);
|
||||
add_choice (choices, GDK_PAINTABLE (media));
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (sw), choices);
|
||||
gtk_grid_attach (GTK_GRID (tweaks), sw, 0, 0, 2, 1);
|
||||
|
||||
label = gtk_label_new ("Size");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_grid_attach (GTK_GRID (tweaks), label, 0, 1, 1, 1);
|
||||
size_spin = gtk_spin_button_new_with_range (2, 10, 1);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (size_spin), width);
|
||||
gtk_grid_attach (GTK_GRID (tweaks), size_spin, 1, 1, 1, 1);
|
||||
|
||||
apply = gtk_button_new_with_label ("Apply");
|
||||
gtk_widget_set_halign (apply, GTK_ALIGN_END);
|
||||
gtk_grid_attach (GTK_GRID (tweaks), apply, 1, 2, 1, 1);
|
||||
g_signal_connect (apply, "clicked", G_CALLBACK (reconfigure), NULL);
|
||||
|
||||
popover = gtk_popover_new (NULL);
|
||||
gtk_popover_set_modal (GTK_POPOVER (popover), TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (popover), tweaks);
|
||||
|
||||
tweak = gtk_menu_button_new ();
|
||||
gtk_menu_button_set_popover (GTK_MENU_BUTTON (tweak), popover);
|
||||
gtk_button_set_icon_name (GTK_BUTTON (tweak), "emblem-system-symbolic");
|
||||
|
||||
restart = gtk_button_new_from_icon_name ("view-refresh-symbolic");
|
||||
g_signal_connect (restart, "clicked", G_CALLBACK (reshuffle), NULL);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), restart);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), tweak);
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Sliding Puzzle");
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
frame = gtk_aspect_frame_new (NULL, 0.5, 0.5, (float) gdk_paintable_get_intrinsic_aspect_ratio (puzzle), FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (window), frame);
|
||||
|
||||
start_puzzle (puzzle);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -33,14 +33,14 @@ hex_spin_output (GtkSpinButton *spin_button)
|
||||
{
|
||||
GtkAdjustment *adjustment;
|
||||
gchar *buf;
|
||||
gdouble val;
|
||||
gint val;
|
||||
|
||||
adjustment = gtk_spin_button_get_adjustment (spin_button);
|
||||
val = gtk_adjustment_get_value (adjustment);
|
||||
val = (gint) gtk_adjustment_get_value (adjustment);
|
||||
if (fabs (val) < 1e-5)
|
||||
buf = g_strdup ("0x00");
|
||||
else
|
||||
buf = g_strdup_printf ("0x%.2X", (gint) val);
|
||||
buf = g_strdup_printf ("0x%.2X", val);
|
||||
if (strcmp (buf, gtk_spin_button_get_text (spin_button)))
|
||||
gtk_spin_button_set_text (spin_button, buf);
|
||||
g_free (buf);
|
||||
|
||||
@@ -53,7 +53,7 @@ do_spinner (GtkWidget *do_widget)
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
||||
g_object_set (vbox, "margin", 5, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), vbox);
|
||||
gtk_box_pack_start (GTK_BOX (content_area), vbox);
|
||||
|
||||
/* Sensitive */
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
||||
|
||||
@@ -157,7 +157,7 @@ create_text_view (GtkWidget *hbox,
|
||||
guint timeout;
|
||||
|
||||
swindow = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), swindow);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), swindow);
|
||||
textview = gtk_text_view_new ();
|
||||
gtk_container_add (GTK_CONTAINER (swindow), textview);
|
||||
|
||||
|
||||
@@ -280,7 +280,7 @@ insert_text (GtkTextBuffer *buffer)
|
||||
gtk_text_buffer_insert (buffer, &iter,
|
||||
"This line (and most of the others in this buffer) is word-wrapped, "
|
||||
"using the proper Unicode algorithm. Word wrap should work in all "
|
||||
"scripts and languages that GTK supports. Let's make this a long "
|
||||
"scripts and languages that GTK+ supports. Let's make this a long "
|
||||
"paragraph to demonstrate: blah blah blah blah blah blah blah blah "
|
||||
"blah blah blah blah blah blah blah blah blah blah blah\n\n", -1);
|
||||
|
||||
|
||||
@@ -131,6 +131,9 @@
|
||||
<property name="can-focus">1</property>
|
||||
<property name="receives-default">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
@@ -138,6 +141,9 @@
|
||||
<property name="can-focus">1</property>
|
||||
<property name="receives-default">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* Theming/Style Classes
|
||||
*
|
||||
* GTK uses CSS for theming. Style classes can be associated
|
||||
* GTK+ uses CSS for theming. Style classes can be associated
|
||||
* with widgets to inform the theme about intended rendering.
|
||||
*
|
||||
* This demo shows some common examples where theming features
|
||||
* of GTK are used for certain effects: primary toolbars,
|
||||
* of GTK+ are used for certain effects: primary toolbars,
|
||||
* inline toolbars and linked buttons.
|
||||
*/
|
||||
|
||||
|
||||
@@ -12,10 +12,12 @@ do_transparent (GtkWidget *do_widget)
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *sw;
|
||||
GtkWidget *overlay;
|
||||
GtkWidget *button;
|
||||
GtkWidget *label;
|
||||
GtkWidget *picture;
|
||||
GtkWidget *box;
|
||||
GtkWidget *image;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
@@ -52,8 +54,17 @@ do_transparent (GtkWidget *do_widget)
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), button);
|
||||
gtk_container_child_set (GTK_CONTAINER (overlay), button, "blur", 5.0, NULL);
|
||||
|
||||
picture = gtk_picture_new_for_resource ("/transparent/portland-rose.jpg");
|
||||
gtk_container_add (GTK_CONTAINER (overlay), picture);
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (overlay), sw);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (sw), box);
|
||||
image = gtk_image_new_from_resource ("/transparent/portland-rose.jpg");
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (box), image);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -401,7 +401,7 @@ do_tree_store (GtkWidget *do_widget)
|
||||
g_object_set (vbox, "margin", 8, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox),
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
gtk_label_new ("Jonathan's Holiday Card Planning Sheet"));
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
@@ -410,7 +410,7 @@ do_tree_store (GtkWidget *do_widget)
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), sw);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), sw);
|
||||
|
||||
/* create model */
|
||||
model = create_model ();
|
||||
|
||||
412
demos/gtk-demo/widgetbowl.c
Normal file
412
demos/gtk-demo/widgetbowl.c
Normal file
@@ -0,0 +1,412 @@
|
||||
/* Benchmark/Widgetbowl
|
||||
*
|
||||
* This is a version of the Fishbowl demo that instead shows different
|
||||
* kinds of widgets, which is useful for comparing the rendering performance
|
||||
* of theme specifics.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "gtkfishbowl.h"
|
||||
#include "gtkgears.h"
|
||||
|
||||
const char *const css =
|
||||
".blurred-button {"
|
||||
" box-shadow: 0px 0px 5px 10px rgba(0, 0, 0, 0.5);"
|
||||
"}"
|
||||
"";
|
||||
|
||||
GtkWidget *fishbowl;
|
||||
|
||||
static GtkWidget *
|
||||
create_button (void)
|
||||
{
|
||||
return gtk_button_new_with_label ("Button");
|
||||
}
|
||||
static GtkWidget *
|
||||
create_blurred_button (void)
|
||||
{
|
||||
GtkWidget *w = gtk_button_new ();
|
||||
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (w), "blurred-button");
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_font_button (void)
|
||||
{
|
||||
return gtk_font_button_new ();
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_level_bar (void)
|
||||
{
|
||||
GtkWidget *w = gtk_level_bar_new_for_interval (0, 100);
|
||||
|
||||
gtk_level_bar_set_value (GTK_LEVEL_BAR (w), 50);
|
||||
|
||||
/* Force them to be a bit larger */
|
||||
gtk_widget_set_size_request (w, 200, -1);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_spinner (void)
|
||||
{
|
||||
GtkWidget *w = gtk_spinner_new ();
|
||||
|
||||
gtk_spinner_start (GTK_SPINNER (w));
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_spinbutton (void)
|
||||
{
|
||||
GtkWidget *w = gtk_spin_button_new_with_range (0, 10, 1);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_label (void)
|
||||
{
|
||||
GtkWidget *w = gtk_label_new ("pLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.");
|
||||
|
||||
gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
|
||||
gtk_label_set_max_width_chars (GTK_LABEL (w), 100);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_video (void)
|
||||
{
|
||||
GtkMediaStream *stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
|
||||
GtkWidget *w = gtk_image_new_from_paintable (GDK_PAINTABLE (stream));
|
||||
gtk_media_stream_set_loop (stream, TRUE);
|
||||
gtk_media_stream_play (stream);
|
||||
g_object_unref (stream);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_gears (void)
|
||||
{
|
||||
GtkWidget *w = gtk_gears_new ();
|
||||
|
||||
gtk_widget_set_size_request (w, 100, 100);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
GtkWidget * (*create_func) (void);
|
||||
} widget_types[] = {
|
||||
{ "Button", create_button },
|
||||
{ "Blurbutton", create_blurred_button },
|
||||
{ "Fontbutton", create_font_button },
|
||||
{ "Levelbar" , create_level_bar },
|
||||
{ "Label" , create_label },
|
||||
{ "Spinner" , create_spinner },
|
||||
{ "Spinbutton", create_spinbutton },
|
||||
{ "Video", create_video },
|
||||
{ "Gears", create_gears },
|
||||
};
|
||||
|
||||
static int selected_widget_type = -1;
|
||||
static const int N_WIDGET_TYPES = G_N_ELEMENTS (widget_types);
|
||||
|
||||
#define N_STATS 5
|
||||
|
||||
#define STATS_UPDATE_TIME G_USEC_PER_SEC
|
||||
|
||||
static void
|
||||
set_widget_type (GtkWidget *headerbar,
|
||||
int widget_type_index)
|
||||
{
|
||||
GList *children, *l;
|
||||
|
||||
if (widget_type_index == selected_widget_type)
|
||||
return;
|
||||
|
||||
/* Remove everything */
|
||||
children = gtk_container_get_children (GTK_CONTAINER (fishbowl));
|
||||
for (l = children; l; l = l->next)
|
||||
{
|
||||
gtk_container_remove (GTK_CONTAINER (fishbowl), (GtkWidget*)l->data);
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
|
||||
selected_widget_type = widget_type_index;
|
||||
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar),
|
||||
widget_types[selected_widget_type].name);
|
||||
}
|
||||
|
||||
|
||||
typedef struct _Stats Stats;
|
||||
struct _Stats {
|
||||
gint64 last_stats;
|
||||
gint64 last_frame;
|
||||
gint last_suggestion;
|
||||
guint frame_counter_max;
|
||||
|
||||
guint stats_index;
|
||||
guint frame_counter[N_STATS];
|
||||
guint item_counter[N_STATS];
|
||||
};
|
||||
|
||||
static Stats *
|
||||
get_stats (GtkWidget *widget)
|
||||
{
|
||||
static GQuark stats_quark = 0;
|
||||
Stats *stats;
|
||||
|
||||
if (G_UNLIKELY (stats_quark == 0))
|
||||
stats_quark = g_quark_from_static_string ("stats");
|
||||
|
||||
stats = g_object_get_qdata (G_OBJECT (widget), stats_quark);
|
||||
if (stats == NULL)
|
||||
{
|
||||
stats = g_new0 (Stats, 1);
|
||||
g_object_set_qdata_full (G_OBJECT (widget), stats_quark, stats, g_free);
|
||||
stats->last_frame = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
|
||||
stats->last_stats = stats->last_frame;
|
||||
}
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
static void
|
||||
do_stats (GtkWidget *widget,
|
||||
GtkWidget *info_label,
|
||||
gint *suggested_change)
|
||||
{
|
||||
Stats *stats;
|
||||
gint64 frame_time;
|
||||
|
||||
stats = get_stats (widget);
|
||||
frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
|
||||
|
||||
if (stats->last_stats + STATS_UPDATE_TIME < frame_time)
|
||||
{
|
||||
char *new_label;
|
||||
guint i, n_frames;
|
||||
|
||||
n_frames = 0;
|
||||
for (i = 0; i < N_STATS; i++)
|
||||
{
|
||||
n_frames += stats->frame_counter[i];
|
||||
}
|
||||
|
||||
new_label = g_strdup_printf ("widgets - %.1f fps",
|
||||
(double) G_USEC_PER_SEC * n_frames
|
||||
/ (N_STATS * STATS_UPDATE_TIME));
|
||||
gtk_label_set_label (GTK_LABEL (info_label), new_label);
|
||||
g_free (new_label);
|
||||
|
||||
if (stats->frame_counter[stats->stats_index] >= 19 * stats->frame_counter_max / 20)
|
||||
{
|
||||
if (stats->last_suggestion > 0)
|
||||
stats->last_suggestion *= 2;
|
||||
else
|
||||
stats->last_suggestion = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (stats->last_suggestion < 0)
|
||||
stats->last_suggestion--;
|
||||
else
|
||||
stats->last_suggestion = -1;
|
||||
stats->last_suggestion = MAX (stats->last_suggestion, 1 - (int) stats->item_counter[stats->stats_index]);
|
||||
}
|
||||
|
||||
stats->stats_index = (stats->stats_index + 1) % N_STATS;
|
||||
stats->frame_counter[stats->stats_index] = 0;
|
||||
stats->item_counter[stats->stats_index] = stats->item_counter[(stats->stats_index + N_STATS - 1) % N_STATS];
|
||||
stats->last_stats = frame_time;
|
||||
|
||||
if (suggested_change)
|
||||
*suggested_change = stats->last_suggestion;
|
||||
else
|
||||
stats->last_suggestion = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (suggested_change)
|
||||
*suggested_change = 0;
|
||||
}
|
||||
|
||||
stats->last_frame = frame_time;
|
||||
stats->frame_counter[stats->stats_index]++;
|
||||
stats->frame_counter_max = MAX (stats->frame_counter_max, stats->frame_counter[stats->stats_index]);
|
||||
}
|
||||
|
||||
static void
|
||||
stats_update (GtkWidget *widget)
|
||||
{
|
||||
Stats *stats;
|
||||
|
||||
stats = get_stats (widget);
|
||||
|
||||
stats->item_counter[stats->stats_index] = gtk_fishbowl_get_count (GTK_FISHBOWL (widget));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
move_fish (GtkWidget *bowl,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer info_label)
|
||||
{
|
||||
gint suggested_change = 0;
|
||||
|
||||
do_stats (bowl, info_label, &suggested_change);
|
||||
|
||||
if (suggested_change > 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < suggested_change; i ++)
|
||||
{
|
||||
GtkWidget *new_widget = widget_types[selected_widget_type].create_func ();
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (fishbowl), new_widget);
|
||||
|
||||
}
|
||||
}
|
||||
else if (suggested_change < 0)
|
||||
{
|
||||
GList *children, *l;
|
||||
int n_removed = 0;
|
||||
|
||||
children = gtk_container_get_children (GTK_CONTAINER (fishbowl));
|
||||
for (l = children; l; l = l->next)
|
||||
{
|
||||
gtk_container_remove (GTK_CONTAINER (fishbowl), (GtkWidget *)l->data);
|
||||
n_removed ++;
|
||||
|
||||
if (n_removed >= (-suggested_change))
|
||||
break;
|
||||
}
|
||||
|
||||
g_list_free (children);
|
||||
}
|
||||
|
||||
stats_update (bowl);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
next_button_clicked_cb (GtkButton *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *headerbar = user_data;
|
||||
int new_index;
|
||||
|
||||
if (selected_widget_type + 1 >= N_WIDGET_TYPES)
|
||||
new_index = 0;
|
||||
else
|
||||
new_index = selected_widget_type + 1;
|
||||
|
||||
set_widget_type (headerbar, new_index);
|
||||
}
|
||||
|
||||
static void
|
||||
prev_button_clicked_cb (GtkButton *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *headerbar = user_data;
|
||||
int new_index;
|
||||
|
||||
if (selected_widget_type - 1 < 0)
|
||||
new_index = N_WIDGET_TYPES - 1;
|
||||
else
|
||||
new_index = selected_widget_type - 1;
|
||||
|
||||
set_widget_type (headerbar, new_index);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_widgetbowl (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkCssProvider *provider = NULL;
|
||||
|
||||
gtk_init ();
|
||||
|
||||
if (provider == NULL)
|
||||
{
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, css, -1);
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
}
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *info_label;
|
||||
GtkWidget *count_label;
|
||||
GtkWidget *titlebar;
|
||||
GtkWidget *title_box;
|
||||
GtkWidget *left_box;
|
||||
GtkWidget *next_button;
|
||||
GtkWidget *prev_button;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
titlebar = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (titlebar), TRUE);
|
||||
info_label = gtk_label_new ("widget - 00.0 fps");
|
||||
count_label = gtk_label_new ("0");
|
||||
fishbowl = gtk_fishbowl_new ();
|
||||
title_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
prev_button = gtk_button_new_from_icon_name ("pan-start-symbolic");
|
||||
next_button = gtk_button_new_from_icon_name ("pan-end-symbolic");
|
||||
left_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
|
||||
g_object_bind_property (fishbowl, "count", count_label, "label", 0);
|
||||
g_signal_connect (next_button, "clicked", G_CALLBACK (next_button_clicked_cb), titlebar);
|
||||
g_signal_connect (prev_button, "clicked", G_CALLBACK (prev_button_clicked_cb), titlebar);
|
||||
|
||||
gtk_fishbowl_set_animating (GTK_FISHBOWL (fishbowl), TRUE);
|
||||
|
||||
gtk_widget_set_hexpand (title_box, TRUE);
|
||||
gtk_widget_set_halign (title_box, GTK_ALIGN_END);
|
||||
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), titlebar);
|
||||
gtk_container_add (GTK_CONTAINER (title_box), count_label);
|
||||
gtk_container_add (GTK_CONTAINER (title_box), info_label);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (titlebar), title_box);
|
||||
gtk_container_add (GTK_CONTAINER (window), fishbowl);
|
||||
|
||||
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (left_box), "linked");
|
||||
gtk_container_add (GTK_CONTAINER (left_box), prev_button);
|
||||
gtk_container_add (GTK_CONTAINER (left_box), next_button);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (titlebar), left_box);
|
||||
|
||||
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);
|
||||
gtk_widget_add_tick_callback (fishbowl, move_fish, info_label, NULL);
|
||||
|
||||
set_widget_type (titlebar, 0);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ media-view-subtitles=The icon used to show subtitles in a media player
|
||||
|
||||
[network]
|
||||
Name=Network
|
||||
Description=Icons related to network status
|
||||
Description=Icons related to network status");
|
||||
|
||||
network-transmit-receive=The icon used data is being both transmitted and received simultaneously, while the computing device is connected to a network
|
||||
network-transmit=The icon used when data is being transmitted, while the computing device is connected to a network
|
||||
@@ -513,5 +513,3 @@ trophy-gold=
|
||||
night-light=
|
||||
daytime-sunrise=
|
||||
daytime-sunset=
|
||||
on=
|
||||
off=
|
||||
|
||||
@@ -286,16 +286,13 @@ populate (IconBrowserWindow *win)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
key_event_cb (GtkEventController *controller,
|
||||
guint keyval,
|
||||
guint keycode,
|
||||
GdkModifierType state,
|
||||
gpointer data)
|
||||
key_press_event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
IconBrowserWindow *win = data;
|
||||
|
||||
return gtk_search_bar_handle_event (GTK_SEARCH_BAR (win->searchbar),
|
||||
gtk_get_current_event ());
|
||||
return gtk_search_bar_handle_event (GTK_SEARCH_BAR (win->searchbar), event);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -376,9 +373,10 @@ search_mode_toggled (GObject *searchbar, GParamSpec *pspec, IconBrowserWindow *w
|
||||
|
||||
static void
|
||||
get_image_data (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GdkDragContext *context,
|
||||
GtkSelectionData *selection,
|
||||
guint target_info,
|
||||
guint time,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *image;
|
||||
@@ -398,9 +396,10 @@ get_image_data (GtkWidget *widget,
|
||||
|
||||
static void
|
||||
get_scalable_image_data (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GdkDragContext *context,
|
||||
GtkSelectionData *selection,
|
||||
guint target_info,
|
||||
guint time,
|
||||
gpointer data)
|
||||
{
|
||||
gchar *uris[2];
|
||||
@@ -452,7 +451,6 @@ static void
|
||||
icon_browser_window_init (IconBrowserWindow *win)
|
||||
{
|
||||
GdkContentFormats *list;
|
||||
GtkEventController *controller;
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (win));
|
||||
|
||||
@@ -482,30 +480,12 @@ icon_browser_window_init (IconBrowserWindow *win)
|
||||
|
||||
symbolic_toggled (GTK_TOGGLE_BUTTON (win->symbolic_radio), win);
|
||||
|
||||
controller = gtk_event_controller_key_new ();
|
||||
g_signal_connect (controller, "key-pressed", G_CALLBACK (key_event_cb), win);
|
||||
gtk_widget_add_controller (GTK_WIDGET (win), controller);
|
||||
|
||||
populate (win);
|
||||
}
|
||||
|
||||
static void
|
||||
icon_browser_window_finalize (GObject *object)
|
||||
{
|
||||
IconBrowserWindow *win = ICON_BROWSER_WINDOW (object);
|
||||
|
||||
g_hash_table_unref (win->contexts);
|
||||
|
||||
G_OBJECT_CLASS (icon_browser_window_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
icon_browser_window_class_init (IconBrowserWindowClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = icon_browser_window_finalize;
|
||||
|
||||
g_type_ensure (ICON_STORE_TYPE);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
@@ -536,6 +516,7 @@ icon_browser_window_class_init (IconBrowserWindowClass *class)
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), item_activated);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), selected_context_changed);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), symbolic_toggled);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), key_press_event_cb);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), copy_to_clipboard);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ executable('gtk4-icon-browser',
|
||||
dependencies: libgtk_dep,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true)
|
||||
|
||||
install_data('org.gtk.IconBrowser.desktop', install_dir: gtk_applicationsdir)
|
||||
install_data('gtk4-icon-browser.desktop', install_dir: gtk_applicationsdir)
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
<property name="child-model">store</property>
|
||||
</object>
|
||||
<template class="IconBrowserWindow" parent="GtkApplicationWindow">
|
||||
<style><class name="devel"/></style>
|
||||
<property name="title" translatable="yes">Icon Browser</property>
|
||||
<property name="default-width">1024</property>
|
||||
<property name="default-height">768</property>
|
||||
<signal name="key-press-event" handler="key_press_event_cb"/>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="title" translatable="yes">Icon Browser</property>
|
||||
@@ -121,7 +121,7 @@
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="resizable">0</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<child internal-child="content_area">
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[Desktop Entry]
|
||||
Name=Widget Factory
|
||||
Comment=A showcase for GTK widgets, designed for testing themes.
|
||||
Comment=A showcase for GTK+ widgets, designed for testing themes.
|
||||
Exec=gtk4-widget-factory
|
||||
Icon=gtk4-widget-factory
|
||||
Terminal=false
|
||||
19
demos/widget-factory/menus.ui
Normal file
19
demos/widget-factory/menus.ui
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.0 -->
|
||||
<menu id="app-menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">About</attribute>
|
||||
<attribute name="action">app.about</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Quit</attribute>
|
||||
<attribute name="action">app.quit</attribute>
|
||||
<attribute name="accel"><Primary>q</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
||||
@@ -9,11 +9,10 @@ executable('gtk4-widget-factory',
|
||||
dependencies: libgtk_dep,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true)
|
||||
|
||||
# desktop file
|
||||
install_data('org.gtk.WidgetFactory.desktop', install_dir: gtk_applicationsdir)
|
||||
install_data('gtk4-widget-factory.desktop', install_dir: gtk_applicationsdir)
|
||||
|
||||
# icons
|
||||
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
<id>org.gtk.WidgetFactory.desktop</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<name>GTK Widget Factory</name>
|
||||
<summary>Program to demonstrate GTK functions</summary>
|
||||
<name>GTK+ Widget Factory</name>
|
||||
<summary>Program to demonstrate GTK+ functions</summary>
|
||||
<description>
|
||||
<p>
|
||||
GTK Widget Factory is a showcase of GTK widgets. It was
|
||||
GTK+ Widget Factory is a showcase of GTK+ widgets. It was
|
||||
originally created to help theme authors test their creations
|
||||
for completeness.
|
||||
</p>
|
||||
|
||||
@@ -212,28 +212,28 @@ activate_about (GSimpleAction *action,
|
||||
glib_major_version,
|
||||
glib_minor_version,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tGTK\t%d.%d.%d\n",
|
||||
g_string_append_printf (s, "\tGTK+\t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
g_string_append_printf (s, "\nA link can apppear here: <http://www.gtk.org>");
|
||||
|
||||
version = g_strdup_printf ("%s\nRunning against GTK %d.%d.%d",
|
||||
version = g_strdup_printf ("%s\nRunning against GTK+ %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
|
||||
"program-name", "GTK Widget Factory",
|
||||
"program-name", "GTK+ Widget Factory",
|
||||
"version", version,
|
||||
"copyright", "(C) 1997-2013 The GTK Team",
|
||||
"copyright", "(C) 1997-2013 The GTK+ Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK themes and widgets",
|
||||
"comments", "Program to demonstrate GTK+ themes and widgets",
|
||||
"authors", authors,
|
||||
"logo-icon-name", "gtk4-widget-factory",
|
||||
"title", "About GTK Widget Factory",
|
||||
"title", "About GTK+ Widget Factory",
|
||||
"system-information", s->str,
|
||||
NULL);
|
||||
|
||||
@@ -353,6 +353,7 @@ update_pulse_time (GtkAdjustment *adjustment, GtkWidget *widget)
|
||||
static void
|
||||
on_entry_icon_release (GtkEntry *entry,
|
||||
GtkEntryIconPosition icon_pos,
|
||||
GdkEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (icon_pos != GTK_ENTRY_ICON_SECONDARY)
|
||||
@@ -803,7 +804,7 @@ overshot (GtkScrolledWindow *sw, GtkPositionType pos, GtkWidget *widget)
|
||||
"margin", 6,
|
||||
"xalign", 0.0,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (row), label);
|
||||
gtk_box_pack_start (GTK_BOX (row), label);
|
||||
gdk_rgba_parse (&rgba, color);
|
||||
swatch = g_object_new (g_type_from_name ("GtkColorSwatch"),
|
||||
"rgba", &rgba,
|
||||
@@ -815,7 +816,7 @@ overshot (GtkScrolledWindow *sw, GtkPositionType pos, GtkWidget *widget)
|
||||
NULL);
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (box), swatch);
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
gtk_box_pack_start (GTK_BOX (row), box);
|
||||
gtk_list_box_insert (GTK_LIST_BOX (widget), row, -1);
|
||||
row = gtk_widget_get_parent (row);
|
||||
gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE);
|
||||
@@ -914,7 +915,7 @@ populate_colors (GtkWidget *widget, GtkWidget *chooser)
|
||||
"hexpand", TRUE,
|
||||
"xalign", 0.0,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (row), label);
|
||||
gtk_box_pack_start (GTK_BOX (row), label);
|
||||
gdk_rgba_parse (&rgba, colors[i].color);
|
||||
swatch = g_object_new (g_type_from_name ("GtkColorSwatch"),
|
||||
"rgba", &rgba,
|
||||
@@ -926,7 +927,7 @@ populate_colors (GtkWidget *widget, GtkWidget *chooser)
|
||||
NULL);
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (box), swatch);
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
gtk_box_pack_start (GTK_BOX (row), box);
|
||||
gtk_list_box_insert (GTK_LIST_BOX (widget), row, -1);
|
||||
row = gtk_widget_get_parent (row);
|
||||
gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE);
|
||||
@@ -966,8 +967,8 @@ background_loaded_cb (GObject *source,
|
||||
return;
|
||||
}
|
||||
|
||||
child = gtk_picture_new_for_pixbuf (pixbuf);
|
||||
gtk_widget_set_size_request (child, 110, 70);
|
||||
child = gtk_image_new_from_pixbuf (pixbuf);
|
||||
gtk_widget_show (child);
|
||||
gtk_flow_box_insert (GTK_FLOW_BOX (bd->flowbox), child, -1);
|
||||
child = gtk_widget_get_parent (child);
|
||||
g_object_set_data_full (G_OBJECT (child), "filename", bd->filename, g_free);
|
||||
@@ -995,7 +996,8 @@ populate_flowbox (GtkWidget *flowbox)
|
||||
|
||||
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 110, 70);
|
||||
gdk_pixbuf_fill (pixbuf, 0xffffffff);
|
||||
child = gtk_picture_new_for_pixbuf (pixbuf);
|
||||
child = gtk_image_new_from_pixbuf (pixbuf);
|
||||
gtk_widget_show (child);
|
||||
gtk_flow_box_insert (GTK_FLOW_BOX (flowbox), child, -1);
|
||||
|
||||
location = "/usr/share/backgrounds/gnome";
|
||||
@@ -1080,7 +1082,7 @@ set_accel (GtkApplication *app, GtkWidget *widget)
|
||||
typedef struct
|
||||
{
|
||||
GtkTextView tv;
|
||||
GdkTexture *texture;
|
||||
cairo_surface_t *surface;
|
||||
} MyTextView;
|
||||
|
||||
typedef GtkTextViewClass MyTextViewClass;
|
||||
@@ -1093,23 +1095,18 @@ my_text_view_init (MyTextView *tv)
|
||||
}
|
||||
|
||||
static void
|
||||
my_tv_snapshot_layer (GtkTextView *widget,
|
||||
GtkTextViewLayer layer,
|
||||
GtkSnapshot *snapshot)
|
||||
my_tv_draw_layer (GtkTextView *widget,
|
||||
GtkTextViewLayer layer,
|
||||
cairo_t *cr)
|
||||
{
|
||||
MyTextView *tv = (MyTextView *)widget;
|
||||
|
||||
if (layer == GTK_TEXT_VIEW_LAYER_BELOW_TEXT && tv->texture)
|
||||
if (layer == GTK_TEXT_VIEW_LAYER_BELOW_TEXT && tv->surface)
|
||||
{
|
||||
gtk_snapshot_push_opacity (snapshot, 0.333);
|
||||
gtk_snapshot_append_texture (snapshot,
|
||||
tv->texture,
|
||||
&GRAPHENE_RECT_INIT(
|
||||
0, 0,
|
||||
gdk_texture_get_width (tv->texture),
|
||||
gdk_texture_get_height (tv->texture)
|
||||
));
|
||||
gtk_snapshot_pop (snapshot);
|
||||
cairo_save (cr);
|
||||
cairo_set_source_surface (cr, tv->surface, 0.0, 0.0);
|
||||
cairo_paint_with_alpha (cr, 0.333);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1118,7 +1115,8 @@ my_tv_finalize (GObject *object)
|
||||
{
|
||||
MyTextView *tv = (MyTextView *)object;
|
||||
|
||||
g_clear_object (&tv->texture);
|
||||
if (tv->surface)
|
||||
cairo_surface_destroy (tv->surface);
|
||||
|
||||
G_OBJECT_CLASS (my_text_view_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -1130,24 +1128,24 @@ my_text_view_class_init (MyTextViewClass *class)
|
||||
GObjectClass *o_class = G_OBJECT_CLASS (class);
|
||||
|
||||
o_class->finalize = my_tv_finalize;
|
||||
tv_class->snapshot_layer = my_tv_snapshot_layer;
|
||||
tv_class->draw_layer = my_tv_draw_layer;
|
||||
}
|
||||
|
||||
static void
|
||||
my_text_view_set_background (MyTextView *tv, const gchar *filename)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
GError *error = NULL;
|
||||
GFile *file;
|
||||
|
||||
g_clear_object (&tv->texture);
|
||||
if (tv->surface)
|
||||
cairo_surface_destroy (tv->surface);
|
||||
|
||||
tv->surface = NULL;
|
||||
|
||||
if (filename == NULL)
|
||||
return;
|
||||
|
||||
file = g_file_new_for_path (filename);
|
||||
tv->texture = gdk_texture_new_from_file (file, &error);
|
||||
g_object_unref (file);
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_file (filename, &error);
|
||||
if (error)
|
||||
{
|
||||
g_warning ("%s", error->message);
|
||||
@@ -1155,6 +1153,10 @@ my_text_view_set_background (MyTextView *tv, const gchar *filename)
|
||||
return;
|
||||
}
|
||||
|
||||
tv->surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL);
|
||||
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (tv));
|
||||
}
|
||||
|
||||
@@ -1653,6 +1655,7 @@ activate (GApplication *app)
|
||||
gint i;
|
||||
GPermission *permission;
|
||||
GAction *action;
|
||||
GtkGesture *gesture;
|
||||
|
||||
g_type_ensure (my_text_view_get_type ());
|
||||
|
||||
@@ -1677,7 +1680,6 @@ activate (GApplication *app)
|
||||
gtk_builder_add_callback_symbol (builder, "reset_icon_size", (GCallback)reset_icon_size);
|
||||
gtk_builder_add_callback_symbol (builder, "scale_format_value", (GCallback)scale_format_value);
|
||||
gtk_builder_add_callback_symbol (builder, "scale_format_value_blank", (GCallback)scale_format_value_blank);
|
||||
gtk_builder_add_callback_symbol (builder, "osd_frame_pressed", (GCallback)osd_frame_pressed);
|
||||
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
|
||||
@@ -1895,6 +1897,10 @@ activate (GApplication *app)
|
||||
g_signal_connect (adj, "value-changed", G_CALLBACK (adjustment3_value_changed), widget);
|
||||
g_signal_connect (adj, "value-changed", G_CALLBACK (adjustment3_value_changed), widget2);
|
||||
|
||||
widget = (GtkWidget *)gtk_builder_get_object (builder, "osd_frame");
|
||||
gesture = gtk_gesture_multi_press_new (widget);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (osd_frame_pressed), widget);
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
|
||||
g_object_unref (builder);
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
<gresource prefix="/org/gtk/WidgetFactory">
|
||||
<file>widget-factory.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/org/gtk/WidgetFactory/gtk">
|
||||
<file preprocess="xml-stripblanks">menus.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/org/gtk/WidgetFactory/gtk">
|
||||
<file preprocess="xml-stripblanks">help-overlay.ui</file>
|
||||
</gresource>
|
||||
|
||||
@@ -16,16 +16,6 @@
|
||||
<attribute name="action">win.transition</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
|
||||
<attribute name="action">win.show-help-overlay</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About Widget Factory</attribute>
|
||||
<attribute name="action">app.about</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<menu id="dinner_menu">
|
||||
<section>
|
||||
@@ -406,8 +396,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="window">
|
||||
<style><class name="devel"/></style>
|
||||
<property name="title">GTK Widget Factory</property>
|
||||
<property name="title">GTK+ Widget Factory</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="headerbar1">
|
||||
<property name="show-title-buttons">1</property>
|
||||
@@ -472,17 +461,22 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry1">
|
||||
<property name="can-focus">1</property>
|
||||
<property name="enable-emoji-completion">1</property>
|
||||
<property name="invisible_char">•</property>
|
||||
<property name="invisible-char">•</property>
|
||||
<property name="placeholder-text" translatable="yes">Click icon to change mode</property>
|
||||
<property name="secondary-icon-name">view-refresh-symbolic</property>
|
||||
<property name="secondary-icon-tooltip-text">Change mode</property>
|
||||
<signal name="icon-release" handler="on_entry_icon_release" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry2">
|
||||
@@ -491,6 +485,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="invisible-char">•</property>
|
||||
<property name="text" translatable="yes">entry</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box223">
|
||||
@@ -510,8 +507,14 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="can-focus">1</property>
|
||||
<property name="icon-name">window-close-symbolic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
@@ -573,6 +576,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="sensitive">0</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="spinbutton1">
|
||||
@@ -581,6 +587,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="max-width-chars">2</property>
|
||||
<property name="adjustment">adjustment2</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="spinbutton2">
|
||||
@@ -589,6 +598,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="width-chars">2</property>
|
||||
<property name="max-width-chars">2</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
@@ -782,6 +794,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<object class="GtkSeparator" id="separator1">
|
||||
<property name="orientation">vertical</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box19">
|
||||
@@ -801,6 +816,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="can-focus">1</property>
|
||||
<property name="receives-default">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="togglebutton3">
|
||||
@@ -809,6 +827,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="togglebutton4">
|
||||
@@ -818,6 +839,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="combobox1">
|
||||
@@ -830,6 +854,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBox" id="combobox2">
|
||||
@@ -843,13 +870,18 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFontButton" id="fontbutton1">
|
||||
<property name="can-focus">1</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="level">family|style|size|features|variations</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColorButton" id="colorbutton1">
|
||||
@@ -858,10 +890,16 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="rgba">#31316867a09f</property>
|
||||
<property name="use-alpha">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFileChooserButton" id="filechooserbutton1">
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLinkButton" id="linkbutton1">
|
||||
@@ -872,24 +910,39 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="uri">http://www.gtk.org</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">9</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="switch1">
|
||||
<property name="halign">center</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">10</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="switch2">
|
||||
<property name="sensitive">0</property>
|
||||
<property name="halign">center</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">11</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="separator2">
|
||||
<property name="orientation">vertical</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box20">
|
||||
@@ -910,17 +963,26 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="fraction">0.5</property>
|
||||
<property name="inverted">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkProgressBar" id="progressbar3">
|
||||
<property name="fraction">0.5</property>
|
||||
<property name="show-text">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLevelBar" id="levelbar1">
|
||||
<property name="value">0.6</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">10</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLevelBar" id="levelbar2">
|
||||
@@ -933,6 +995,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<offset name="full" value="5"/>
|
||||
</offsets>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">11</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
@@ -961,10 +1026,16 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="fill-level">75</property>
|
||||
<property name="draw-value">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale" id="scale5">
|
||||
@@ -982,6 +1053,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<mark value="4" position="bottom"></mark>
|
||||
</marks>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box25">
|
||||
@@ -1005,6 +1079,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="inverted">1</property>
|
||||
<property name="halign">start</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
@@ -1039,17 +1116,32 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="halign">start</property>
|
||||
<signal name="format-value" handler="scale_format_value_blank"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="separator3">
|
||||
<property name="orientation">vertical</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box26">
|
||||
@@ -1082,6 +1174,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame3">
|
||||
@@ -1095,6 +1190,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame4">
|
||||
@@ -1108,13 +1206,22 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="separator4">
|
||||
<property name="orientation">vertical</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">7</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box4">
|
||||
@@ -1215,13 +1322,25 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">8</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="separator5"/>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box5">
|
||||
@@ -1247,6 +1366,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<object class="GtkBox" id="box7">
|
||||
<property name="orientation">vertical</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="tab">
|
||||
<object class="GtkLabel" id="label6">
|
||||
@@ -1328,6 +1450,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkNotebook" id="notebook3">
|
||||
@@ -1381,6 +1506,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkNotebook" id="notebook4">
|
||||
@@ -1434,8 +1562,14 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
@@ -2090,9 +2224,6 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="tooltip-text" translatable="yes">Save the current document</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton">
|
||||
<property name="label" translatable="yes">Search</property>
|
||||
@@ -2910,6 +3041,9 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<class name="small-button"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
@@ -2940,6 +3074,9 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<class name="small-button"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
@@ -2962,11 +3099,6 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGestureMultiPress">
|
||||
<signal name="pressed" handler="osd_frame_pressed" object="osd_frame" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -2998,6 +3130,9 @@ microphone-sensitivity-medium-symbolic</property>
|
||||
<property name="show-emoji-icon">1</property>
|
||||
<property name="placeholder-text" translatable="yes">Age…</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
@@ -3133,7 +3268,7 @@ bad things might happen.</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="title" translatable="yes">Zelda</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<child internal-child="content_area">
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
@@ -3172,7 +3307,7 @@ bad things might happen.</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="title" translatable="yes">Settings</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<child internal-child="content_area">
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
@@ -3293,7 +3428,7 @@ bad things might happen.</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="title" translatable="yes">Choose one</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<child internal-child="content_area">
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkFlowBox" id="selection_flowbox">
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
# These are the people responsible for subsystems in GTK; if you're opening
|
||||
# a merge request for files listed here, please add the following people to
|
||||
# the list of reviewers
|
||||
|
||||
# The syntax of this file is similar to the GitHub CODEOWNERS file:
|
||||
# https://help.github.com/articles/about-codeowners/
|
||||
# Which, in turn, is similar to the .gitignore and .gitattributes files:
|
||||
#
|
||||
# - comments start with `#`
|
||||
# - the first column contains paths and globs
|
||||
# - the second column contains GitLab user names or email addresses,
|
||||
# separated by spaces
|
||||
#
|
||||
# If you want to be responsible for code reviews in specific sections of
|
||||
# the GTK code base, add yourself here.
|
||||
|
||||
# Maintainer
|
||||
* @matthiasc
|
||||
|
||||
# Build system
|
||||
meson.build @ebassi @nirbheek
|
||||
*.py @ebassi
|
||||
|
||||
# CSS
|
||||
gtk/gtkcss*.[ch] @otte @baedert
|
||||
gtk/gtkstyle*.[ch] @otte @baedert
|
||||
|
||||
# Gestures
|
||||
gtk/gtkeventcontroller* @carlosg
|
||||
gtk/gtkgesture*.[ch] @carlosg
|
||||
|
||||
# GtkFileChooser
|
||||
gtk/gtkfilechooser* @federico
|
||||
gtk/gtkfilesystem* @federico
|
||||
gtk/gtkfilefilter* @federico
|
||||
|
||||
# GtkFontChooser
|
||||
gtk/gtkfontchooser* @matthiasc
|
||||
|
||||
# Input methods
|
||||
gtk/gtkimcontext* @carlosg
|
||||
|
||||
# Media
|
||||
gtk/gtkmedia* @otte
|
||||
|
||||
# GSK
|
||||
gsk @otte @baedert @ebassi
|
||||
|
||||
# GL rendering
|
||||
gsk/gl @baedert @ebassi
|
||||
|
||||
# Vulkan rendering
|
||||
gsk/vulkan
|
||||
|
||||
# Documentation
|
||||
docs/ @ebassi @dboles
|
||||
|
||||
# Wayland
|
||||
gdk/wayland @jadahl
|
||||
|
||||
# X11
|
||||
gdk/x11 @ofourdan @matthiasc
|
||||
|
||||
# Themes
|
||||
gtk/themes @lapoc @jimmac
|
||||
|
||||
# Inspector
|
||||
gtk/inspector @otte @matthiasc
|
||||
@@ -1,8 +1,8 @@
|
||||
GTK Coding Style
|
||||
GTK+ Coding Style
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This document is intended to be a short description of the preferred
|
||||
coding style to be used for the GTK source code. It was strongly
|
||||
coding style to be used for the GTK+ source code. It was strongly
|
||||
inspired by Clutter's CODING_STYLE.
|
||||
|
||||
Coding style is a matter of consistency, readability and maintainance;
|
||||
@@ -12,7 +12,7 @@ and consistent answers to common questions regarding the coding style,
|
||||
and will also try to identify the allowed exceptions.
|
||||
|
||||
The examples will show the preferred coding style; the negative examples
|
||||
will be clearly identified. Please, don't submit code to GTK that
|
||||
will be clearly identified. Please, don't submit code to GTK+ that
|
||||
looks like any of these.
|
||||
|
||||
Part of the rationales for these coding style rules are available either
|
||||
@@ -38,10 +38,10 @@ using tab characters alone, or using a combination of spaces and tabs.
|
||||
|
||||
Do not change the editor's configuration to change the meaning of a
|
||||
tab character (see below); code using tabs to indent will not be accepted
|
||||
into GTK.
|
||||
into GTK+.
|
||||
|
||||
Even if two spaces for each indentation level allows deeper nesting than
|
||||
8 spaces, GTK favours self-documenting function names that can take
|
||||
8 spaces, GTK+ favours self-documenting function names that can take
|
||||
quite some space. For this reason you should avoid deeply nested code.
|
||||
|
||||
+ Tab characters
|
||||
@@ -399,7 +399,7 @@ patch or commit. Never use empty lines at the beginning or at the end of
|
||||
a file.
|
||||
|
||||
Do enable the default git pre-commit hook that detect trailing
|
||||
whitespace for you and help you to avoid corrupting GTK's tree with
|
||||
whitespace for you and help you to avoid corrupting GTK+'s tree with
|
||||
it. Do that as follows:
|
||||
|
||||
chmod a+x .git/hooks/pre-commit
|
||||
@@ -410,7 +410,7 @@ duplicate blank lines.
|
||||
|
||||
+ Headers
|
||||
|
||||
Headers are special, for GTK, in that they don't have to obey the
|
||||
Headers are special, for GTK+, in that they don't have to obey the
|
||||
80 characters limit. The only major rule for headers is that the function
|
||||
definitions should be vertically aligned in three columns:
|
||||
|
||||
@@ -479,7 +479,7 @@ Additionally, public headers should use C++ guards around their declarations:
|
||||
|
||||
+ Includes
|
||||
|
||||
GTK source files must never include the global gtk.h header; instead, it
|
||||
GTK+ source files must never include the global gtk.h header; instead, it
|
||||
should include the individual headers that are needed.
|
||||
|
||||
Every source file must include config.h first, followed by the header matching
|
||||
@@ -658,7 +658,7 @@ after the license header:
|
||||
* @Short_Description: Height-for-width geometry management
|
||||
* @Title: GtkSizeRequest
|
||||
*
|
||||
* The GtkSizeRequest interface is GTK's height-for-width (and
|
||||
* The GtkSizeRequest interface is GTK+'s height-for-width (and
|
||||
* width-for-height) geometry management system.
|
||||
* ...
|
||||
*/
|
||||
@@ -672,8 +672,8 @@ get_type function needs to listed in gtk3.types.
|
||||
|
||||
+ Old code
|
||||
|
||||
New code that is being added to GTK should adhere to the style
|
||||
explained above. Existing GTK code does largely follow these
|
||||
New code that is being added to GTK+ should adhere to the style
|
||||
explained above. Existing GTK+ code does largely follow these
|
||||
conventions, but there are some differences, e.g. occurrences
|
||||
of tabs, etc.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
How to do a GTK release?
|
||||
========================
|
||||
How to do a GTK+ release?
|
||||
=========================
|
||||
|
||||
## Before we begin
|
||||
|
||||
@@ -91,7 +91,7 @@ $ ninja -C _build gtk40-properties-pot
|
||||
12. Tag the release. The git command for doing that looks like:
|
||||
|
||||
```sh
|
||||
$ git tag -m "GTK 4.2.0" 4.2.0
|
||||
$ git tag -m "GTK+ 4.2.0" 4.2.0
|
||||
```
|
||||
|
||||
13. Bump the version number in `meson.build` and commit the change.
|
||||
@@ -110,8 +110,8 @@ $ git push origin 4.2.0
|
||||
this looks like:
|
||||
|
||||
```sh
|
||||
$ scp gtk-4.2.0.tar.xz matthiasc@master.gnome.org:
|
||||
$ ssh matthiasc@master.gnome.org ftpadmin install gtk-4.2.0.tar.xz
|
||||
$ scp gtk+-4.2.0.tar.xz matthiasc@master.gnome.org:
|
||||
$ ssh matthiasc@master.gnome.org ftpadmin install gtk+-4.2.0.tar.xz
|
||||
```
|
||||
|
||||
16. Go to the gnome-announce list archives, find the last announce message,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Things to care about when using/programing for GTK
|
||||
==================================================
|
||||
Things to care about when using/programing for GTK+
|
||||
===================================================
|
||||
|
||||
This file is meant to collect some frequently triggered failures when
|
||||
programming for/with Gtk, having the spirit of a developers FAQ.
|
||||
|
||||
@@ -57,7 +57,7 @@ The GDK API
|
||||
===========
|
||||
|
||||
It is expect that the GDK DND API will never be
|
||||
used by anything other than the DND code in GTK.
|
||||
used by anything other than the DND code in GTK+.
|
||||
|
||||
/* Drag and Drop */
|
||||
|
||||
@@ -71,7 +71,10 @@ straightforward manner.
|
||||
void gdk_drag_status (GdkDragContext *context,
|
||||
GdkDragAction action,
|
||||
guint32 time);
|
||||
void gdk_drag_finish (GdkDragContext *context,
|
||||
void gdk_drop_reply (GdkDragContext *context,
|
||||
gboolean ok,
|
||||
guint32 time);
|
||||
void gdk_drop_finish (GdkDragContext *context,
|
||||
gboolean success,
|
||||
guint32 time);
|
||||
GdkAtom gdk_drag_get_selection (GdkDragContext *context);
|
||||
@@ -159,7 +162,7 @@ the taskbar.
|
||||
Internally, when the outer drag enters a proxy dest site, a
|
||||
new source drag is created, with SourceInfo and
|
||||
GdkDragContext. From the GDK side, it looks much like a
|
||||
normal source drag; on the GTK side, most of the code is
|
||||
normal source drag; on the GTK+ side, most of the code is
|
||||
disjoint. The need to pass in a specific target window
|
||||
is the reason why the GDK DND API splits
|
||||
gdk_drag_find_window() and gdk_drag_motion().
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Information about the icon theme cache format used by GTK
|
||||
Information about the icon theme cache format used by GTK+
|
||||
for more information, see the mailing list threads at
|
||||
|
||||
http://mail.gnome.org/archives/gtk-devel-list/2004-April/msg00065.html
|
||||
@@ -30,7 +30,7 @@ We would like to propose the cache file format as an appendix to the
|
||||
icon theme specification. One thing which still needs to be investigated
|
||||
is caching of the actual image data; the file format is has an
|
||||
IMAGE_DATA_OFFSET member to allow adding that compatibly. An
|
||||
implementation of the caching scheme for GTK can be found at [2]. The
|
||||
implementation of the caching scheme for GTK+ can be found at [2]. The
|
||||
cache generator which is included in the patch depends only on glib, and
|
||||
it may be a good idea to move it to freedesktop.org as well.
|
||||
|
||||
|
||||
@@ -27,12 +27,12 @@
|
||||
<xi:include href="xml/gdkmonitor.xml" />
|
||||
<xi:include href="xml/regions.xml" />
|
||||
<xi:include href="xml/textures.xml" />
|
||||
<xi:include href="xml/gdkpaintable.xml" />
|
||||
<xi:include href="xml/rgba_colors.xml" />
|
||||
<xi:include href="xml/cursors.xml" />
|
||||
<xi:include href="xml/gdksurface.xml" />
|
||||
<xi:include href="xml/windows.xml" />
|
||||
<xi:include href="xml/gdkframeclock.xml" />
|
||||
<xi:include href="xml/gdkframetimings.xml" />
|
||||
<xi:include href="xml/gdkdrawingcontext.xml" />
|
||||
<xi:include href="xml/gdkdrawcontext.xml" />
|
||||
<xi:include href="xml/gdkglcontext.xml" />
|
||||
<xi:include href="xml/gdkvulkancontext.xml" />
|
||||
|
||||
@@ -167,10 +167,11 @@ gdk_rgba_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<TITLE>GdkSurface</TITLE>
|
||||
<FILE>gdksurface</FILE>
|
||||
<TITLE>Windows</TITLE>
|
||||
<FILE>windows</FILE>
|
||||
GdkSurface
|
||||
GdkSurfaceType
|
||||
GdkSurfaceClass
|
||||
GdkSurfaceHints
|
||||
GdkGeometry
|
||||
GdkGravity
|
||||
@@ -193,6 +194,7 @@ gdk_surface_is_visible
|
||||
gdk_surface_is_viewable
|
||||
gdk_surface_is_input_only
|
||||
gdk_surface_get_state
|
||||
gdk_surface_withdraw
|
||||
gdk_surface_iconify
|
||||
gdk_surface_deiconify
|
||||
gdk_surface_stick
|
||||
@@ -231,10 +233,13 @@ gdk_surface_set_opaque_region
|
||||
gdk_surface_create_gl_context
|
||||
gdk_surface_create_vulkan_context
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_surface_begin_draw_frame
|
||||
gdk_surface_end_draw_frame
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_surface_invalidate_rect
|
||||
gdk_surface_invalidate_region
|
||||
gdk_surface_queue_expose
|
||||
gdk_surface_freeze_updates
|
||||
gdk_surface_thaw_updates
|
||||
gdk_surface_get_frame_clock
|
||||
@@ -280,6 +285,8 @@ gdk_surface_get_toplevel
|
||||
gdk_surface_get_children
|
||||
gdk_surface_get_children_with_user_data
|
||||
gdk_surface_peek_children
|
||||
gdk_surface_get_events
|
||||
gdk_surface_set_events
|
||||
gdk_surface_set_icon_name
|
||||
gdk_surface_set_transient_for
|
||||
gdk_surface_set_role
|
||||
@@ -297,6 +304,8 @@ gdk_surface_get_support_multidevice
|
||||
gdk_surface_set_support_multidevice
|
||||
gdk_surface_get_device_cursor
|
||||
gdk_surface_set_device_cursor
|
||||
gdk_surface_get_device_events
|
||||
gdk_surface_set_device_events
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_surface_coords_from_parent
|
||||
@@ -398,12 +407,15 @@ gdk_pango_layout_line_get_clip_region
|
||||
<TITLE>Cairo Interaction</TITLE>
|
||||
<FILE>cairo_interaction</FILE>
|
||||
gdk_surface_create_similar_surface
|
||||
gdk_surface_create_similar_image_surface
|
||||
gdk_cairo_get_clip_rectangle
|
||||
gdk_cairo_get_drawing_context
|
||||
gdk_cairo_set_source_rgba
|
||||
gdk_cairo_set_source_pixbuf
|
||||
gdk_cairo_rectangle
|
||||
gdk_cairo_region
|
||||
gdk_cairo_region_create_from_surface
|
||||
gdk_cairo_surface_create_from_pixbuf
|
||||
gdk_cairo_draw_from_gl
|
||||
gdk_cairo_surface_upload_to_gl
|
||||
</SECTION>
|
||||
@@ -621,6 +633,7 @@ GDK_BUTTON_SECONDARY
|
||||
<SUBSECTION>
|
||||
gdk_event_new
|
||||
gdk_event_copy
|
||||
gdk_event_free
|
||||
gdk_event_get_axes
|
||||
gdk_event_get_button
|
||||
gdk_event_get_click_count
|
||||
@@ -646,15 +659,16 @@ gdk_event_get_scancode
|
||||
gdk_event_get_pointer_emulated
|
||||
gdk_event_get_crossing_detail
|
||||
gdk_event_get_crossing_mode
|
||||
gdk_event_get_drop
|
||||
gdk_event_get_drag_context
|
||||
gdk_event_get_focus_in
|
||||
gdk_event_get_grab_surface
|
||||
gdk_event_get_grab_window
|
||||
gdk_event_get_motion_history
|
||||
gdk_event_get_key_group
|
||||
gdk_event_get_key_is_modifier
|
||||
gdk_event_get_pad_axis_value
|
||||
gdk_event_get_pad_button
|
||||
gdk_event_get_pad_group_mode
|
||||
gdk_event_get_string
|
||||
gdk_event_get_touch_emulating_pointer
|
||||
gdk_event_get_touchpad_angle_delta
|
||||
gdk_event_get_touchpad_deltas
|
||||
@@ -690,27 +704,19 @@ gdk_event_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gdkpaintable</FILE>
|
||||
<TITLE>GdkPaintable</TITLE>
|
||||
<TITLE>Paintable</TITLE>
|
||||
<FILE>paintable</FILE>
|
||||
GdkPaintable
|
||||
GdkPaintableFlags
|
||||
gdk_paintable_get_current_image
|
||||
gdk_paintable_snapshot
|
||||
gdk_paintable_get_current_image
|
||||
gdk_paintable_get_flags
|
||||
gdk_paintable_get_intrinsic_width
|
||||
gdk_paintable_get_intrinsic_height
|
||||
gdk_paintable_get_intrinsic_aspect_ratio
|
||||
gdk_paintable_compute_concrete_size
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_paintable_invalidate_contents
|
||||
gdk_paintable_invalidate_size
|
||||
gdk_paintable_new_empty
|
||||
|
||||
<SUBSECTION Private>
|
||||
GDK_TYPE_PAINTABLE
|
||||
gdk_paintable_get_type
|
||||
</SECTION>
|
||||
<SECTION>
|
||||
|
||||
<SECTION>
|
||||
<TITLE>Textures</TITLE>
|
||||
@@ -722,9 +728,8 @@ gdk_texture_new_from_file
|
||||
gdk_texture_get_width
|
||||
gdk_texture_get_height
|
||||
gdk_texture_download
|
||||
gdk_texture_save_to_png
|
||||
GdkMemoryFormat
|
||||
GDK_MEMORY_DEFAULT
|
||||
GDK_MEMORY_FORMAT_DEFAULT
|
||||
gdk_memory_texture_new
|
||||
gdk_gl_texture_new
|
||||
gdk_gl_texture_release
|
||||
@@ -772,60 +777,40 @@ gdk_cursor_get_type
|
||||
<SECTION>
|
||||
<TITLE>Drag and Drop</TITLE>
|
||||
<FILE>dnd</FILE>
|
||||
GdkDrag
|
||||
GdkDrop
|
||||
GdkDragContext
|
||||
GdkDragCancelReason
|
||||
gdk_drop_reply
|
||||
gdk_drag_drop_done
|
||||
gdk_drag_begin
|
||||
GdkDragAction
|
||||
GDK_ACTION_ALL
|
||||
|
||||
gdk_drag_get_display
|
||||
gdk_drag_get_actions
|
||||
gdk_drag_get_suggested_action
|
||||
gdk_drag_get_selected_action
|
||||
gdk_drag_get_formats
|
||||
gdk_drag_get_device
|
||||
gdk_drag_get_drag_surface
|
||||
gdk_drag_set_hotspot
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_drag_action_is_unique
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_drop_get_display
|
||||
gdk_drop_get_device
|
||||
gdk_drop_get_surface
|
||||
gdk_drop_get_formats
|
||||
gdk_drop_get_actions
|
||||
gdk_drop_get_drag
|
||||
gdk_drop_status
|
||||
gdk_drop_finish
|
||||
gdk_drop_read_async
|
||||
gdk_drop_read_finish
|
||||
gdk_drop_read_value_async
|
||||
gdk_drop_read_value_finish
|
||||
gdk_drop_read_text_async
|
||||
gdk_drop_read_text_finish
|
||||
GdkDragAction
|
||||
gdk_drag_status
|
||||
gdk_drag_drop_succeeded
|
||||
|
||||
gdk_drag_context_get_display
|
||||
gdk_drag_context_get_actions
|
||||
gdk_drag_context_get_suggested_action
|
||||
gdk_drag_context_get_selected_action
|
||||
gdk_drag_context_get_formats
|
||||
gdk_drag_context_get_device
|
||||
gdk_drag_context_get_source_surface
|
||||
gdk_drag_context_get_dest_surface
|
||||
gdk_drag_context_get_drag_surface
|
||||
gdk_drag_context_set_hotspot
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GDK_DRAG
|
||||
GDK_TYPE_DRAG
|
||||
GDK_IS_DRAG
|
||||
GDK_DRAG_CLASS
|
||||
GDK_DRAG_GET_CLASS
|
||||
GDK_IS_DRAG_CLASS
|
||||
GDK_DRAG_CONTEXT
|
||||
GDK_TYPE_DRAG_CONTEXT
|
||||
GDK_IS_DRAG_CONTEXT
|
||||
GDK_DRAG_CONTEXT_CLASS
|
||||
GDK_DRAG_CONTEXT_GET_CLASS
|
||||
GDK_IS_DRAG_CONTEXT_CLASS
|
||||
GDK_TYPE_DRAG_ACTION
|
||||
GDK_TYPE_DRAG_PROTOCOL
|
||||
GDK_TYPE_DROP
|
||||
GDK_DROP
|
||||
GDK_IS_DROP
|
||||
|
||||
<SUBSECTION Private>
|
||||
GdkDragClass
|
||||
gdk_drag_get_type
|
||||
GdkDropClass
|
||||
gdk_drop_get_type
|
||||
GdkDragContextClass
|
||||
gdk_drag_context_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
@@ -868,6 +853,7 @@ gdk_x11_screen_lookup_visual
|
||||
gdk_x11_screen_supports_net_wm_hint
|
||||
gdk_x11_screen_get_number_of_desktops
|
||||
gdk_x11_screen_get_current_desktop
|
||||
gdk_x11_surface_foreign_new_for_display
|
||||
gdk_x11_surface_lookup_for_display
|
||||
gdk_x11_surface_get_xid
|
||||
gdk_x11_surface_set_theme_variant
|
||||
@@ -1120,10 +1106,6 @@ gdk_frame_timings_get_type
|
||||
GdkDrawContext
|
||||
gdk_draw_context_get_display
|
||||
gdk_draw_context_get_surface
|
||||
gdk_draw_context_begin_frame
|
||||
gdk_draw_context_end_frame
|
||||
gdk_draw_context_is_in_frame
|
||||
gdk_draw_context_get_frame_region
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GDK_DRAW_CONTEXT
|
||||
@@ -1157,6 +1139,7 @@ gdk_gl_context_is_legacy
|
||||
<SUBSECTION>
|
||||
GdkGLError
|
||||
gdk_gl_context_realize
|
||||
gdk_gl_context_get_damage
|
||||
gdk_gl_context_make_current
|
||||
gdk_gl_context_get_current
|
||||
gdk_gl_context_clear_current
|
||||
@@ -1201,12 +1184,23 @@ GDK_IS_MONITOR
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gdkcairocontext</FILE>
|
||||
GdkCairoContext
|
||||
gdk_cairo_context_cairo_create
|
||||
<FILE>gdkdrawingcontext</FILE>
|
||||
GdkDrawingContext
|
||||
gdk_drawing_context_get_surface
|
||||
gdk_drawing_context_get_clip
|
||||
gdk_drawing_context_get_cairo_context
|
||||
gdk_drawing_context_is_valid
|
||||
gdk_drawing_context_get_paint_context
|
||||
|
||||
<SUBSECTION Standard>
|
||||
gdk_cairo_context_get_type
|
||||
gdk_drawing_context_get_type
|
||||
GdkDrawingContextClass
|
||||
GDK_TYPE_DRAWING_CONTEXT
|
||||
GDK_DRAWING_CONTEXT_CLASS
|
||||
GDK_DRAWING_CONTEXT_GET_CLASS
|
||||
GDK_IS_DRAWING_CONTEXT_CLASS
|
||||
GDK_DRAWING_CONTEXT
|
||||
GDK_IS_DRAWING_CONTEXT
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
@@ -1264,7 +1258,6 @@ gdk_clipboard_get_type
|
||||
<SECTION>
|
||||
<FILE>gdkcontentprovider</FILE>
|
||||
GdkContentProvider
|
||||
GdkContentProviderClass
|
||||
gdk_content_provider_new_for_value
|
||||
gdk_content_provider_new_for_bytes
|
||||
gdk_content_provider_ref_formats
|
||||
@@ -1280,6 +1273,7 @@ GDK_CONTENT_PROVIDER_CLASS
|
||||
GDK_CONTENT_PROVIDER_GET_CLASS
|
||||
GDK_IS_CONTENT_PROVIDER
|
||||
GDK_IS_CONTENT_PROVIDER_CLASS
|
||||
GdkContentProviderClass
|
||||
gdk_content_provider_get_type
|
||||
</SECTION>
|
||||
|
||||
@@ -1338,4 +1332,3 @@ GDK_CONTENT_DESERIALIZER
|
||||
GDK_IS_CONTENT_DESERIALIZER
|
||||
gdk_content_deserializer_get_type
|
||||
</SECTION>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user