Compare commits

..

6 Commits

Author SHA1 Message Date
Matthias Clasen
a0df3ac544 paned: Stop using motion notify
We can use the new motion event controller that
was introduced for this purpose.
2017-12-11 19:27:35 -05:00
Matthias Clasen
6dde66d4d8 about dialog: Stop using event-after as well
We can just use a multipress gesture for this purpose.
2017-12-11 19:00:24 -05:00
Matthias Clasen
3e2363eb03 about dialog: Stop using motion notify
We can use the new motion event controller for this.
2017-12-11 18:46:47 -05:00
Matthias Clasen
d66ba60128 label: Use GtkEventControllerMotion
This lets us avoid legacy event signals here.
2017-12-11 18:30:22 -05:00
Matthias Clasen
e52675206b Add a simple motion eventcontroller
This can serve as a replacement for the legacy
event signals for enter/leave/motion notify.
2017-12-11 18:30:03 -05:00
Matthias Clasen
1521bdbaa7 Try to make a composite entry
This is an attempt to see how much work is needed to
reproduce entry icons by just putting an entry and images
in a box, with some css glue.
2017-12-11 00:02:21 -05:00
2546 changed files with 281547 additions and 325083 deletions

1
.gitignore vendored
View File

@@ -1 +0,0 @@
/subprojects/*/

View File

@@ -1,82 +0,0 @@
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
stage: build
script:
- bash -x ./.gitlab-ci/test-docker.sh
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
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/
artifacts:
paths:
- public
only:
- master

View File

@@ -1,82 +0,0 @@
FROM fedora:29
RUN dnf -y install \
hicolor-icon-theme \
adwaita-icon-theme \
atk-devel \
at-spi2-atk-devel \
avahi-gobject-devel \
cairo-devel \
cairo-gobject-devel \
ccache \
colord-devel \
cups-devel \
desktop-file-utils \
elfutils-libelf-devel \
fribidi-devel \
gcc \
gcc-c++ \
gdk-pixbuf2-devel \
gdk-pixbuf2-modules \
gettext \
git \
glib2-devel \
glibc-devel \
glibc-headers \
gobject-introspection-devel \
graphene-devel \
gstreamer1-devel \
gstreamer1-plugins-good \
gstreamer1-plugins-bad-free-devel \
gstreamer1-plugins-base-devel \
gtk-doc \
iso-codes \
itstool \
json-glib-devel \
lcov \
libattr-devel \
libepoxy-devel \
libffi-devel \
libmount-devel \
librsvg2 \
libselinux-devel \
libXcomposite-devel \
libXcursor-devel \
libXcursor-devel \
libXdamage-devel \
libXfixes-devel \
libXi-devel \
libXinerama-devel \
libxkbcommon-devel \
libXrandr-devel \
libXrender-devel \
libxslt \
mesa-dri-drivers \
mesa-libEGL-devel \
mesa-libwayland-egl-devel \
ninja-build \
pango-devel \
pcre-devel \
python3 \
python3-pip \
python3-wheel \
redhat-rpm-config \
sassc \
systemtap-sdt-devel \
vulkan-devel \
wayland-devel \
wayland-protocols-devel \
which \
xorg-x11-server-Xvfb \
&& dnf clean all
RUN pip3 install meson==0.49.0
ARG HOST_USER_ID=5555
ENV HOST_USER_ID ${HOST_USER_ID}
RUN useradd -u $HOST_USER_ID -ms /bin/bash user
USER user
WORKDIR /home/user
ENV LANG C.UTF-8

View File

@@ -1,44 +0,0 @@
#!/bin/bash
set -e
appid=$1
builddir=app
repodir=repo
flatpak-builder \
--stop-at=gtk \
${builddir} \
build-aux/flatpak/${appid}.json
flatpak-builder \
--run ${builddir} build-aux/flatpak/${appid}.json \
meson \
--prefix /app \
--libdir /app/lib \
--buildtype debug \
-Dx11-backend=true \
-Dwayland-backend=true \
-Dprint-backends=file \
-Dbuild-tests=false \
-Dbuild-examples=false \
-Dintrospection=false \
-Ddemos=true \
_build .
flatpak-builder \
--run ${builddir} build-aux/flatpak/${appid}.json \
ninja -C _build install
flatpak-builder \
--finish-only \
--repo=${repodir} \
${builddir} \
build-aux/flatpak/${appid}.json
flatpak build-bundle \
${repodir} \
${appid}-dev.flatpak \
--runtime-repo=https://flathub.org/repo/flathub.flatpakrepo \
${appid}

View File

@@ -1,11 +0,0 @@
#!/bin/bash
set -e
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v2"
sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \
--file "Dockerfile" .
sudo docker run --rm --security-opt label=disable \
--volume "$(pwd)/..:/home/user/app" --workdir "/home/user/app" \
--tty --interactive "${TAG}" bash

View File

@@ -1,32 +0,0 @@
#!/bin/bash
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 \
--print-errorlogs \
--suite=gtk \
--no-suite=gtk:gsk \
--no-suite=gtk:a11y

View File

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

View File

@@ -1,36 +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.
-->
## Current behavior
<!--
Please describe the current behaviour
-->
## Expected outcome
<!--
Please describe the expected outcome
-->
## 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
-->
## Additional information
<!--
- Screenshots or screen recordings are useful for visual errors
- Please report any warning or message printed on the terminal
-->

View File

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

View File

@@ -1,266 +1,40 @@
# Contribution guidelines If you want to hack on the GTK+ project, you'll need to have the development
tools appropriate for your operating system, including:
Thank you for considering contributing to the GTK project! - Python (2.7 or 3.x)
- Meson
These guidelines are meant for new contributors, regardless of their level - Ninja
of proficiency; following them allows the maintainers of the GTK project to - Gettext (19.7 or newer)
more effectively evaluate your contribution, and provide prompt feedback to - a C99 compatible compiler
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:
- Python 3.x
- Meson
- Ninja
- Gettext (19.7 or newer)
- a [C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
Up-to-date instructions about developing GNOME applications and libraries Up-to-date instructions about developing GNOME applications and libraries
can be found on [the GNOME Developer Center](https://developer.gnome.org). can be found here:
The GTK project uses GitLab for code hosting and for tracking issues. More https://developer.gnome.org
information about using GitLab can be found [on the GNOME
wiki](https://wiki.gnome.org/GitLab).
### Dependencies Information about using git with GNOME can be found here:
In order to get GTK from Git installed on your system, you need to have the https://wiki.gnome.org/Git
required versions of all the software dependencies required by GTK; typically,
this means a recent version of GLib, Cairo, Pango, and ATK, as well as the
platform-specific dependencies for the windowing system you are using (Wayland,
X11, Windows, or macOS).
The core dependencies for GTK are: In order to get Git GTK+ installed on your system, you need to have the
required versions of all the GTK+ dependencies; typically, this means a
recent version of GLib, Cairo, Pango, and ATK.
- [GLib, GObject, and GIO](https://gitlab.gnome.org/GNOME/glib) **Note**: if you plan to push changes to back to the master repository and
- [Cairo](http://cairographics.org) have a GNOME account, you want to use the following instead:
- [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
You should start by forking the GTK repository from the GitLab web UI, and
cloning from your fork:
```sh ```sh
$ git clone https://gitlab.gnome.org/yourusername/gtk.git $ git clone ssh://<username>@git.gnome.org/git/gtk+
$ cd gtk
``` ```
**Note**: if you plan to push changes to back to the main repository and To compile the Git version of GTK+ on your system, you will need to
have a GNOME account, you can skip the fork, and use the following instead:
```sh
$ git clone git@gitlab.gnome.org:GNOME/gtk.git
$ cd gtk
```
To compile the Git version of GTK on your system, you will need to
configure your build using Meson: configure your build using Meson:
```sh ```sh
$ meson _builddir . $ meson _builddir .
$ cd _builddir
$ ninja
``` ```
Typically, you should work on your own branch: For information about submitting patches and pushing changes to Git, see the
`README.md` and `README.commits` files. In particular, don't, under any
```sh circumstances, push anything to Git before reading and understanding
$ git checkout -b your-branch `README.commmits`.
```
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).

8111
NEWS

File diff suppressed because it is too large Load Diff

View File

@@ -1,903 +0,0 @@
Overview of Changes in GTK+ 2.0.0
=================================
* GtkTreeView fixes [Jonathan Blandford, Kristian Rietveld, Darin Adler]
* Build fixes [Anders Carlsson, Tor Lillqvist, Manish Singh]
* Bug fixes. [Thomas Leonard, Owen Taylor]
Overview of Changes in GTK+ 2.0.0 rc1
=====================================
* GtkTreeView fixes [Kristian Rietveld, Jonathan Blandford, Richard Hult]
* Text widget fixes [Havoc Pennington]
* Efficiency fixes when using Xft [Owen Taylor]
* Key handling fixes and other fixes for Win32 [Hans Breuer, Tor Lillqvist]
* Try to fix key handling without XKEYBOARD extension [Owen]
* Documentation fixes and improvements
[Matthias Clasen, Alexey Malyshev, Akira Tagoh, Vitaly Tishkov]
* Widget drawing improvements [Soeren Sandmann]
* Allow cycling between multiple menu bars with <Control>Tab [Owen]
* Try to build libraries with only shared library dependencies on Xft to
deal with transition to Xft2 [Owen]
* Portability fixes [Owen, Miroslaw Dobrzanski-Neumann]
* Don't use red as the default cursor color [Owen]
* Bug fixes, bug fixes, bug fixes.
Other contributors: Darin Adler, Jacob Berkman, Kevin Breit, Hans Breuer,
Anders Carlsson, Damon Chaplin, Finlay Dobbie, Jody Goldberg,
Andreas J. Guelzow, Scott Guilbeaux, Vlad Harchev, James Henstridge,
Tim Janik, Satyajit Kanungo, Charles Kerr, Sergey Kuzminov, Miles Lane,
Alexander Larsson, Paolo Maggi, Skip Montaro, Jan Mynarik, Sven Neumann,
Padraig O'Briain, Narayani Pattipati, Mark Patton, Havoc Pennington,
Ettore Perazzoli, Guillermo S. Romero, Manish Singh, Morten Welinder
Overview of Changes in GTK+ 1.3.15
==================================
* New stock and improved icon images
[Tuomas Kuosmanen, Jakub Steiner, Anders Carlsson]
* Widget drawing improvements for check and radio buttons,
spinbuttons [Soeren Sandmann]
* Clean up module search path algorithm, use GTK_PATH [Owen Taylor]
* Add GtkSetting for font name. [Richard Hestilow]
* Much improved key matching code, accelerators work independent
of group [Owen]
* Make mnemonics work for embedded GtkPlug widgets [Owen]
* Keynav improvements for GtkTreeView [Kristian Rietveld]
* Fix gtk_tree_view_scroll_to_cell() [Jonathan Blandford]
* Rename gtk_tree_view_get_iter_root() and gtk_tree_path_new_root()
to gtk_tree_view_get_iter_first() and gtk_tree_path_new_first(),
add compatibility macros.
* GtkTreeView bug fixes [Kristian, Anders, Damon Chaplin]
* GtkTextView bug fixes [Havoc Pennington]
* Pad class structures for future binary compatibility [Owen]
* Tutorial improvements [Sven Neumann, Matthias Clasen]
* Fixes for MULTIPLE selection target [Gregory Merchan, Owen]
* Fix problems with initial widget size [Owen]
* AIX compilation fixes [Miroslaw Dobrzanski-Neumann]
* Win32 fixes [Hans Breuer, Tor Lillqvist]
* Miscellaneous bug fixes
Other contributors: David L. Cooper, Eric Fischer, Jody Goldberg,
Satajyit Kanungo, Thomas Leonard, Mark Patton, Manish Singh,
Nicolas Setton
Overview of Changes in GTK+ 1.3.14
==================================
* Keyboard focus improvements [Owen Taylor]
* Code cleanup [Matthias Clasen, Manish Singh, Darin Adler]
* Fix accidentally exported variables [Mark McLoughlin]
* GtkTreeView fixes [Jonathan Blandford, Kristian Rietveld, John Harper, Darin]
* Default to yellow tooltips [Owen]
* RC file fixes for reloading, priorities [Owen, Matthias]
* GtkMenu behavior improvements and bug fixes [Owen, Arnaud Charlet]
* GtkTextView fixes [Havoc Pennington, Daniel Elstner, Dennis Bjorklund]
* Improve keynav for paned widgets, tooltips, spin buttons, notebooks,
scrolled windows [Soeren Sandmann, Padraig, Owen]
* Add Emacs/Default key themes [Owen]
* Win32 fixes [Hans Breuer, Tor Lillqvist]
* Ethiopic input methods [Daniel Yacob]
* Opaque paned window resizing [Soeren]
* Tweak table expansion behavior [Tim Janik]
* Fix GtkCalendar focus drawing [Bill Haneman]
* Allow themeable cursor thickness [Bill]
* Start of fixing of tutorial for GTK+-2.0 [Matthias]
* Add a ::adjust-bounds signal to GtkRange to allow spreadsheet style
scrollbars. [Jody Goldberg]
* Add the ability to turn on multiple selection for GtkFileSel [Manish]
* Bug fixes
Other contributors: Jacob Berkman, Padraig O'Briain, Anders Carlsson,
Johan Dahlin, Richard Hult, Stefan Kost, Alex Larsson, Thomas Leonard,
Paolo Maggi, Alexey Malyshev, Federico Mena Quintero, Skip Montaro,
Sven Neumann, Havoc Pennington, Laszlo Peter, Christian Rose, Joe Shaw,
Kevin Vandersloot, Morten Welinder, Peter Williams
Overview of Changes in GTK+ 1.3.13
==================================
* Tree view fixes. [Kristian Rietveld, Jonathan Blandford, Anders Carlsson]
* Tree view support for low-vision themes [Bill Haneman]
* Text view bug fixes. [Havoc Pennington]
* Win32 fixes and improvements. [Tor Lillqvist, Hans Breuer,
Archaeopteryx Software]
* Documentation improvements [Matthias Clasen, Havoc Pennington]
* Accelerate alpha compositing using RENDER extension if present,
and optimize the non-RENDER case a lot. [Owen Taylor]
* Add support for "optional keybindings" (action signal returns FALSE) [Owen]
* Fixed the infamous changing directory deletes filename bug
[Owen and a cast of thousands]
* Add mouse cursor hiding for text widgets [Anders Carlsson]
* Simple Hangul input module [Yusuke Tabata]
* Removed the scary startup warning.
* GdkPixbuf pixel handling fixes [Owen, Michael Hore, Jim Cape]
* Converted GtkFileSelection and GtkFontSelection to use GtKTreeView widgets
instead of the deprecated GtkCList [Owen]
* gtkhsv.h was installed by mistake, fixed that. [reported by Ross Burton]
* gdk_pixbuf_render_to_drawable() now also handles alpha pixbufs.
* Made Gtkimage draw GtkPixmap, GtkImage, GdkPixbuf insensitive, prelighted,
etc. [Havoc, Owen]
* Marked gtk_item_factory_path_from_widget() G_CONST_RETURN. [Matt Wilson]
* gtk_image_menu_item_new_from_stock() now falls back to
new_with_mnemonic, for consistency with gtk_button_new_from_stock()
[Havoc Pennington]
* GdkModifierType is now consistently used for modifier mask parameters
[Mark Patton]
* gtk_widget_set_accel_path() is now publically exported.
Other contributors: Darin Adler, Jeffrey Baker, Damon Chaplin, Brian Cameron,
Murray Cumming, James Henstridge, Jacob Berkman, Arnaud Charlet, Jeff Franks,
Jeff Garzik, Jody Goldberg, Diego Gonzalez, Melvin Hadasht, Raja Harinath,
Tim Janik, Mike Kestner, Mathieu Lacage, Alex Larsson, Ryan Lovett,
Mark McLoughlin, Sven Neumann, Padraig O'Briain, Xavier Ordoquy, Chris Phelps,
Detlef Reichl, Guillermo S. Romero, Federico Mena Quintero, Manish Singh,
HideToshi Tajima, Vitaly Tishkov, Jon Trowbridge, Sergey Vlasov.
Overview of Changes in GTK+ 1.3.12
==================================
* Fix problems with PNG saving [Michael Natterer]
* Cleanups of deprecated usages [Sebastian Wilhelmi]
* Win32 fixes [Tor Lillqvist]
* Documentation improvements [Matthias Clasen, Havoc Pennington,
Vitaly Tishkov]
* Frame buffer port fixes [Manish Singh]
* GtkTextView bug fixes [Havoc Pennington, Chris Phelps]
* Menu behavior improvements [Kristian Rietveld]
* Make focus line width configurable, focus color work on
dark themes. [Bill Haneman, Owen Taylor]
* Add state argument to gtk_paint_focus() [Bill]
* Added incremental revalidation to tree view, for better apparent speed
[Jonathan Blandford]
* Remove useless gtk_tree_view_column_cell_event() [Jonathan]
* Display XIM status in a separate window [HideToshi Tajima]
* Add GDK_DEBUG=nograbs to disable pointer, keyboard grabs [Jacob Berkman]
* Add menu of Unicode control characters to GtkEntry, GtkTextView
[Dov Grobgeld, Havoc]
* Pass key releases along to input methods [Owen]
* Many bug fixes
Other contributors: Darin Adler, Fabrice Bellet, Chris Blizzard,
Hans Breuer, Anders Carlsson, Damon Chaplin, Murray Cumming, Jeff Franks,
James Henstridge, Tim Janik, Alex Larsson, George Lebl, Kjartan, Maraas,
Sven Neumann, Seth Nickell, Padraig O'Briain, Soeren Sandmann, Manish Singh,
Matt Wilson
Overview of Changes in GTK+ 1.3.11
==================================
* Massive rework of accelerator API and implementation (Tim Janik)
* Major fixes to resizing and redrawing to eliminate hysteresis
and optimize. (Owen Taylor, Soeren Sandmann)
* Make many widgets NO_WINDOW to improve appearance and reduce
drawing overhead (Owen)
* Text view fixes (Havoc Pennington)
* Make child widgets in GtkTextView work (Havoc)
* GtkTreeModelSort fixage (Jonathan Blandford, Kristian Rietveld)
* Clean up GtkTreeView drag and drop support (Owen)
* Misc tree view fixes and improvements (Jonathan, Kristian, Anders, Matt Wilson)
* Add gtk_window_get/set_focus(), gtk_window_set_default() as public
functions (Owen, Damian Ivereigh)
* Fixes to GtkPlug/GtkSocket (Michael Meeks, Owen)
* Change button ordering in standard dialogs to correspond to
GNOME usability project proposal (Gregory Merchan)
* Add support for context sensitivity in input methods (Owen)
* Hook up gtk_im_context_set_use_preedit() (Hidetoshi Tajima)
* Fix gdk_window_scroll() and other aspects of big windows (Owen)
* Remove need for X connection for class initialization (Jacob Berkman)
* Propagate key events to parents of focused widget (Owen)
* Don't export normal GTK+ marshalers, export deprecated compat marshalers (Owen)
* Many Win32 Fixes and improvements (Hans Breuer, Tor Lillqvist)
* Bug and documentation fixing (Matthias Clasen, Anders Carlsson,
Jacob Berkman, others.)
Other Contributors:
Darin Adler, Marius Andreiana, Erwann Chenede, Murray Cumming, Janet Davis,
Daniel Egger, Daniel Elstner, Jeff Franks, Alex Larsson, George Lebl,
Sergey Kuzminov, Eric Lemings, Arkadiusz Miskiewicz, Padraig O'Briain, Sven Neumann,
Kristian Rietveld, Nicolas Setton, Manish Singh, Vitaly Tishkov, Sebastian Wilhelmi,
Michael Natterer
Overview of Changes in GTK+ 1.3.10
==================================
* GtkTextView fixes [Havoc Pennington]
* GtkTreeView fixes and improvements [Jonathan Blandford, Kristian,
Manish Singh, Joshua Pritikin, Oleg Maiboroda, James Henstridge]
* gtkdemo improvements [Kristian Rietveld]
* Drag and drop fixes to generic code and widgets
[Owen Taylor, Damian Ivereigh]
* Documentation improvement [Havoc Pennington, Matthias Clasen]
* Spelling fixes [Jacob Berkman]
* Move signals to the GtkEditable interface [Kristian]
* Further stock image improvements [Jakub Steiner]
* Support text chunks for the PGN loader, add gdk_pixbuf_get_option()
[Sven Neumann]
* Rename gdk_pixbuf_new_from_stream back to new_from_inline [Owen]
* Automatically call setlocale(), unless explicitly disabled [Owen]
* Property addition to various widgets [Michael Meeks, Owen]
* Support building with automake-1.4 [James]
* Make GtkRadioButton groups act as a single focus point [Owen]
* Move gdk_window_lookup etc. to be cross-platform [Matthias]
* Draw spinbuttons variably sized [Kristian]
* Separate GdkAtom out from X atoms for compatibility with future
multihead changes [Owen]
* Require gdk_threads_init() to be explicitly called instead
of piggybacking off of g_thread_init(). [Owen]
* Improvements to text-view/label/entry popup menus [Damian, Jacob, Owen]
* Bug fixes and cleanup [Matthias, others]
Other Contributors:
Mark McLoughin, Mikael Hermansson, Soeren Sandmann, Anders Carlsson,
Tim Janik, Murray Cumming, Hidetoshi Tajima, Padraig O'Briain,
Hans Breuer, Vitaly Tishkov, Dov Grobgeld
Overview of Changes in GTK+ 1.3.9
=================================
* Add editable text cells to GtkTreeView.
Keynav, drawing fixes in GtkTreeView [Jonathan Blandford]
* Text widget no longer always has a \n in it. [Havoc Pennington]
* Text widget bug fixes [Havoc, Dov Grobgeld, Hidetoshi Tajima]
* Allow -1 for width/height in gdk_pixbuf_render_*(). [Matthias Clasen]
* Minor fix for major resizing problems in recent releases [Owen Taylor]
* Restore ability to set _set properties to TRUE for
GtkCellRendererText, GtkTextTag [Owen]
* Cursor drawing improvements [Owen]
* Win32 fixes [Hans Breuer]
* Mark various functions as deprecated or private.
* Misc bug fixes, portability fixes, and cleanups.
Other Contributors:
Vitaly Tishkov, Christian Rose, Frank Belew, Jeff Franks, Sven Neumann,
Kristian Rietveld, Vitaly Tishkov, Joshua N. Pritikin, Matt Wilson,
James Henstridge, Detlef Reichl
Overview of Changes in GTK+ 1.3.8
=================================
* GtkTreeView and GtkTreeModel API cleanups/improvements [Jrb]
* GtkOptionMenu scrollwheel support [Alex]
* GtkModule search paths [Owen]
* Documenatation updates [Havoc,Jrb]
* Major Gdk cleanup [Owen]
* Miscellaneous other fixes/cleanups
Other Contributors:
Joshua N Pritikin, Padraig O'Briain, Jakub Steiner, Matthias Clasen,
Matt Wilson, James Henstridge
Overview of Changes in GTK+ 1.3.7
=================================
* Many Pixbuf (loader) improvements [Matthias Clasen, Soeren Sandmann]
* Added publically installed utility gdk-pixbuf-csource to generate
inlined pixbufs in C source code [Tim Janik]
* Optional movement of button children on press [Soeren, Owen Taylor]
* Interactive searching in GtkTreeView [Kristian Rietveld]
* Sorting/ordering improvements for GtkTreeView [Kris, Jonathan Blandford]
* Animation of expander motion for GtkTreeView [Anders Carlsson]
* Lots of misc GtkTreeView fixes and improvements [Jonathan]
* New/improved stock icons [Jakub Steiner]
* Code and API rework for window resizing [Havoc Pennington]
* Converted accel groups to GObject [James Henstridge]
* More property support improvements
* Add facility for "secondary" buttons in
GtkButtonBox/GtkDialog [Gregory Merchan]
* Disentangled child visability from MAPPED state [Owen]
* Plug/Socket improvements and port to the XEMBED protocol [Owen]
* Added priorities for styles in RC files,
support multiple parse contents [Owen]
* Made GdkVisual and GdkDevice GObjects [Alexander Larsson]
* Key binding improvements [Havoc]
* Added GtkWidget::event-after signal since normal event handling
is now aborted as soon as a handler returned TRUE [Tim]
* Dnd fixes and improved icon support [Owen]
* Removed GtkPacker widget
* Fixing missing paired getters/setters [Kris]
* Nuked remaining GtkArg cruft, implemented container/child properties [Tim]
* Added window grab groups [Owen]
* Many frame buffer improvements [Alex]
* Win32 fixes and improvements [Hans Breuer]
* Warning fixes [Darin Adler]
* Miscellaneous bug and API fixes [Matthias et. al]
Other Contributors:
Joshua N Pritikin, Hidetoshi Tajima, Manish Singh, ERDI Gergo, Jens Finke,
Chema Celorio, Lee Mallabone, Vitaly Tishkov, Sebastian Wilhelmi,
Nicola Girardi, Sven Neumann, Padraig O'Briain, Michael Natterer,
Suresh Chandrasekharan, Jonas Borgström, Jay Cox, Michael Meeks,
Mathias Hasselmann, Peter Williams, Thomas Broyer, Kjartan Maraas,
Joel Becker, Jeff Franks, Brian Cameron, Skip Montanaro
Overview of Changes in GTK+ 1.3.6
=================================
* Properly renders strikethrough text
* win32 fixes
* Added "scale" property to GtkTextTag and GtkCellRendererText to do
relative font scaling
* Added "format_value" signal to GtkScale to reformat value text
* framebuffer fixes
* Property support added to lots of widgets
* Many GtkTreeView new features and API/implementation fixes
* Lots of new_with_mnemonic() convenience functions
* Change GtkImageMenuItem API to be more consistent/useful
* Added lots of new stock items/icons
* Rewrote GtkRange/GtkScale/GtkScrollbar, includes support for
enabling/disabling extra scrollbar stepper arrows in gtkrc so NeXT
themes won't need broken hacks
* Convenience API for GtkRange similar to the one added to GtkSpinButton
a while back
* Make menubar/toolbar work properly with xthickness/ythickness of 1 or 0,
and move some attributes from program settings to user settings.
Allows nice 1-pixel-bevel themes.
* Moved ::focus virtual function from GtkContainer to GtkWidget
* Plenty of bug fixes
Overview of Changes in GTK+ 1.3.5
=================================
* New default theme based on Raleigh theme for 1.2.x.
* Dependency on the ATK library added as a step to
providing accessibility-enabling interfaces
* XEMBED-based GtkPlug/GtkSocket now basically works.
* Drag and drop of column headers in GtkTreeView
* GtkColorSelector work: hooks for saving and propagating palette, UI tweaks,
and API sanitation
* Key binding fixes
* Configurable padding/spacing in a lot of places
* Invisible text in GtkTextView fixed
* SHM segments now created with a mode of 0600
* Bug fixes
Overview of Changes in GTK+ 1.3.4
=================================
* Win32 fixes
* GtkTreeView improvements and fixes
* Fix glib-2.0.m4
* Miscellaneous bug fixes
Overview of Changes in GTK+ 1.3.3
=================================
[ 5600 lines of ChangeLog ]
* API cleanups
* Win32 work (Tor, Hans Breuer)
* Focus improvements (Owen)
* Frame buffer improvements (Alex)
* Work on GtkTextView (Havoc)
* Much work on GtkTreeView (Jonathan)
* Selectable labels (Havoc)
* Converted many arguments to properties (Lee Mallabone, John Margaglione)
* Add exact regions to GdkExposeEvent, propagate it. (Alex)
* Added ability to have resize grips in status bars (etc.) using
_NET_WM_MOVERESIZE protocol. (Havoc)
* Added mnemnonic mechanism to make setting underline accelerators
much easier. (Alex)
* Add per-style property mechanism to allow themes to change
geometry parameters. (Tim)
* Added global settings mechanisms for settings such as double-click
time. (Tim, Owen)
* Various support functions for new and old WM properties (Havoc, Alex)
* Add TRUE-stops-returns for boolean-returning signals (Ron Steinke)
Overview of Changes in GTK+ 1.3.2
=================================
GTK Core:
* New stock-icon and stock-item system. Use themeable pixbufs in
dialogs, buttons, etc. [Havoc]
* Theme engines reworked to use derivation and new object system. [Owen]
* Added GtkClipboard object for simple selection handling. [Owen]
* Make GtkEditable an interface, move implementation to GtkOldEditable for
compat. [Owen]
* Better handling of default directionality. [Robert]
* Use GSignal as backend for GtkSignal and other GObject stuff. [Tim]
* Move theme engines to GTypePlugin. [Owen]
GDK:
* Beginning of implementation of client parts of new window manager spec. [Owen]
* Make gdk_drawable_get_image() work with backing store. [Havoc]
Widgets:
* New text widget [Havoc]
- Adjustable tab handling.
- Ability to have scrolling side areas in new text widget for tabs/line numbers.
- Many cleanups and small improvements.
* Improvements to submenu navigation [Nils Barth/David Santiago] and
scrolling menus. [Alex]
* Simplification of progress bar API. [Havoc]
* Make GtkImage a generic image-display widget. [Havoc]
* New GtkTreeView tree widget. Model/view architecture, flexible rendering,
large datasets, etc. [Jonathan]
* New GtkMessageBox widget for message display. [Havoc]
* Allow labels to have contents set from XML-like markup language. [Havoc]
* Make dialogs derive from GtkDialog and use stock buttons. [Havoc]
Internationalization:
* Proper character set conversion for clipboard/selection. [Owen]
* New input method system via loadable modules; support on-the-spot
preedit in GtkEntry and new text widget; allow switching input methods
on the fly; include modules for XIM and demo Cyrillic-transliteration
module. [Owen]
* VIQR, Thai, and Inuktitut input methods. [Robert]
* Convert po files to UTF-8. [Robert]
gdk-pixbuf:
* Full-alpha compositing for gdk-pixbuf on drawable. [Havoc]
* Add simple saving to gdk-pixbuf. [David Welton/Havoc]
* Add improved error handling with GError to gdk-pixbuf. [Havoc]
Ports:
* Much work on Win32 Port. [Tor/Hans]
* Much work on Linux-FB Port. [Elliot/Alex]
Misc:
* Start of new gtk-demo demo program. [Owen/Jonathan]
* Bug fixes and more bug fixes.
Overview of Changes in GTK+ 1.3.1:
* GTK+ now uses the Pango library for text manipulation. All
strings in GTK+ now are in Unicode, languages written
from right-to-left, and complex-text languages are now supported.
* The gdk-pixbuf library for image loading and manipulation is
has been integrated with GTK+.
* The GTK+ object system has mostly been moved to GLib, separating
it from the GUI code. Many significant enhancements have been
made as part of this.
* A new text widget is now included. This started as a port
of the Tk text widget, and includes such features of the Tk
text widget as tags, marks, and unicode text support. It
has been enhanced to support model-view operation and the
full power of Pango.
* The GDK library has been extensively revised to support multiple
windowing systems. The only fully functional backend in 1.3.1
is the X11 backend, however, ports to Win32, Linux-framebuffer,
Nano-X, BeOS, and MacOS exist in various states of completion,
and at least some of these will be finished and integrated in
before the final GTK+-2.0 release.
* 32-bit coordinates are now supported throughout GDK and GTK+
(they are emulated where not supported by the windowing system.)
* Many minor bug fixes and enhancements. Incompatible changes
are documented in docs/Changes-2.0.txt
Overview of Changes in GTK+ 1.2.8:
* GNU Make 3.79 bug workaround
* FAQ and tutorial updates and improvements
* Miscellaneous bug fixes: CList, Calendar, rc-files, FontSelection
Overview of Changes in GTK+ 1.2.7:
* More header cleanups.
* Fixed activation bug for insensitive widgets.
* Locale fixes to RC file parsing code.
* Miscellaneous bugfixes for Item Factory, CList, CTree, X Selections,
HScale, VScale, Pixmap, Viewport, OptionMenu, Entry and Notebook.
* Upgrade to libtool 1.3.4.
Overview of Changes in GTK+ 1.2.6:
* container queue_resize fixes
* gtk[vh]scale: minor fixups
* rename idle to idle_id in testgtk to avoid conflicts with
broken libs
* More consistent naming of gtkrc files
* Added language support: ro, uk
Overview of Changes in GTK+ 1.2.5:
* more GtkCTree and GtkWindow bug fixes.
* more redraw/resize queue fixes, better expose event
discarding code.
* more miscellaneous bugs fixed
* new configure.in option --disable-rebuilds to completely disable
rebuilds of autogenerated sources.
* check for 5.002 now, to avoid failing autogeneration build rules due
to old perl versions.
* fonts (and fontsets) are cached now.
* more autogeneration make rules and dependency fixups, we should be
save with autogeneration up to make -j12 now ;)
* new window position GTK_WIN_POS_CENTER_ALWAYS, which will recenter the
GtkWindow on every size change.
* major rework of window manager hints handling code, fixed a bunch of
races with the new resizing code.
* the new wm hints and resizing code is absolutely perfect and bug free now,
it only lacks testing ;)
* fixed up various rc style memory problems.
* gtk_widget_modify_style() now properly changes the style of realized widgets
and references the style passed into it. if people worked around this bug,
this will introduce a slight memory leak in their code.
The code should typically look like:
GtkRcStyle *rc_style = gtk_rc_style_new ();
[...]
gtk_widget_modify_style (widget, rc_style);
gtk_rc_style_unref (rc_style);
* fix problems with positioning menus offscreen.
* GtkText fixes for some crashes and drawing errors.
* Better handling for unexpected window destroys in GDK and GTK+.
This should make it possible to use a GtkPlug and catch the
case where its parent socket is randomly killed.
* FAQ updates.
* FileSelection i18n patches, RadioButton fixups.
* many translation improvements.
* miscellaneous other bugs fixed.
Overview of Changes in GTK+ 1.2.4:
* DnD improvements (drags can be canceled with Esc now).
* suppressed configure event reordering in Gdk.
* rewrite of Gtk's configure event handling.
* major improvements for the object argument system (Elena Devdariani).
* major bugfixes for threading, GtkNotebook, GtkItemFactory, GtkCList and
GtkCTree.
* tutorial/FAQ updates, new file generation.txt on autogenerated sources.
* configure's --with-glib= is "officially" unsupported.
* upgrade to libtool 1.3.3.
* various buglets fixed.
Overview of Changes in GTK+ 1.2.3:
* Upgrade to libtool 1.3
* Check for dgettext (for systems with old versions of GNU Gettext)
* Many bug fixes (see ChangeLog for details)
Overview of Changes in GTK+ 1.2.2:
* Improved Dnd behaviour with Motif applications.
* Bug fixes for the Gtk selection code.
* Minor bug fixes to the Gdk Atom cache and Dnd code (with --display option).
* Bug fixes and leak plugs for the Gdk IM code.
* Added gtk_object_get() facility to retrieve object arguments easily.
The var args list expects ("arg-name", &value) pairs.
* Fixed mapping for GdkInputCondition<->GIOCondition, this should fix
problems where closed pipes were no longer signaling GDK_INPUT_READ on
systems with a native poll().
* Some cleanups to GtkLabel's memory allocation code (shouldn't leak memory
anymore).
* We don't attempt to lookup xpm color "None" anymore, this should prevent
eXodus (commercial X windows server) from popping up a color dialog every
time a transparent pixmap is created.
* Fixed bug where Gtk timeout/idle handlers would execute without the global
Gdk lock being held.
* Other minor bug fixes.
Overview of Changes in GTK+ 1.2.1:
* Many Bug fixes have been applied to the menu and accelerator code.
* GtkItemFactory can "adopt" foreign menu items now and manage their
accelerator installation. This is often required to get GtkItemFactory
like accelerator propagation between different windows with the same
menu hierarchy and for centralized parsing and saving of accelerators.
* GtkCList/GtkCTree buttons should always display correctly now.
* Miscellaneous other bug fixes.
What's New in GTK+ 1.2.0 (since 1.0.x):
* New widgets: GtkFontSelector, GtkPacker, GtkItemFactory, GtkCTree,
GtkInvisible, GtkCalendar, GtkLayout, GtkPlug, GtkSocket
* Many new features and robustness for existing widgets
* Theme support
* New DND implementation
* Internationalization of standard dialogs
* New key binding system
* Tearoff menus and menu accelerators
* Wide character support for entry and text
* Resizing code has been overhauled
* Queued redraws of partial areas
* Far better support for object arguments
* Speed optimizations
* Runtime loading of dynamic modules
* Support for GLib log domains
* Tutorial improvements
* A bug fix or two
Overview of Changes in GTK+ 1.1.16:
* Major fixes and improvements for handlebox
* A change to the way widget->requisition works. Now,
widget->requisition is always what the widget requested,
unmodified by the usize. See Changes-1.2.txt for details.
This correct various bugs with gtk_widget_set_usize().
* Fixes for XIM on X11R5 systems
* Don't allow cut-and-paste of text in password-style entries
* --enable-debug is now on by default for the development release.
(When compiling for "production", use --enable-debug=minimum)
* Handle systems where Helvetica is not present more gracefully
* Fixes for memory leaks
* CList and CTree fixes
* Bug fixes for drawing problems.
* Miscellaneous bug fixes to GtkLabel, GtkCList, GtkCTree,
GtkColorsel, Focusing, DND
* Tutorial improvements
Overview of Changes in GTK+ 1.1.15:
* Tutorial Updates
* Added --libs gthread to gtk-config
* Bug fixes
What is new in GTK+ 1.1.14:
* Additions to docs/Changes-1.2.txt
* Just warn when loading theme engine fails
* CLAMP GtkScale digits to a meaningful range
* GTK_LOCALDIR is now defined in a better fashion
* New functions (feature freeze, we know...):
gtk_menu_set_title()
gtk_toggle_button_get_active()
* Some locale fixups in gtkrc code
* Fixes to make gtk_radio_button_set_group() keep only
one radio button in the group active
* Foreign windows are now always treated as viewable; this fixes
a problem where updating didn't occur properly in GtkPlug
* DND fixes for 64 bit architectures, and for specifying operations
with modifier keys.
* Major revisions to GtkLayout: avoid having to create window
for NO_WINDOW children, adjust allocations of children as
scrolled so queued draws work, and a resize is queued instead
of allocating directly in a put() or move()
What is new in GTK+ 1.1.13:
* Dnd and selection bug fixes and memory purification.
* Widget sensitivity fixups.
* Tooltips windows are now named "gtk-tooltips" so rc file rules
can match tooltips windows. Fixed interaction of tooltips and NO_WINDOW
widgets.
* Spin buttons now update their values upon value retrieval.
* Overhaul of the resizing vs. redrawing logic to reduce redrawing needs
a lot. Gtk makes full use of the draw_area coalescing code now, which
got minorly improved as well.
* Containers map their Gdk windows after their children now to reduce
expose event generation.
* Gdk event queue fixups, this solves the double-click problems people were
recently having.
* Account for the fact that GSource's are only properly reentrant from
within dispatch(), thus we don't do Gdk event processing from within
check() or prepare() anymore.
* Rc files feature a bg_pixmap value of "<none>" now.
* Improved session management support in Gdk.
* Automatic disabling of NLS if no gettext is found should work now.
* Removed deprecated functions, docs/Changes-1.2.txt gives an overview.
* Gtk+ development now requires GNU autoconf 2.13, GNU automake 1.4
and GNU libtool 1.2d.
* More bug fixes all over the place.
What is new in GTK+ 1.1.12:
* Korean translation added
* Fixed memory leaks
* A few other bug fixes
What is new in GTK+ 1.1.11:
* Dutch, Japanese, Swedish, Polish, and Norwegian translations
* Removed deprecated _interp variants: gtk_container_foreach_interp,
gtk_idle_add_interp, gtk_timeout_add_interp, gtk_signal_connect_interp
* Lots of cast corrections
* Many fixes
What is new in GTK+ 1.1.9:
* Check for broken glibc 2.0 mb functions and avoid them
* Label and Entry display fixes
* Move main thread back to GDK, for locking when translating events
* Bug fixes
What is new in GTK+ 1.1.8:
* Added support for gettext and the localization of the standard
dialogs.
* Added line-wrapping for the label, and JUSTIFY_FILL
* Support reordering via drag and drop in CList and CTree.
* Replaced GtkDrawWindow widget with a GTK_USER_DRAW flag
* Extended gtkpaned API to support minimum sizes and proportional
resizing.
* Changed the handling of shared memory segments so as to
remove the need for GTK+ to set up signal handlers.
* Re-implemented event loop in terms of the event loop
that has been added to GLib 1.1.8
* Added 'grab_focus' signal to allow keyboard accelerators
for entries.
* Load locale specific RC files if present.
* Bug fixes.
What is new in GTK+ 1.1.7:
* Fixed memory mis-allocation in default files code
* Various event handling fixes
* Wide character support for entry and text
* Destroy widgets _after_ propagating unrealize signals through
widget hierarchy
* Only build XIM-support if available
* Tutorial and examples updates
* Added gtk_drag_source_unset()
What is new in GTK+ 1.1.6:
* The signal system now features emission hooks with special semantics,
refer to the ChangeLog for this.
* Minor? speedups and memory reductions to the emission handling of the
signal system.
* _interp() function variants are deprecated now. the corresponding *_full()
variants are provided for a long time now.
* Dnd abort timeout increased to 10 minutes.
* GtkScrolledWindow inherits from GtkBin now.
* GTK_POLICY_NEVER is implemented for scrolled windows now.
* Lots of API clean ups.
* Incremental freezing abilities.
* Integrated widgets from the GNOME tree: GtkLayout, GtkPlug and GtkSocket.
* New window functions for transient relationship, default size, and
geometry hints
* Default rc files are now read in (<sysconfdir/etc/gtkrc and ~/.gtkrc)
GTK_RC_FILES environment variable and functions are provided to configure
this behavior
* Read doc/Changes-1.2.txt to properly adapt your code.
* Bug Fixes.
What is new in GTK+ 1.1.5:
* Theme integration
* Widget style modification is now handled through GtkRcStyles
* GtkPixmaps now grey out pixmaps when insensitive
* Notebook enhancements
* Shadow configurability for menubars and handleboxes
* DND enhancements
* gtkfilesel now supports automounters better
* Implementation of expose compression
* Queued redraws of partial areas
* Scrolledwindow (+Viewport) source incompatibilities, children that are added
to a scrolled window don't get an automatic viewport anymore. a convenience
function gtk_scrolled_window_add_with_viewport() is supplied for this task
* Deprecated functions will now issue a message, informing the programmer about
the use of this function. These functions will get removed in future versions
* Non-functional functions got removed entirely
* gtk_widget_new() and gtk_object_new() will now auto-construct new objects.
A new function gtk_object_default_construct() is provided now which should
be called after every gtk_type_new() to perform the auto-construction
* Improved argument support of several widgets
* Bug Fixes
What is new in GTK+ 1.1.3:
* GtkCList/GtkCTree now have the ability to:
- hide/show individual columns
- disable/enable column resizing
- set min and max for column widths
- set expander style of the ctree
- set/get row and cell styles
- set spacing between tree expander and cell contents in ctree
- toggle auto_resize for columns
* Must enhanced DND support, removed old DND code
* Idle functions are now implemented via GHook, giving a slight speed
improvement
* An environment variable GTK_MODULES which takes a colon separated
list of module names GTK+ will now automatically load at gtk_init() startup
* GtkFontSel now has support for an extra 'base' filter
* New function gdk_window_set_root_origin to get the real geometry taking
into account window manager offsets
* New function gtk_text_set_line_wrap to toggle line wrapping
* New function gtk_widget_add_events which safely adds additional
events to a widget's event mask
* New function gdk_event_get_time to get the timestamp from a generic
event
* New widget GtkCalendar
* New widget GtkInvisible - InputOnly offscreen windows used for reliable
pointer grabs and selection handling in DND code
* New functions gtk_object_remove_no_notify[_by_id] to remove a certain
data portion without invocation of its destroy notifier
* gtk_spin_button_construct is now deprecated, use gtk_spin_button_configure
instead
* gtk_clist_set_border is now deprecated, use gtk_clist_set_shadow_type
instead
* Removed functions gtk_object_set_data_destroy[_by_id]
* Documentation additions/updates
* HTML and plain text files are now included in the distribution
* Bug fixes, typeness corrections, and general fixups
What is new in GTK+ 1.1.2:
* Gtk+ is now featuring runtime loading of dynamic modules via the
--gtk-modules= command line switch. such modules have to export a
G_MODULE_EXPORT void gtk_module_init (gint *argc, gchar ***argv);
function which will be invoked to initialize the module. since such
modules may create new widget types, they are always resident.
* The tutorial has been updated again.
* Changes to menus including tearoff menus and accelerators.
* Better support for modal dialogs.
* Removed CAN_FOCUS by default from scrollbars and button children of toolbar.
* More improvements and fixes for GtkCList and GtkCTree (i.e. row sorting).
* GtkCTree rows can be unselectable now.
* The GtkCTree API has undergone major renames (see ChangeLog entry from Lars
Hamann on Tue Aug 18 00:29:13 1998).
* A bunch of varargs functions changed to get va_lists working on systems that
implement va_lists as arrays.
* Improvements to the gdkrgb code.
* Improvements to Gdk color handling so we greatly reduce server traffic and
don't leak colors anymore.
* Improved internal widget tree iterators (the GtkContainer::foreach signal
vanished because of this).
* Option menus can have the keyboard focus now.
* More fixups to the text widget.
* GtkFileSelection should behave much more nicely in combination with AFS now.
* Support for label underlining.
* Support for GLib 1.1.3 log domains.
* Documentation improvements.
* Configuration fixes on various platforms.
* Miscellaneous fixes to XInput support.
* Build with shared library dependencies on Linux
* Fix for a major bug in the type systems memory allocation code that could
cause random crashes.
* Libtool update to version 1.2b.
* Lots of bugfixes and cleanups again ;)
What is new in GTK+ 1.1.1:
* Tutorial updates and additions.
* Key binding support for GtkListItems and GtkList.
* Extended selection mode and autoscrolling for GtkLists.
* A GtkCtree now operates on GtkCTreeNode* structures rather than GList*.
* GtkCTreeNodes can now be created from GNode trees.
* Bug fixes for GtkNotebook, GtkCList, GtkCombo and GdkWindow reparentation.
What is new in GTK+ 1.1.0:
* New widget GtkFontSelector.
* New featureful progress bar.
* New container widget GtkPacker.
* New object GtkItemFactory, GtkMenuFactory is deprecated.
* New key binding system, configurable via rcfiles, similar to styles.
* New widget GtkCTree with drag selections and keyboard movement and
and horizontal scrolling. Features also implemented for GtkCList.
* Significant speedups to widget creation and destruction through caching
colormap and visual queries to the XServer.
* Speedups for type creation and especially gtk_type_is_a() checks.
* Speedups in signal lookup, creation and emissions and connection handling.
* Minor speedups with object data allocation and destruction.
* Additions to the signal handling API (e.g. *_emitv).
* Support for rc-file reparsing.
* Resizing logic is now implemented on container widget basis, rather than
for toplevel GtkWindows only.
* Buttons support relief styles now.
* Some widgets are now allocated through memchunks to behave more memory wise.
* Newly included file gtkfeatures.h which defines compatibility macros to
test for certain API features upon program compilation.
* Child arguments support for container widgets.
* Far better support for object arguments, revamp of the underlying
mechanism for speed and reusability. Child/object arguments don't
need to be preceded by the "GtkType::" portion anymore.
* Removed GtkAcceleratorTable in favour of GtkAccelGroup, accelerator display
is now performed by a new widget GtkAccelLabel.
* Overhaul of the resizing code. Resizing behaviour can now be specified
on GtkContainer basis, so the underlying algorithm isn't only available
for GtkWindows.
* GtkTables are now fully resizable.
* The GtkType system now supports an additional base class initialization
function.
* GtkStyles and key bindings can now be looked up depending on the base
types of a widget, through a new keyword `class' in rc files.
* GtkButton derives from GtkBin (finally).
* More descriptive error messages on rc parsing.
* Runtime information is available to query enum/flag definition values.
* Upgrade to libtool-1.2
* Legions of bug fixes, memory leaks, segfaults, of-by-something errors...
including those that already went into the 1.0.x branch.
* A big bunch of features and cosmetic fixups that just got lost in
the masses of changesonfigure problem when cross-compiling

File diff suppressed because it is too large Load Diff

72
README.commits Normal file
View 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

View File

@@ -1,17 +1,15 @@
GTK — The GTK toolkit GTK+ — The GTK toolkit
===================== ======================
[![Build Status](https://gitlab.gnome.org/GNOME/gtk/badges/master/build.svg)](https://gitlab.gnome.org/GNOME/gtk/pipelines)
General information General information
------------------- -------------------
GTK is a multi-platform toolkit for creating graphical user interfaces. GTK+ is a multi-platform toolkit for creating graphical user interfaces.
Offering a complete set of widgets, GTK is suitable for projects ranging Offering a complete set of widgets, GTK+ is suitable for projects ranging
from small one-off projects to complete application suites. from small one-off projects to complete application suites.
GTK is free software and part of the GNU Project. However, the GTK+ is free software and part of the GNU Project. However, the
licensing terms for GTK, the GNU LGPL, allow it to be used by all licensing terms for GTK+, the GNU LGPL, allow it to be used by all
developers, including those developing proprietary software, without any developers, including those developing proprietary software, without any
license fees or royalties. license fees or royalties.
@@ -31,18 +29,13 @@ Information about mailing lists can be found at
- http://www.gtk.org/mailing-lists.php - http://www.gtk.org/mailing-lists.php
Nightly documentation can be found at
- Gtk: https://gnome.pages.gitlab.gnome.org/gtk/gtk/
- Gdk: https://gnome.pages.gitlab.gnome.org/gtk/gdk/
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk/
Building and installing Building and installing
----------------------- -----------------------
In order to build GTK you will need: In order to build GTK+ you will need:
- [a C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements) - a C99 compatible compiler
- [Python 3](https://www.python.org/) - Python 3
- [Meson](http://mesonbuild.com) - [Meson](http://mesonbuild.com)
- [Ninja](https://ninja-build.org) - [Ninja](https://ninja-build.org)
@@ -66,10 +59,10 @@ If you are building the X11 backend, you will also need:
- xrender - xrender
- xi - xi
- xext - xext
- xfixes - xfixes (optional)
- xcursor - xcursor (optional)
- xdamage - xdamage (optional)
- xcomposite - xcomposite (optional)
- [atk-bridge-2.0](https://download.gnome.org/sources/at-spi2-atk) - [atk-bridge-2.0](https://download.gnome.org/sources/at-spi2-atk)
If you are building the Wayland backend, you will also need: If you are building the Wayland backend, you will also need:
@@ -79,7 +72,7 @@ If you are building the Wayland backend, you will also need:
- Wayland-cursor - Wayland-cursor
- Wayland-EGL - Wayland-EGL
Once you have all the necessary dependencies, you can build GTK by using Once you have all the necessary dependencies, you can build GTK+ by using
Meson: Meson:
```sh ```sh
@@ -94,7 +87,7 @@ You can run the test suite using:
$ meson test $ meson test
``` ```
And, finally, you can install GTK using: And, finally, you can install GTK+ using:
``` ```
$ sudo ninja install $ sudo ninja install
@@ -112,27 +105,27 @@ Or [online](https://developer.gnome.org/gtk4/stable/gtk-building.html)
How to report bugs How to report bugs
------------------ ------------------
Bugs should be reported on the [issues page](https://gitlab.gnome.org/GNOME/gtk/issues/new). Bugs should be reported to the GNOME [bug tracking system](https://bugzilla.gnome.org/enter_bug.cgi?product=gtk%2b).
You will need an account for yourself.
In the bug report please include: In the bug report please include:
* Information about your system. For instance: * Information about your system. For instance:
- which version of GTK you are using - which version of GTK+ you are using
- what operating system and version - what operating system and version
- for Linux, which distribution - for Linux, which distribution
- if you built GTK, the list of options used to configure the build - if you built GTK+, the list of options used to configure the build
And anything else you think is relevant. And anything else you think is relevant.
* How to reproduce the bug. * How to reproduce the bug.
If you can reproduce it with one of the demo applications that are If you can reproduce it with one of the test programs that are built
built in the demos/ subdirectory, on one of the test programs that in the tests/ subdirectory, that will be most convenient. Otherwise,
are built in the tests/ subdirectory, that will be most convenient. please include a short test program that exhibits the behavior.
Otherwise, please include a short test program that exhibits the As a last resort, you can also provide a pointer to a larger piece
behavior. As a last resort, you can also provide a pointer to a of software that can be downloaded.
larger piece of software that can be downloaded.
* If the bug was a crash, the exact text that was printed out * If the bug was a crash, the exact text that was printed out
when the crash occurred. when the crash occurred.
@@ -140,10 +133,28 @@ In the bug report please include:
* Further information such as stack traces may be useful, but * Further information such as stack traces may be useful, but
is not necessary. is not necessary.
Contributing
------------
Patches should also be submitted to the bug tracking system. If the patch
fixes an existing bug, add the patch as an attachment to that bug report;
otherwise, enter a new bug report that describes the patch, and attach the
patch to that bug report.
Patches should be in Git-formatted form. You should use `git format-patch`
to generate them. We recommend using [git-bz](http://git.fishsoup.net/man/git-bz.html).
For more information on the recommended workflow, please read
[this wiki page](https://wiki.gnome.org/Git/WorkingWithPatches).
Please, follow the `CODING_STYLE` document in order to conform to GTK+'s
coding style when submitting a code contribution.
Release notes Release notes
------------- -------------
The release notes for GTK are part of the migration guide in the API The release notes for GTK+ are part of the migration guide in the API
reference. See: reference. See:
- [3.x release notes](https://developer.gnome.org/gtk3/unstable/gtk-migrating-2-to-3.html) - [3.x release notes](https://developer.gnome.org/gtk3/unstable/gtk-migrating-2-to-3.html)
@@ -152,7 +163,7 @@ reference. See:
Licensing terms Licensing terms
--------------- ---------------
GTK is released under the terms of the GNU Lesser General Public License, GTK+ is released under the terms of the GNU Lesser General Public License,
version 2.1 or, at your option, any later version, as published by the Free version 2.1 or, at your option, any later version, as published by the Free
Software Foundation. Software Foundation.

View File

@@ -1,73 +0,0 @@
{
"app-id": "org.gtk.Demo",
"runtime": "org.gnome.Platform",
"runtime-version": "master",
"sdk": "org.gnome.Sdk",
"command": "gtk4-demo",
"tags": ["devel", "development", "nightly"],
"desktop-file-name-prefix": "(Development) ",
"finish-args": [
"--device=dri",
"--share=ipc",
"--socket=x11",
"--socket=wayland",
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*",
"--talk-name=ca.desrt.conf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf"
],
"cleanup": [
"/include",
"/lib/pkgconfig", "/share/pkgconfig",
"/share/aclocal",
"/man", "/share/man", "/share/gtk-doc",
"*.la", ".a",
"/lib/girepository-1.0",
"/share/gir-1.0",
"/share/doc"
],
"modules": [
{
"name" : "wayland",
"buildsystem" : "autotools",
"builddir" : true,
"config-opts" : [
"--disable-documentation"
],
"sources" : [
{
"type" : "git",
"url" : "https://github.com/wayland-project/wayland.git"
}
]
},
{
"name": "graphene",
"buildsystem": "meson",
"builddir": true,
"config-opts": [
"--libdir=/app/lib",
"-Dtests=false",
"-Dbenchmarks=false"
],
"sources": [
{
"type": "git",
"url": "https://github.com/ebassi/graphene.git"
}
]
},
{
"name": "gtk",
"buildsystem": "meson",
"builddir": true,
"config-opts": [
"--libdir=/app/lib"
],
"sources": [
{
"type": "git",
"url": "https://gitlab.gnome.org/GNOME/gtk.git"
}
]
}
]
}

View File

@@ -1,73 +0,0 @@
{
"app-id": "org.gtk.WidgetFactory",
"runtime": "org.gnome.Platform",
"runtime-version": "master",
"sdk": "org.gnome.Sdk",
"command": "gtk4-widget-factory",
"tags": ["devel", "development", "nightly"],
"desktop-file-name-prefix": "(Development) ",
"finish-args": [
"--device=dri",
"--share=ipc",
"--socket=x11",
"--socket=wayland",
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*",
"--talk-name=ca.desrt.conf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf"
],
"cleanup": [
"/include",
"/lib/pkgconfig", "/share/pkgconfig",
"/share/aclocal",
"/man", "/share/man", "/share/gtk-doc",
"*.la", ".a",
"/lib/girepository-1.0",
"/share/gir-1.0",
"/share/doc"
],
"modules": [
{
"name" : "wayland",
"buildsystem" : "autotools",
"builddir" : true,
"config-opts" : [
"--disable-documentation"
],
"sources" : [
{
"type" : "git",
"url" : "https://github.com/wayland-project/wayland.git"
}
]
},
{
"name": "graphene",
"buildsystem": "meson",
"builddir": true,
"config-opts": [
"--libdir=/app/lib",
"-Dtests=false",
"-Dbenchmarks=false"
],
"sources": [
{
"type": "git",
"url": "https://github.com/ebassi/graphene.git"
}
]
},
{
"name": "gtk",
"buildsystem": "meson",
"builddir": true,
"config-opts": [
"--libdir=/app/lib"
],
"sources": [
{
"type": "git",
"url": "https://gitlab.gnome.org/GNOME/gtk.git"
}
]
}
]
}

View File

@@ -1,31 +0,0 @@
#!/usr/bin/env python3
import os
import sys
import subprocess
if 'DESTDIR' not in os.environ:
gtk_api_version = sys.argv[1]
gtk_abi_version = sys.argv[2]
gtk_libdir = sys.argv[3]
gtk_datadir = sys.argv[4]
gtk_moduledir = os.path.join(gtk_libdir, 'gtk-' + gtk_api_version, gtk_abi_version)
gtk_printmodule_dir = os.path.join(gtk_moduledir, 'printbackends')
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
print('Compiling GSettings schemas...')
subprocess.call(['glib-compile-schemas',
os.path.join(gtk_datadir, 'glib-2.0', 'schemas')])
print('Updating icon cache...')
subprocess.call(['gtk-update-icon-cache', '-q', '-t' ,'-f',
os.path.join(gtk_datadir, 'icons', 'hicolor')])
print('Updating module cache for print backends...')
os.makedirs(gtk_printmodule_dir, exist_ok=True)
subprocess.call(['gio-querymodules', gtk_printmodule_dir])
print('Updating module cache for input methods...')
os.makedirs(gtk_immodule_dir, exist_ok=True)
subprocess.call(['gio-querymodules', gtk_immodule_dir])

21
build-aux/meson/post-install.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/sh
gtk_api_version=$1
gtk_abi_version=$2
gtk_libdir=$3
gtk_datadir=$4
# Package managers set this so we don't need to run
if [ -z "$DESTDIR" ]; then
echo Compiling GSettings schemas...
glib-compile-schemas ${gtk_datadir}/glib-2.0/schemas
echo Updating desktop database...
update-desktop-database -q ${gtk_datadir}/applications
echo Updating icon cache...
gtk-update-icon-cache -q -t -f ${gtk_datadir}/icons/hicolor
echo Updating input method modules cache...
gtk4-query-immodules > ${gtk_libdir}/gtk-${gtk_api_version}/${gtk_abi_version}/immodules.cache
fi

View File

@@ -41,9 +41,6 @@
/* Define to 1 if you have the <dlfcn.h> header file. */ /* Define to 1 if you have the <dlfcn.h> header file. */
#mesondefine HAVE_DLFCN_H #mesondefine HAVE_DLFCN_H
/* Have the ffmpeg library */
#mesondefine HAVE_FFMPEG
/* Define to 1 if you have the <ftw.h> header file. */ /* Define to 1 if you have the <ftw.h> header file. */
#mesondefine HAVE_FTW_H #mesondefine HAVE_FTW_H
@@ -56,9 +53,6 @@
/* Define if gio-unix is available */ /* Define if gio-unix is available */
#mesondefine HAVE_GIO_UNIX #mesondefine HAVE_GIO_UNIX
/* Define if GStreamer support is available */
#mesondefine HAVE_GSTREAMER
/* Define to 1 if you have the `httpGetAuthString' function. */ /* Define to 1 if you have the `httpGetAuthString' function. */
#mesondefine HAVE_HTTPGETAUTHSTRING #mesondefine HAVE_HTTPGETAUTHSTRING
@@ -286,10 +280,6 @@
/* Define to 1 if linux/memfd.h exists */ /* Define to 1 if linux/memfd.h exists */
#mesondefine HAVE_LINUX_MEMFD_H #mesondefine HAVE_LINUX_MEMFD_H
#mesondefine HAVE_LINUX_INPUT_H
#mesondefine HAVE_DEV_EVDEV_INPUT_H
#mesondefine GTK_SYSCONFDIR #mesondefine GTK_SYSCONFDIR
#mesondefine GTK_LOCALEDIR #mesondefine GTK_LOCALEDIR
@@ -299,19 +289,3 @@
#mesondefine GTK_LIBDIR #mesondefine GTK_LIBDIR
#mesondefine GTK_PRINT_BACKENDS #mesondefine GTK_PRINT_BACKENDS
#mesondefine HAVE_HARFBUZZ
#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

View File

@@ -200,20 +200,20 @@ activate_about (GSimpleAction *action,
}; };
gtk_show_about_dialog (GTK_WINDOW (window), gtk_show_about_dialog (GTK_WINDOW (window),
"program-name", "GTK Code Demos", "program-name", "GTK+ Code Demos",
"version", g_strdup_printf ("%s,\nRunning against GTK %d.%d.%d", "version", g_strdup_printf ("%s,\nRunning against GTK+ %d.%d.%d",
PACKAGE_VERSION, PACKAGE_VERSION,
gtk_get_major_version (), gtk_get_major_version (),
gtk_get_minor_version (), gtk_get_minor_version (),
gtk_get_micro_version ()), gtk_get_micro_version ()),
"copyright", "(C) 1997-2013 The GTK Team", "copyright", "(C) 1997-2013 The GTK+ Team",
"license-type", GTK_LICENSE_LGPL_2_1, "license-type", GTK_LICENSE_LGPL_2_1,
"website", "http://www.gtk.org", "website", "http://www.gtk.org",
"comments", "Program to demonstrate GTK functions.", "comments", "Program to demonstrate GTK+ functions.",
"authors", authors, "authors", authors,
"documenters", documentors, "documenters", documentors,
"logo-icon-name", "org.gtk.Demo", "logo-icon-name", "gtk4-demo",
"title", "About GTK Code Demos", "title", "About GTK+ Code Demos",
NULL); NULL);
} }
@@ -455,49 +455,36 @@ demo_application_window_constructed (GObject *object)
} }
static void static void
demo_application_window_size_allocate (GtkWidget *widget, demo_application_window_size_allocate (GtkWidget *widget,
int width, const GtkAllocation *allocation,
int height, int baseline,
int baseline) GtkAllocation *out_clip)
{ {
DemoApplicationWindow *window = (DemoApplicationWindow *)widget; DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
GTK_WIDGET_CLASS (demo_application_window_parent_class)->size_allocate (widget, GTK_WIDGET_CLASS (demo_application_window_parent_class)->size_allocate (widget, allocation,
width, baseline, out_clip);
height,
baseline);
if (!window->maximized && !window->fullscreen) if (!window->maximized && !window->fullscreen)
gtk_window_get_size (GTK_WINDOW (window), &window->width, &window->height); gtk_window_get_size (GTK_WINDOW (window), &window->width, &window->height);
} }
static void static gboolean
surface_state_changed (GtkWidget *widget) demo_application_window_state_event (GtkWidget *widget,
GdkEventWindowState *event)
{ {
DemoApplicationWindow *window = (DemoApplicationWindow *)widget; DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
GdkSurfaceState new_state; gboolean res = GDK_EVENT_PROPAGATE;
GdkWindowState changed, new_state;
new_state = gdk_surface_get_state (gtk_widget_get_surface (widget)); if (GTK_WIDGET_CLASS (demo_application_window_parent_class)->window_state_event)
window->maximized = (new_state & GDK_SURFACE_STATE_MAXIMIZED) != 0; res = GTK_WIDGET_CLASS (demo_application_window_parent_class)->window_state_event (widget, event);
window->fullscreen = (new_state & GDK_SURFACE_STATE_FULLSCREEN) != 0;
}
static void gdk_event_get_window_state ((GdkEvent *)event, &changed, &new_state);
demo_application_window_realize (GtkWidget *widget) window->maximized = (new_state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
{ window->fullscreen = (new_state & GDK_WINDOW_STATE_FULLSCREEN) != 0;
GTK_WIDGET_CLASS (demo_application_window_parent_class)->realize (widget);
g_signal_connect_swapped (gtk_widget_get_surface (widget), "notify::state", return res;
G_CALLBACK (surface_state_changed), widget);
}
static void
demo_application_window_unrealize (GtkWidget *widget)
{
g_signal_handlers_disconnect_by_func (gtk_widget_get_surface (widget),
surface_state_changed, widget);
GTK_WIDGET_CLASS (demo_application_window_parent_class)->unrealize (widget);
} }
static void static void
@@ -519,8 +506,7 @@ demo_application_window_class_init (DemoApplicationWindowClass *class)
object_class->constructed = demo_application_window_constructed; object_class->constructed = demo_application_window_constructed;
widget_class->size_allocate = demo_application_window_size_allocate; widget_class->size_allocate = demo_application_window_size_allocate;
widget_class->realize = demo_application_window_realize; widget_class->window_state_event = demo_application_window_state_event;
widget_class->unrealize = demo_application_window_unrealize;
widget_class->destroy = demo_application_window_destroy; widget_class->destroy = demo_application_window_destroy;
gtk_widget_class_set_template_from_resource (widget_class, "/application_demo/application.ui"); gtk_widget_class_set_template_from_resource (widget_class, "/application_demo/application.ui");

View File

@@ -1,3 +1,4 @@
<?xml version="1.0"?>
<interface> <interface>
<template class="DemoApplicationWindow" parent="GtkApplicationWindow"> <template class="DemoApplicationWindow" parent="GtkApplicationWindow">
<property name="title" translatable="yes">Application Class</property> <property name="title" translatable="yes">Application Class</property>
@@ -6,28 +7,35 @@
<property name="icon-name">document-open</property> <property name="icon-name">document-open</property>
<child> <child>
<object class="GtkGrid"> <object class="GtkGrid">
<property name="visible">1</property>
<child> <child>
<object class="GtkToolbar"> <object class="GtkToolbar">
<property name="visible">1</property>
<property name="hexpand">1</property> <property name="hexpand">1</property>
<style> <style>
<class name="primary-toolbar"/> <class name="primary-toolbar"/>
</style> </style>
<child> <child>
<object class="GtkMenuToolButton" id="menutool"> <object class="GtkMenuToolButton" id="menutool">
<property name="visible">1</property>
<property name="icon-name">document-open</property> <property name="icon-name">document-open</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkToolButton"> <object class="GtkToolButton">
<property name="visible">1</property>
<property name="icon-name">application-exit</property> <property name="icon-name">application-exit</property>
<property name="action-name">app.quit</property> <property name="action-name">app.quit</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkSeparatorToolItem"/> <object class="GtkSeparatorToolItem">
<property name="visible">1</property>
</object>
</child> </child>
<child> <child>
<object class="GtkToolButton"> <object class="GtkToolButton">
<property name="visible">1</property>
<property name="icon-name">applications-other</property> <property name="icon-name">applications-other</property>
<property name="action-name">win.logo</property> <property name="action-name">win.logo</property>
</object> </object>
@@ -46,6 +54,7 @@
<object class="GtkBox" id="content_area"> <object class="GtkBox" id="content_area">
<child> <child>
<object class="GtkLabel" id="message"> <object class="GtkLabel" id="message">
<property name="visible">1</property>
<property name="hexpand">1</property> <property name="hexpand">1</property>
</object> </object>
</child> </child>
@@ -55,9 +64,10 @@
<object class="GtkBox"> <object class="GtkBox">
<child> <child>
<object class="GtkButton"> <object class="GtkButton">
<property name="visible">1</property>
<property name="valign">center</property> <property name="valign">center</property>
<property name="label" translatable="yes">_OK</property> <property name="label" translatable="yes">_OK</property>
<property name="use-underline">1</property> <property name="use_underline">1</property>
<signal name="clicked" handler="clicked_cb"/> <signal name="clicked" handler="clicked_cb"/>
</object> </object>
</child> </child>
@@ -71,9 +81,11 @@
</child> </child>
<child> <child>
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="visible">1</property>
<property name="shadow-type">in</property> <property name="shadow-type">in</property>
<child> <child>
<object class="GtkTextView"> <object class="GtkTextView">
<property name="visible">1</property>
<property name="hexpand">1</property> <property name="hexpand">1</property>
<property name="vexpand">1</property> <property name="vexpand">1</property>
<property name="buffer">buffer</property> <property name="buffer">buffer</property>
@@ -88,6 +100,7 @@
<child> <child>
<object class="GtkStatusbar" id="status"> <object class="GtkStatusbar" id="status">
<property name="hexpand">1</property> <property name="hexpand">1</property>
<property name="visible">1</property>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left-attach">0</property>

View File

@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<!-- interface-requires gtk+ 3.10 -->
<menu id="appmenu"> <menu id="appmenu">
<section> <section>
<item> <item>

View File

@@ -80,7 +80,7 @@ on_entry_changed (GtkWidget *widget, gpointer data)
page_number = gtk_assistant_get_current_page (assistant); page_number = gtk_assistant_get_current_page (assistant);
current_page = gtk_assistant_get_nth_page (assistant, page_number); current_page = gtk_assistant_get_nth_page (assistant, page_number);
text = gtk_editable_get_text (GTK_EDITABLE (widget)); text = gtk_entry_get_text (GTK_ENTRY (widget));
if (text && *text) if (text && *text)
gtk_assistant_set_page_complete (assistant, current_page, TRUE); gtk_assistant_set_page_complete (assistant, current_page, TRUE);
@@ -96,12 +96,12 @@ create_page1 (GtkWidget *assistant)
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
label = gtk_label_new ("You must fill out this entry to continue:"); label = gtk_label_new ("You must fill out this entry to continue:");
gtk_container_add (GTK_CONTAINER (box), label); gtk_box_pack_start (GTK_BOX (box), label);
entry = gtk_entry_new (); entry = gtk_entry_new ();
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE); gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
gtk_widget_set_valign (entry, GTK_ALIGN_CENTER); gtk_widget_set_valign (entry, GTK_ALIGN_CENTER);
gtk_container_add (GTK_CONTAINER (box), entry); gtk_box_pack_start (GTK_BOX (box), entry);
g_signal_connect (G_OBJECT (entry), "changed", g_signal_connect (G_OBJECT (entry), "changed",
G_CALLBACK (on_entry_changed), assistant); G_CALLBACK (on_entry_changed), assistant);
@@ -119,7 +119,7 @@ create_page2 (GtkWidget *assistant)
checkbutton = gtk_check_button_new_with_label ("This is optional data, you may continue " checkbutton = gtk_check_button_new_with_label ("This is optional data, you may continue "
"even if you do not check this"); "even if you do not check this");
gtk_container_add (GTK_CONTAINER (box), checkbutton); gtk_box_pack_start (GTK_BOX (box), checkbutton);
gtk_assistant_append_page (GTK_ASSISTANT (assistant), box); gtk_assistant_append_page (GTK_ASSISTANT (assistant), box);
gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), box, TRUE); gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), box, TRUE);

View File

@@ -1,16 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk+" version="3.20"/> <requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="window"> <object class="GtkWindow" id="window">
<property name="resizable">0</property> <property name="can_focus">False</property>
<property name="resizable">False</property>
<property name="title">CSS Blend Modes</property> <property name="title">CSS Blend Modes</property>
<property name="default-width">400</property> <property name="default_width">400</property>
<property name="default-height">300</property> <property name="default_height">300</property>
<child> <child>
<object class="GtkGrid"> <object class="GtkGrid">
<property name="row-spacing">12</property> <property name="visible">True</property>
<property name="column-spacing">12</property> <property name="can_focus">False</property>
<property name="row_spacing">12</property>
<property name="column_spacing">12</property>
<child> <child>
<object class="GtkLabel"> <object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Blend mode:</property> <property name="label" translatable="yes">Blend mode:</property>
<property name="xalign">0</property> <property name="xalign">0</property>
<style> <style>
@@ -18,319 +24,368 @@
</style> </style>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left_attach">0</property>
<property name="top-attach">0</property> <property name="top_attach">0</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkScrolledWindow" id="scrolledwindow"> <object class="GtkScrolledWindow" id="scrolledwindow">
<property name="can-focus">1</property> <property name="visible">True</property>
<property name="vexpand">1</property> <property name="can_focus">True</property>
<property name="shadow-type">in</property> <property name="vexpand">True</property>
<property name="min-content-width">150</property> <property name="shadow_type">in</property>
<property name="min_content_width">150</property>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left_attach">0</property>
<property name="top-attach">1</property> <property name="top_attach">1</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkStackSwitcher"> <object class="GtkStackSwitcher">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property> <property name="halign">center</property>
<property name="hexpand">1</property> <property name="hexpand">True</property>
<property name="stack">stack</property> <property name="stack">stack</property>
</object> </object>
<packing> <packing>
<property name="left-attach">1</property> <property name="left_attach">1</property>
<property name="top-attach">0</property> <property name="top_attach">0</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkStack" id="stack"> <object class="GtkStack" id="stack">
<property name="hexpand">1</property> <property name="visible">True</property>
<property name="vexpand">1</property> <property name="can_focus">False</property>
<property name="hhomogeneous">0</property> <property name="hexpand">True</property>
<property name="vhomogeneous">0</property> <property name="vexpand">True</property>
<property name="transition-type">crossfade</property> <property name="hhomogeneous">False</property>
<property name="vhomogeneous">False</property>
<property name="transition_type">crossfade</property>
<child> <child>
<object class="GtkStackPage"> <object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="hexpand">False</property>
<property name="vexpand">True</property>
<property name="row_spacing">12</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Duck</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Background</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="duck"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="gradient"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">
Blended picture</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<style>
<class name="blend0"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">2</property>
</packing>
</child>
</object>
<packing>
<property name="name">page0</property> <property name="name">page0</property>
<property name="title" translatable="yes">Ducky</property> <property name="title" translatable="yes">Ducky</property>
<property name="child"> </packing>
<object class="GtkGrid">
<property name="halign">center</property>
<property name="valign">center</property>
<property name="vexpand">1</property>
<property name="row-spacing">12</property>
<property name="column-spacing">12</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Duck</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Background</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkImage">
<style>
<class name="duck"/>
</style>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkImage">
<style>
<class name="gradient"/>
</style>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">
Blended picture</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkImage">
<property name="halign">center</property>
<style>
<class name="blend0"/>
</style>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
<property name="width">2</property>
</packing>
</child>
</object>
</property>
</object>
</child> </child>
<child> <child>
<object class="GtkStackPage"> <object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="hexpand">False</property>
<property name="vexpand">True</property>
<property name="row_spacing">12</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Red</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Blue</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="red"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="blue"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">
Blended picture</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<style>
<class name="blend1"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">2</property>
</packing>
</child>
</object>
<packing>
<property name="name">page1</property> <property name="name">page1</property>
<property name="title" translatable="yes">Blends</property> <property name="title" translatable="yes">Blends</property>
<property name="child"> </packing>
<object class="GtkGrid">
<property name="halign">center</property>
<property name="valign">center</property>
<property name="vexpand">1</property>
<property name="row-spacing">12</property>
<property name="column-spacing">12</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Red</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Blue</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkImage">
<style>
<class name="red"/>
</style>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkImage">
<style>
<class name="blue"/>
</style>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">
Blended picture</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkImage">
<property name="halign">center</property>
<style>
<class name="blend1"/>
</style>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
<property name="width">2</property>
</packing>
</child>
</object>
</property>
</object>
</child> </child>
<child> <child>
<object class="GtkStackPage"> <object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="cyan"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="magenta"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="yellow"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<style>
<class name="blend2"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Cyan</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Magenta</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Yellow</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Blended picture</property>
<property name="xalign">0</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
</object>
<packing>
<property name="name">page2</property> <property name="name">page2</property>
<property name="title" translatable="yes">CMYK</property> <property name="title" translatable="yes">CMYK</property>
<property name="child"> </packing>
<object class="GtkGrid">
<property name="halign">center</property>
<property name="valign">center</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="row-spacing">6</property>
<property name="column-spacing">12</property>
<child>
<object class="GtkImage">
<style>
<class name="cyan"/>
</style>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkImage">
<style>
<class name="magenta"/>
</style>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkImage">
<style>
<class name="yellow"/>
</style>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkImage">
<property name="halign">center</property>
<style>
<class name="blend2"/>
</style>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Cyan</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Magenta</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Yellow</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Blended picture</property>
<property name="xalign">0</property>
<attributes>
<attribute name="weight" value="bold"></attribute>
</attributes>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
</packing>
</child>
</object>
</property>
</object>
</child> </child>
</object> </object>
<packing> <packing>
<property name="left-attach">1</property> <property name="left_attach">1</property>
<property name="top-attach">1</property> <property name="top_attach">1</property>
</packing> </packing>
</child> </child>
</object> </object>
</child> </child>
<child type="titlebar"/> <child type="titlebar">
<placeholder/>
</child>
</object> </object>
</interface> </interface>

View File

@@ -1,482 +0,0 @@
/*
* bluroverlay.c
* This file is part of gtk
*
* Copyright (C) 2011 - Ignacio Casal Quinteiro, Mike Krüger
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "bluroverlay.h"
/*
* This is a cut-down copy of gtkoverlay.c with a custom snapshot
* function that support a limited form of blur-under.
*/
typedef struct _BlurOverlayChild BlurOverlayChild;
struct _BlurOverlayChild
{
double blur;
};
enum {
GET_CHILD_POSITION,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
static GQuark child_data_quark = 0;
G_DEFINE_TYPE (BlurOverlay, blur_overlay, GTK_TYPE_BIN)
static void
blur_overlay_set_overlay_child (GtkWidget *widget,
BlurOverlayChild *child_data)
{
g_object_set_qdata_full (G_OBJECT (widget), child_data_quark, child_data, g_free);
}
static BlurOverlayChild *
blur_overlay_get_overlay_child (GtkWidget *widget)
{
return (BlurOverlayChild *) g_object_get_qdata (G_OBJECT (widget), child_data_quark);
}
static void
blur_overlay_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkWidget *child;
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
{
int child_min, child_nat, child_min_baseline, child_nat_baseline;
gtk_widget_measure (child,
orientation,
for_size,
&child_min, &child_nat,
&child_min_baseline, &child_nat_baseline);
*minimum = MAX (*minimum, child_min);
*natural = MAX (*natural, child_nat);
if (child_min_baseline > -1)
*minimum_baseline = MAX (*minimum_baseline, child_min_baseline);
if (child_nat_baseline > -1)
*natural_baseline = MAX (*natural_baseline, child_nat_baseline);
}
}
static void
blur_overlay_compute_child_allocation (BlurOverlay *overlay,
GtkWidget *widget,
BlurOverlayChild *child,
GtkAllocation *widget_allocation)
{
GtkAllocation allocation;
gboolean result;
g_signal_emit (overlay, signals[GET_CHILD_POSITION],
0, widget, &allocation, &result);
widget_allocation->x = allocation.x;
widget_allocation->y = allocation.y;
widget_allocation->width = allocation.width;
widget_allocation->height = allocation.height;
}
static GtkAlign
effective_align (GtkAlign align,
GtkTextDirection direction)
{
switch (align)
{
case GTK_ALIGN_START:
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_END : GTK_ALIGN_START;
case GTK_ALIGN_END:
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_START : GTK_ALIGN_END;
case GTK_ALIGN_FILL:
case GTK_ALIGN_CENTER:
case GTK_ALIGN_BASELINE:
default:
return align;
}
}
static void
blur_overlay_child_update_style_classes (BlurOverlay *overlay,
GtkWidget *child,
GtkAllocation *child_allocation)
{
int width, height;
GtkAlign valign, halign;
gboolean is_left, is_right, is_top, is_bottom;
gboolean has_left, has_right, has_top, has_bottom;
GtkStyleContext *context;
context = gtk_widget_get_style_context (child);
has_left = gtk_style_context_has_class (context, GTK_STYLE_CLASS_LEFT);
has_right = gtk_style_context_has_class (context, GTK_STYLE_CLASS_RIGHT);
has_top = gtk_style_context_has_class (context, GTK_STYLE_CLASS_TOP);
has_bottom = gtk_style_context_has_class (context, GTK_STYLE_CLASS_BOTTOM);
is_left = is_right = is_top = is_bottom = FALSE;
width = gtk_widget_get_width (GTK_WIDGET (overlay));
height = gtk_widget_get_height (GTK_WIDGET (overlay));
halign = effective_align (gtk_widget_get_halign (child),
gtk_widget_get_direction (child));
if (halign == GTK_ALIGN_START)
is_left = (child_allocation->x == 0);
else if (halign == GTK_ALIGN_END)
is_right = (child_allocation->x + child_allocation->width == width);
valign = gtk_widget_get_valign (child);
if (valign == GTK_ALIGN_START)
is_top = (child_allocation->y == 0);
else if (valign == GTK_ALIGN_END)
is_bottom = (child_allocation->y + child_allocation->height == height);
if (has_left && !is_left)
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_LEFT);
else if (!has_left && is_left)
gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT);
if (has_right && !is_right)
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_RIGHT);
else if (!has_right && is_right)
gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT);
if (has_top && !is_top)
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_TOP);
else if (!has_top && is_top)
gtk_style_context_add_class (context, GTK_STYLE_CLASS_TOP);
if (has_bottom && !is_bottom)
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_BOTTOM);
else if (!has_bottom && is_bottom)
gtk_style_context_add_class (context, GTK_STYLE_CLASS_BOTTOM);
}
static void
blur_overlay_child_allocate (BlurOverlay *overlay,
GtkWidget *widget,
BlurOverlayChild *child)
{
GtkAllocation child_allocation;
if (!gtk_widget_get_visible (widget))
return;
blur_overlay_compute_child_allocation (overlay, widget, child, &child_allocation);
blur_overlay_child_update_style_classes (overlay, widget, &child_allocation);
gtk_widget_size_allocate (widget, &child_allocation, -1);
}
static void
blur_overlay_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
BlurOverlay *overlay = BLUR_OVERLAY (widget);
GtkWidget *child;
GtkWidget *main_widget;
main_widget = gtk_bin_get_child (GTK_BIN (overlay));
if (main_widget && gtk_widget_get_visible (main_widget))
gtk_widget_size_allocate (main_widget,
&(GtkAllocation) {
0, 0,
width, height
}, -1);
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
{
if (child != main_widget)
{
BlurOverlayChild *child_data = blur_overlay_get_overlay_child (child);
blur_overlay_child_allocate (overlay, child, child_data);
}
}
}
static gboolean
blur_overlay_get_child_position (BlurOverlay *overlay,
GtkWidget *widget,
GtkAllocation *alloc)
{
GtkRequisition min, req;
GtkAlign halign;
GtkTextDirection direction;
int width, height;
gtk_widget_get_preferred_size (widget, &min, &req);
width = gtk_widget_get_width (GTK_WIDGET (overlay));
height = gtk_widget_get_height (GTK_WIDGET (overlay));
alloc->x = 0;
alloc->width = MAX (min.width, MIN (width, req.width));
direction = gtk_widget_get_direction (widget);
halign = gtk_widget_get_halign (widget);
switch (effective_align (halign, direction))
{
case GTK_ALIGN_START:
/* nothing to do */
break;
case GTK_ALIGN_FILL:
alloc->width = MAX (alloc->width, width);
break;
case GTK_ALIGN_CENTER:
alloc->x += width / 2 - alloc->width / 2;
break;
case GTK_ALIGN_END:
alloc->x += width - alloc->width;
break;
case GTK_ALIGN_BASELINE:
default:
g_assert_not_reached ();
break;
}
alloc->y = 0;
alloc->height = MAX (min.height, MIN (height, req.height));
switch (gtk_widget_get_valign (widget))
{
case GTK_ALIGN_START:
/* nothing to do */
break;
case GTK_ALIGN_FILL:
alloc->height = MAX (alloc->height, height);
break;
case GTK_ALIGN_CENTER:
alloc->y += height / 2 - alloc->height / 2;
break;
case GTK_ALIGN_END:
alloc->y += height - alloc->height;
break;
case GTK_ALIGN_BASELINE:
default:
g_assert_not_reached ();
break;
}
return TRUE;
}
static void
blur_overlay_add (GtkContainer *container,
GtkWidget *widget)
{
BlurOverlay *overlay = BLUR_OVERLAY (container);
gtk_widget_insert_after (widget, GTK_WIDGET (container), NULL);
overlay->main_widget = widget;
}
static void
blur_overlay_remove (GtkContainer *container,
GtkWidget *widget)
{
BlurOverlay *overlay = BLUR_OVERLAY (container);
gtk_widget_unparent (widget);
if (overlay->main_widget == widget)
overlay->main_widget = NULL;
}
static void
blur_overlay_forall (GtkContainer *overlay,
GtkCallback callback,
gpointer callback_data)
{
GtkWidget *child;
child = gtk_widget_get_first_child (GTK_WIDGET (overlay));
while (child != NULL)
{
GtkWidget *next = gtk_widget_get_next_sibling (child);
(* callback) (child, callback_data);
child = next;
}
}
static void
blur_overlay_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkWidget *main_widget;
GskRenderNode *main_widget_node = NULL;
GtkWidget *child;
GtkAllocation main_alloc;
cairo_region_t *clip = NULL;
int i;
main_widget = BLUR_OVERLAY (widget)->main_widget;
gtk_widget_get_allocation (widget, &main_alloc);
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
{
BlurOverlayChild *child_info = blur_overlay_get_overlay_child (child);
double blur = 0;
if (child_info)
blur = child_info->blur;
if (blur > 0)
{
GtkAllocation alloc;
graphene_rect_t bounds;
if (main_widget_node == NULL)
{
GtkSnapshot *child_snapshot;
child_snapshot = gtk_snapshot_new ();
gtk_widget_snapshot_child (widget, main_widget, child_snapshot);
main_widget_node = gtk_snapshot_free_to_node (child_snapshot);
}
gtk_widget_get_allocation (child, &alloc);
graphene_rect_init (&bounds, alloc.x, alloc.y, alloc.width, alloc.height);
gtk_snapshot_push_blur (snapshot, blur);
gtk_snapshot_push_clip (snapshot, &bounds);
gtk_snapshot_append_node (snapshot, main_widget_node);
gtk_snapshot_pop (snapshot);
gtk_snapshot_pop (snapshot);
if (clip == NULL)
{
cairo_rectangle_int_t rect;
rect.x = rect.y = 0;
rect.width = main_alloc.width;
rect.height = main_alloc.height;
clip = cairo_region_create_rectangle (&rect);
}
cairo_region_subtract_rectangle (clip, (cairo_rectangle_int_t *)&alloc);
}
}
if (clip == NULL)
{
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
{
gtk_widget_snapshot_child (widget, child, snapshot);
}
return;
}
for (i = 0; i < cairo_region_num_rectangles (clip); i++)
{
cairo_rectangle_int_t rect;
graphene_rect_t bounds;
cairo_region_get_rectangle (clip, i, &rect);
graphene_rect_init (&bounds, rect.x, rect.y, rect.width, rect.height);
gtk_snapshot_push_clip (snapshot, &bounds);
gtk_snapshot_append_node (snapshot, main_widget_node);
gtk_snapshot_pop (snapshot);
}
cairo_region_destroy (clip);
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
{
if (child != main_widget)
gtk_widget_snapshot_child (widget, child, snapshot);
}
gsk_render_node_unref (main_widget_node);
}
static void
blur_overlay_class_init (BlurOverlayClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
widget_class->measure = blur_overlay_measure;
widget_class->size_allocate = blur_overlay_size_allocate;
widget_class->snapshot = blur_overlay_snapshot;
container_class->add = blur_overlay_add;
container_class->remove = blur_overlay_remove;
container_class->forall = blur_overlay_forall;
klass->get_child_position = blur_overlay_get_child_position;
signals[GET_CHILD_POSITION] =
g_signal_new ("get-child-position",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (BlurOverlayClass, get_child_position),
g_signal_accumulator_true_handled, NULL,
NULL,
G_TYPE_BOOLEAN, 2,
GTK_TYPE_WIDGET,
GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
child_data_quark = g_quark_from_static_string ("gtk-overlay-child-data");
gtk_widget_class_set_css_name (widget_class, "overlay");
}
static void
blur_overlay_init (BlurOverlay *overlay)
{
gtk_widget_set_has_surface (GTK_WIDGET (overlay), FALSE);
}
GtkWidget *
blur_overlay_new (void)
{
return g_object_new (BLUR_TYPE_OVERLAY, NULL);
}
void
blur_overlay_add_overlay (BlurOverlay *overlay,
GtkWidget *widget,
double blur)
{
BlurOverlayChild *child = g_new0 (BlurOverlayChild, 1);
gtk_widget_insert_before (widget, GTK_WIDGET (overlay), NULL);
child->blur = blur;
blur_overlay_set_overlay_child (widget, child);
}

View File

@@ -1,65 +0,0 @@
/*
* bluroverlay.h
* This file is part of gtk
*
* Copyright (C) 2011 - Ignacio Casal Quinteiro, Mike Krüger
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __BLUR_OVERLAY_H__
#define __BLUR_OVERLAY_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define BLUR_TYPE_OVERLAY (blur_overlay_get_type ())
#define BLUR_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BLUR_TYPE_OVERLAY, BlurOverlay))
#define BLUR_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BLUR_TYPE_OVERLAY, BlurOverlayClass))
#define BLUR_IS_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BLUR_TYPE_OVERLAY))
#define BLUR_IS_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BLUR_TYPE_OVERLAY))
#define BLUR_OVERLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BLUR_TYPE_OVERLAY, BlurOverlayClass))
typedef struct _BlurOverlay BlurOverlay;
typedef struct _BlurOverlayClass BlurOverlayClass;
struct _BlurOverlay
{
GtkBin parent_instance;
GtkWidget *main_widget;
};
struct _BlurOverlayClass
{
GtkBinClass parent_class;
gboolean (*get_child_position) (BlurOverlay *overlay,
GtkWidget *widget,
GtkAllocation *allocation);
};
GDK_AVAILABLE_IN_ALL
GType blur_overlay_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkWidget *blur_overlay_new (void);
GDK_AVAILABLE_IN_ALL
void blur_overlay_add_overlay (BlurOverlay *overlay,
GtkWidget *widget,
double blur);
G_END_DECLS
#endif /* __BLUR_OVERLAY_H__ */

127
demos/gtk-demo/button_box.c Normal file
View 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;
}

View File

@@ -7,7 +7,7 @@
* computers, as long as there is a network connection to the * computers, as long as there is a network connection to the
* computer where the application is running. * 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 * concept of multiple displays. (The X Window System is the
* main example.) Other windowing systems can only handle one * main example.) Other windowing systems can only handle one
* keyboard and mouse, and combine all monitors into * keyboard and mouse, and combine all monitors into
@@ -68,25 +68,32 @@ enum
static GtkWidget * static GtkWidget *
find_toplevel_at_pointer (GdkDisplay *display) find_toplevel_at_pointer (GdkDisplay *display)
{ {
GdkSurface *pointer_window; GdkWindow *pointer_window;
GtkWidget *widget = NULL; GtkWidget *widget = NULL;
pointer_window = gdk_device_get_surface_at_position (gtk_get_current_event_device (), NULL, NULL); pointer_window = gdk_device_get_window_at_position (gtk_get_current_event_device (),
NULL, NULL);
/* The user data field of a GdkWindow is used to store a pointer
* to the widget that created it.
*/
if (pointer_window) if (pointer_window)
widget = GTK_WIDGET (gtk_root_get_for_surface (pointer_window)); {
gpointer widget_ptr;
gdk_window_get_user_data (pointer_window, &widget_ptr);
widget = widget_ptr;
}
return widget; return widget ? gtk_widget_get_toplevel (widget) : NULL;
} }
static void static gboolean
released_cb (GtkGestureMultiPress *gesture, button_release_event_cb (GtkWidget *widget,
guint n_press, GdkEventButton *event,
gdouble x, gboolean *clicked)
gdouble y,
gboolean *clicked)
{ {
*clicked = TRUE; *clicked = TRUE;
return TRUE;
} }
/* Asks the user to click on a window, then waits for them click /* Asks the user to click on a window, then waits for them click
@@ -120,26 +127,22 @@ query_for_toplevel (GdkDisplay *display,
device = gtk_get_current_event_device (); device = gtk_get_current_event_device ();
if (gdk_seat_grab (gdk_device_get_seat (device), if (gdk_seat_grab (gdk_device_get_seat (device),
gtk_widget_get_surface (popup), gtk_widget_get_window (popup),
GDK_SEAT_CAPABILITY_ALL_POINTING, GDK_SEAT_CAPABILITY_ALL_POINTING,
FALSE, cursor, NULL, NULL, NULL) == GDK_GRAB_SUCCESS) FALSE, cursor, NULL, NULL, NULL) == GDK_GRAB_SUCCESS)
{ {
GtkGesture *gesture = gtk_gesture_multi_press_new ();
gboolean clicked = FALSE; gboolean clicked = FALSE;
g_signal_connect (gesture, "released", g_signal_connect (popup, "button-release-event",
G_CALLBACK (released_cb), &clicked); G_CALLBACK (button_release_event_cb), &clicked);
gtk_widget_add_controller (popup, GTK_EVENT_CONTROLLER (gesture));
/* Process events until clicked is set by our button release event handler. /* Process events until clicked is set by button_release_event_cb.
* We pass in may_block=TRUE since we want to wait if there * We pass in may_block=TRUE since we want to wait if there
* are no events currently. * are no events currently.
*/ */
while (!clicked) while (!clicked)
g_main_context_iteration (NULL, TRUE); g_main_context_iteration (NULL, TRUE);
gdk_seat_ungrab (gdk_device_get_seat (device));
toplevel = find_toplevel_at_pointer (display); toplevel = find_toplevel_at_pointer (display);
if (toplevel == popup) if (toplevel == popup)
toplevel = NULL; toplevel = NULL;
@@ -307,7 +310,7 @@ create_frame (ChangeDisplayInfo *info,
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin),
GTK_SHADOW_IN); GTK_SHADOW_IN);
gtk_container_add (GTK_CONTAINER (hbox), scrollwin); gtk_box_pack_start (GTK_BOX (hbox), scrollwin);
*tree_view = gtk_tree_view_new (); *tree_view = gtk_tree_view_new ();
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (*tree_view), FALSE); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (*tree_view), FALSE);
@@ -317,7 +320,7 @@ create_frame (ChangeDisplayInfo *info,
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
*button_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5); *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) if (!info->size_group)
info->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); info->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
@@ -357,11 +360,11 @@ create_display_frame (ChangeDisplayInfo *info)
button = left_align_button_new ("_Open..."); button = left_align_button_new ("_Open...");
g_signal_connect (button, "clicked", G_CALLBACK (open_display_cb), info); 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"); button = left_align_button_new ("_Close");
g_signal_connect (button, "clicked", G_CALLBACK (close_display_cb), info); 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, info->display_model = (GtkTreeModel *)gtk_list_store_new (DISPLAY_NUM_COLUMNS,
G_TYPE_STRING, G_TYPE_STRING,
@@ -534,10 +537,10 @@ do_changedisplay (GtkWidget *do_widget)
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
g_object_set (vbox, "margin", 8, NULL); 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); frame = create_display_frame (info);
gtk_container_add (GTK_CONTAINER (vbox), frame); gtk_box_pack_start (GTK_BOX (vbox), frame);
initialize_displays (info); initialize_displays (info);

View File

@@ -28,7 +28,7 @@ copy_button_clicked (GtkWidget *button,
clipboard = gtk_widget_get_clipboard (entry); clipboard = gtk_widget_get_clipboard (entry);
/* Set clipboard text */ /* Set clipboard text */
gdk_clipboard_set_text (clipboard, gtk_editable_get_text (GTK_EDITABLE (entry))); gdk_clipboard_set_text (clipboard, gtk_entry_get_text (GTK_ENTRY (entry)));
} }
void void
@@ -50,7 +50,7 @@ paste_received (GObject *source_object,
if (text) if (text)
{ {
/* Set the entry text */ /* Set the entry text */
gtk_editable_set_text (GTK_EDITABLE (entry), text); gtk_entry_set_text (GTK_ENTRY (entry), text);
g_free (text); g_free (text);
} }
else else
@@ -93,8 +93,8 @@ paste_button_clicked (GtkWidget *button,
gdk_clipboard_read_text_async (clipboard, NULL, paste_received, entry); gdk_clipboard_read_text_async (clipboard, NULL, paste_received, entry);
} }
static GdkPaintable * static GdkTexture *
get_image_paintable (GtkImage *image) get_image_texture (GtkImage *image)
{ {
const gchar *icon_name; const gchar *icon_name;
GtkIconTheme *icon_theme; GtkIconTheme *icon_theme;
@@ -102,15 +102,15 @@ get_image_paintable (GtkImage *image)
switch (gtk_image_get_storage_type (image)) switch (gtk_image_get_storage_type (image))
{ {
case GTK_IMAGE_PAINTABLE: case GTK_IMAGE_TEXTURE:
return g_object_ref (gtk_image_get_paintable (image)); return g_object_ref (gtk_image_get_texture (image));
case GTK_IMAGE_ICON_NAME: case GTK_IMAGE_ICON_NAME:
icon_name = gtk_image_get_icon_name (image); icon_name = gtk_image_get_icon_name (image);
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image))); icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image)));
icon_info = gtk_icon_theme_lookup_icon (icon_theme, icon_name, 48, GTK_ICON_LOOKUP_GENERIC_FALLBACK); icon_info = gtk_icon_theme_lookup_icon (icon_theme, icon_name, 48, GTK_ICON_LOOKUP_GENERIC_FALLBACK);
if (icon_info == NULL) if (icon_info == NULL)
return NULL; return NULL;
return GDK_PAINTABLE (gtk_icon_info_load_texture (icon_info)); return gtk_icon_info_load_texture (icon_info);
default: default:
g_warning ("Image storage type %d not handled", g_warning ("Image storage type %d not handled",
gtk_image_get_storage_type (image)); gtk_image_get_storage_type (image));
@@ -120,37 +120,36 @@ get_image_paintable (GtkImage *image)
static void static void
drag_begin (GtkWidget *widget, drag_begin (GtkWidget *widget,
GdkDrag *drag, GdkDragContext *context,
gpointer data) gpointer data)
{ {
GdkPaintable *paintable; GdkTexture *texture;
paintable = get_image_paintable (GTK_IMAGE (widget)); texture = get_image_texture (GTK_IMAGE (widget));
if (paintable) if (texture)
{ gtk_drag_set_icon_texture (context, texture, -2, -2);
gtk_drag_set_icon_paintable (drag, paintable, -2, -2);
g_object_unref (paintable);
}
} }
void void
drag_data_get (GtkWidget *widget, drag_data_get (GtkWidget *widget,
GdkDrag *drag, GdkDragContext *context,
GtkSelectionData *selection_data, GtkSelectionData *selection_data,
guint info, guint info,
guint time,
gpointer data) gpointer data)
{ {
GdkPaintable *paintable; GdkTexture *texture;
paintable = get_image_paintable (GTK_IMAGE (widget)); texture = get_image_texture (GTK_IMAGE (widget));
if (GDK_IS_TEXTURE (paintable)) if (texture)
gtk_selection_data_set_texture (selection_data, GDK_TEXTURE (paintable)); gtk_selection_data_set_texture (selection_data, texture);
} }
static void static void
drag_data_received (GtkWidget *widget, drag_data_received (GtkWidget *widget,
GdkDrop *drop, GdkDragContext *context,
GtkSelectionData *selection_data, GtkSelectionData *selection_data,
guint32 time,
gpointer data) gpointer data)
{ {
if (gtk_selection_data_get_length (selection_data) > 0) if (gtk_selection_data_get_length (selection_data) > 0)
@@ -158,7 +157,7 @@ drag_data_received (GtkWidget *widget,
GdkTexture *texture; GdkTexture *texture;
texture = gtk_selection_data_get_texture (selection_data); texture = gtk_selection_data_get_texture (selection_data);
gtk_image_set_from_paintable (GTK_IMAGE (data), GDK_PAINTABLE (texture)); gtk_image_set_from_texture (GTK_IMAGE (data), texture);
g_object_unref (texture); g_object_unref (texture);
} }
} }
@@ -168,16 +167,16 @@ copy_image (GtkMenuItem *item,
gpointer data) gpointer data)
{ {
GdkClipboard *clipboard; GdkClipboard *clipboard;
GdkPaintable *paintable; GdkTexture *texture;
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data)); clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
paintable = get_image_paintable (GTK_IMAGE (data)); texture = get_image_texture (GTK_IMAGE (data));
if (GDK_IS_TEXTURE (paintable)) if (texture)
gdk_clipboard_set_texture (clipboard, GDK_TEXTURE (paintable)); {
gdk_clipboard_set_texture (clipboard, texture);
if (paintable) g_object_unref (texture);
g_object_unref (paintable); }
} }
static void static void
@@ -191,7 +190,7 @@ paste_image_received (GObject *source,
if (texture == NULL) if (texture == NULL)
return; return;
gtk_image_set_from_paintable (GTK_IMAGE (data), GDK_PAINTABLE (texture)); gtk_image_set_from_texture (GTK_IMAGE (data), texture);
g_object_unref (texture); g_object_unref (texture);
} }
@@ -208,29 +207,34 @@ paste_image (GtkMenuItem *item,
data); data);
} }
static void static gboolean
pressed_cb (GtkGesture *gesture, button_press (GtkWidget *widget,
int n_press, GdkEventButton *event,
double x, gpointer data)
double y,
GtkWidget *image)
{ {
GtkWidget *menu; GtkWidget *menu;
GtkWidget *item; GtkWidget *item;
guint button;
gdk_event_get_button ((GdkEvent *)event, &button);
if (button != GDK_BUTTON_SECONDARY)
return FALSE;
menu = gtk_menu_new (); menu = gtk_menu_new ();
item = gtk_menu_item_new_with_mnemonic (_("_Copy")); item = gtk_menu_item_new_with_mnemonic (_("_Copy"));
g_signal_connect (item, "activate", G_CALLBACK (copy_image), image); g_signal_connect (item, "activate", G_CALLBACK (copy_image), data);
gtk_widget_show (item); gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = gtk_menu_item_new_with_mnemonic (_("_Paste")); item = gtk_menu_item_new_with_mnemonic (_("_Paste"));
g_signal_connect (item, "activate", G_CALLBACK (paste_image), image); g_signal_connect (item, "activate", G_CALLBACK (paste_image), data);
gtk_widget_show (item); gtk_widget_show (item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL); gtk_menu_popup_at_pointer (GTK_MENU (menu), (GdkEvent *) event);
return TRUE;
} }
GtkWidget * GtkWidget *
@@ -242,7 +246,6 @@ do_clipboard (GtkWidget *do_widget)
GtkWidget *label; GtkWidget *label;
GtkWidget *entry, *button; GtkWidget *entry, *button;
GtkWidget *image; GtkWidget *image;
GtkGesture *gesture;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL); window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_display (GTK_WINDOW (window), gtk_window_set_display (GTK_WINDOW (window),
@@ -259,45 +262,45 @@ do_clipboard (GtkWidget *do_widget)
label = gtk_label_new ("\"Copy\" will copy the text\nin the entry to the clipboard"); label = gtk_label_new ("\"Copy\" will copy the text\nin the entry to the clipboard");
gtk_container_add (GTK_CONTAINER (vbox), label); gtk_box_pack_start (GTK_BOX (vbox), label);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
g_object_set (hbox, "margin", 8, NULL); 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 */ /* Create the first entry */
entry = gtk_entry_new (); entry = gtk_entry_new ();
gtk_container_add (GTK_CONTAINER (hbox), entry); gtk_box_pack_start (GTK_BOX (hbox), entry);
/* Create the button */ /* Create the button */
button = gtk_button_new_with_mnemonic (_("_Copy")); button = gtk_button_new_with_mnemonic (_("_Copy"));
gtk_container_add (GTK_CONTAINER (hbox), button); gtk_box_pack_start (GTK_BOX (hbox), button);
g_signal_connect (button, "clicked", g_signal_connect (button, "clicked",
G_CALLBACK (copy_button_clicked), entry); G_CALLBACK (copy_button_clicked), entry);
label = gtk_label_new ("\"Paste\" will paste the text from the clipboard to the entry"); label = gtk_label_new ("\"Paste\" will paste the text from the clipboard to the entry");
gtk_container_add (GTK_CONTAINER (vbox), label); gtk_box_pack_start (GTK_BOX (vbox), label);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
g_object_set (hbox, "margin", 8, NULL); 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 */ /* Create the second entry */
entry = gtk_entry_new (); entry = gtk_entry_new ();
gtk_container_add (GTK_CONTAINER (hbox), entry); gtk_box_pack_start (GTK_BOX (hbox), entry);
/* Create the button */ /* Create the button */
button = gtk_button_new_with_mnemonic (_("_Paste")); button = gtk_button_new_with_mnemonic (_("_Paste"));
gtk_container_add (GTK_CONTAINER (hbox), button); gtk_box_pack_start (GTK_BOX (hbox), button);
g_signal_connect (button, "clicked", g_signal_connect (button, "clicked",
G_CALLBACK (paste_button_clicked), entry); G_CALLBACK (paste_button_clicked), entry);
label = gtk_label_new ("Images can be transferred via the clipboard, too"); label = gtk_label_new ("Images can be transferred via the clipboard, too");
gtk_container_add (GTK_CONTAINER (vbox), label); gtk_box_pack_start (GTK_BOX (vbox), label);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
g_object_set (hbox, "margin", 8, NULL); 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 */ /* Create the first image */
image = gtk_image_new_from_icon_name ("dialog-warning"); image = gtk_image_new_from_icon_name ("dialog-warning");
@@ -319,10 +322,8 @@ do_clipboard (GtkWidget *do_widget)
G_CALLBACK (drag_data_received), image); G_CALLBACK (drag_data_received), image);
/* context menu on image */ /* context menu on image */
gesture = gtk_gesture_multi_press_new (); g_signal_connect (image, "button-press-event",
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY); G_CALLBACK (button_press), image);
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
/* Create the second image */ /* Create the second image */
image = gtk_image_new_from_icon_name ("process-stop"); image = gtk_image_new_from_icon_name ("process-stop");
@@ -344,10 +345,8 @@ do_clipboard (GtkWidget *do_widget)
G_CALLBACK (drag_data_received), image); G_CALLBACK (drag_data_received), image);
/* context menu on image */ /* context menu on image */
gesture = gtk_gesture_multi_press_new (); g_signal_connect (image, "button-press-event",
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY); G_CALLBACK (button_press), image);
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
} }
if (!gtk_widget_get_visible (window)) if (!gtk_widget_get_visible (window))

View File

@@ -1,7 +1,7 @@
/* Color Chooser /* Color Chooser
* *
* A GtkColorChooser lets the user choose a color. There are several * 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 * GtkColorChooserDialog is a prebuilt dialog containing a
* GtkColorChooserWidget. * GtkColorChooserWidget.
*/ */
@@ -88,7 +88,7 @@ do_colorsel (GtkWidget *do_widget)
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); 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 (); da = gtk_drawing_area_new ();
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 200); 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_halign (button, GTK_ALIGN_END);
gtk_widget_set_valign (button, GTK_ALIGN_CENTER); 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_signal_connect (button, "clicked",
G_CALLBACK (change_color_callback), NULL); G_CALLBACK (change_color_callback), NULL);

View File

@@ -144,7 +144,7 @@ create_capital_store (void)
{ NULL, "Jackson" }, { NULL, "Jackson" },
{ NULL, "Jefferson City" }, { NULL, "Jefferson City" },
{ NULL, "Juneau" }, { NULL, "Juneau" },
{ "K - O", NULL }, { "K - O" },
{ NULL, "Lansing" }, { NULL, "Lansing" },
{ NULL, "Lincoln" }, { NULL, "Lincoln" },
{ NULL, "Little Rock" }, { NULL, "Little Rock" },
@@ -154,7 +154,7 @@ create_capital_store (void)
{ NULL, "Nashville" }, { NULL, "Nashville" },
{ NULL, "Oklahoma City" }, { NULL, "Oklahoma City" },
{ NULL, "Olympia" }, { NULL, "Olympia" },
{ "P - S", NULL }, { NULL, "P - S" },
{ NULL, "Phoenix" }, { NULL, "Phoenix" },
{ NULL, "Pierre" }, { NULL, "Pierre" },
{ NULL, "Providence" }, { NULL, "Providence" },
@@ -256,7 +256,7 @@ mask_entry_set_background (MaskEntry *entry)
{ {
if (entry->mask) if (entry->mask)
{ {
if (!g_regex_match_simple (entry->mask, gtk_editable_get_text (GTK_EDITABLE (entry)), 0, 0)) if (!g_regex_match_simple (entry->mask, gtk_entry_get_text (GTK_ENTRY (entry)), 0, 0))
{ {
PangoAttrList *attrs; PangoAttrList *attrs;
@@ -326,7 +326,7 @@ do_combobox (GtkWidget *do_widget)
* insensitive rows * insensitive rows
*/ */
frame = gtk_frame_new ("Items with icons"); frame = gtk_frame_new ("Items with icons");
gtk_container_add (GTK_CONTAINER (vbox), frame); gtk_box_pack_start (GTK_BOX (vbox), frame);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
g_object_set (box, "margin", 5, NULL); g_object_set (box, "margin", 5, NULL);
@@ -367,7 +367,7 @@ do_combobox (GtkWidget *do_widget)
/* A combobox demonstrating trees. /* A combobox demonstrating trees.
*/ */
frame = gtk_frame_new ("Where are we ?"); frame = gtk_frame_new ("Where are we ?");
gtk_container_add (GTK_CONTAINER (vbox), frame); gtk_box_pack_start (GTK_BOX (vbox), frame);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
g_object_set (box, "margin", 5, NULL); g_object_set (box, "margin", 5, NULL);
@@ -395,7 +395,7 @@ do_combobox (GtkWidget *do_widget)
/* A GtkComboBoxEntry with validation */ /* A GtkComboBoxEntry with validation */
frame = gtk_frame_new ("Editable"); frame = gtk_frame_new ("Editable");
gtk_container_add (GTK_CONTAINER (vbox), frame); gtk_box_pack_start (GTK_BOX (vbox), frame);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
g_object_set (box, "margin", 5, NULL); g_object_set (box, "margin", 5, NULL);
@@ -413,7 +413,7 @@ do_combobox (GtkWidget *do_widget)
/* A combobox with string IDs */ /* A combobox with string IDs */
frame = gtk_frame_new ("String IDs"); frame = gtk_frame_new ("String IDs");
gtk_container_add (GTK_CONTAINER (vbox), frame); gtk_box_pack_start (GTK_BOX (vbox), frame);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
g_object_set (box, "margin", 5, NULL); g_object_set (box, "margin", 5, NULL);

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 874 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128" version="1.0"><defs><linearGradient id="f"><stop offset="0" stop-color="#ff7800"/><stop offset="1" stop-color="#ed333b"/></linearGradient><linearGradient id="e"><stop offset="0" stop-color="#f5c211"/><stop offset="1" stop-color="#33d17a" stop-opacity=".899"/></linearGradient><linearGradient id="d"><stop offset="0" stop-color="#c0bfbc"/><stop offset=".036" stop-color="#fafaf9"/><stop offset=".088" stop-color="#c0bfbc"/><stop offset=".399" stop-color="#d5d5d3"/><stop offset=".491" stop-color="#eaeae9"/><stop offset=".569" stop-color="#a7a5a1"/><stop offset=".966" stop-color="#a9a7a3"/><stop offset="1" stop-color="#fff"/></linearGradient><linearGradient id="a"><stop offset="0" stop-color="#d5d3cf"/><stop offset="1" stop-color="#f6f5f4"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#d5d3cf"/><stop offset="1" stop-color="#949390"/></linearGradient><linearGradient id="c"><stop offset="0" stop-color="#9a9996"/><stop offset="1" stop-color="#77767b"/></linearGradient><linearGradient xlink:href="#d" id="g" x1="-142.049" y1="236.001" x2="-9.951" y2="236.001" gradientUnits="userSpaceOnUse"/><radialGradient xlink:href="#e" id="h" cx="90.974" cy="263.479" fx="90.974" fy="263.479" r="22.703" gradientTransform="matrix(1.90297 -.05506 .0501 1.73133 -89.25 -176.863)" gradientUnits="userSpaceOnUse"/><radialGradient xlink:href="#f" id="i" cx="61.718" cy="270.719" fx="61.718" fy="270.719" r="22.703" gradientTransform="matrix(2.49049 0 0 2.92132 -91.99 -503.52)" gradientUnits="userSpaceOnUse"/></defs><path transform="translate(123.265 -118.118) scale(.7798)" d="M-75.74 161.438a10.997 10.997 0 0 0-5.758 1.468l-55.053 31.785a10.997 10.997 0 0 0-5.498 9.524v63.57a10.997 10.997 0 0 0 5.498 9.524l55.053 31.785a10.997 10.997 0 0 0 10.996 0l55.053-31.785a10.997 10.997 0 0 0 5.498-9.524v-63.57a10.997 10.997 0 0 0-5.498-9.524l-55.053-31.785a10.997 10.997 0 0 0-5.238-1.469z" style="marker:none" fill="url(#g)"/><path style="marker:none" d="M64.203 3.77a8.575 8.575 0 0 0-4.49 1.146l-42.93 24.786a8.575 8.575 0 0 0-4.288 7.427V86.7a8.575 8.575 0 0 0 4.287 7.426l42.93 24.786a8.575 8.575 0 0 0 8.575 0l42.93-24.786a8.575 8.575 0 0 0 4.288-7.426V37.129a8.575 8.575 0 0 0-4.287-7.427L68.288 4.916a8.575 8.575 0 0 0-4.085-1.145z" fill="#fff"/><path style="marker:none" d="M109.869 33.297L64 59.779 18.131 33.297 64 6.814z" fill="#98c1f1"/><path style="marker:none" d="M66.263 287.505l45.35-25.884.056-52.762-45.406 26.215z" fill="url(#h)" transform="translate(0 -172)"/><path d="M61.718 287.34l-45.35-25.885-.056-52.761 45.406 26.215z" style="marker:none" fill="url(#i)" transform="translate(0 -172)"/></svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 101 KiB

View File

@@ -0,0 +1,29 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:dc='http://purl.org/dc/elements/1.1/' sodipodi:docname='gtk3-demo-symbolic.svg' height='16.000015' id='svg7384' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' xmlns:osb='http://www.openswatchbook.org/uri/2009/osb' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:svg='http://www.w3.org/2000/svg' inkscape:version='0.48.5 r10040' version='1.1' width='16' xmlns='http://www.w3.org/2000/svg'>
<metadata id='metadata90'>
<rdf:RDF>
<cc:Work rdf:about=''>
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
<dc:title>Gnome Symbolic Icon Theme</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview inkscape:bbox-paths='true' bordercolor='#666666' borderopacity='1' inkscape:current-layer='layer9' inkscape:cx='-12.5126' inkscape:cy='-0.73412416' gridtolerance='10' inkscape:guide-bbox='true' guidetolerance='10' id='namedview88' inkscape:object-nodes='false' inkscape:object-paths='false' objecttolerance='10' pagecolor='#555753' inkscape:pageopacity='1' inkscape:pageshadow='2' showborder='false' showgrid='false' showguides='true' inkscape:snap-bbox='true' inkscape:snap-bbox-midpoints='false' inkscape:snap-global='true' inkscape:snap-grids='true' inkscape:snap-nodes='true' inkscape:snap-others='false' inkscape:snap-to-guides='true' inkscape:window-height='1375' inkscape:window-maximized='1' inkscape:window-width='2560' inkscape:window-x='0' inkscape:window-y='27' inkscape:zoom='5.6568542'>
<inkscape:grid empspacing='2' enabled='true' id='grid4866' originx='-182.99998px' originy='-251.99998px' snapvisiblegridlinesonly='true' spacingx='1px' spacingy='1px' type='xygrid' visible='true'/>
</sodipodi:namedview>
<title id='title9167'>Gnome Symbolic Icon Theme</title>
<defs id='defs7386'>
<linearGradient id='linearGradient7212' osb:paint='solid'>
<stop id='stop7214' offset='0' style='stop-color:#000000;stop-opacity:1;'/>
</linearGradient>
</defs>
<g inkscape:groupmode='layer' id='layer9' inkscape:label='apps' style='display:inline' transform='translate(-424.00018,35)'>
<rect height='8.0000048' id='rect7866' style='opacity:0.3;color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.39999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new' transform='matrix(0.83205029,0.5547002,0,1,0,0)' width='7.2111053' x='510.78668' y='-314.33347'/>
<rect height='8.0000086' id='rect7868' style='opacity:0.5;color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.39999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new' transform='matrix(-0.86824295,0.49613928,0,1,0,0)' width='8.0622425' x='-505.61908' y='219.8575'/>
<path inkscape:connector-curvature='0' d='m 431.53145,-28 -5.875,-3.65625 6.8125,-3.34375 6.03125,3 z' id='path7870' sodipodi:nodetypes='ccccc' style='color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.39999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new'/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -1,114 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="org.gtk.Demo-symbolic.svg"
height="16.03125"
id="svg7384"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
version="1.1"
width="16">
<metadata
id="metadata90">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Gnome Symbolic Icon Theme</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
inkscape:bbox-paths="true"
bordercolor="#666666"
borderopacity="1"
inkscape:current-layer="layer9"
inkscape:cx="0.53203442"
inkscape:cy="9.1822592"
gridtolerance="10"
inkscape:guide-bbox="true"
guidetolerance="10"
id="namedview88"
inkscape:object-nodes="false"
inkscape:object-paths="false"
objecttolerance="10"
pagecolor="#555753"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
showborder="true"
showgrid="false"
showguides="true"
inkscape:snap-bbox="true"
inkscape:snap-bbox-midpoints="false"
inkscape:snap-global="true"
inkscape:snap-grids="true"
inkscape:snap-nodes="true"
inkscape:snap-others="false"
inkscape:snap-to-guides="true"
inkscape:window-height="1375"
inkscape:window-maximized="1"
inkscape:window-width="2560"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:zoom="1">
<inkscape:grid
empspacing="2"
enabled="true"
id="grid4866"
originx="-203"
originy="-251.96875"
snapvisiblegridlinesonly="true"
spacingx="1"
spacingy="1"
type="xygrid"
visible="true" />
</sodipodi:namedview>
<title
id="title9167">Gnome Symbolic Icon Theme</title>
<defs
id="defs7386">
<linearGradient
id="linearGradient7212"
osb:paint="solid">
<stop
id="stop7214"
offset="0"
style="stop-color:#000000;stop-opacity:1;" />
</linearGradient>
</defs>
<g
inkscape:groupmode="layer"
id="layer9"
inkscape:label="apps"
style="display:inline"
transform="translate(-444.0002,35)">
<path
style="display:inline;opacity:0.3;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
d="m 457.97232,-31.569556 -5.96212,3.44224 -5.96215,-3.44224 v 0 l 5.96215,-3.44226 z"
id="path870-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path886-9"
d="m 450.98519,-19.648086 -5.99273,-3.42041 -0.007,-6.97219 v 0 l 6.00018,3.4642 z"
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new" />
<path
style="display:inline;opacity:0.60100002;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
d="m 452.98577,-19.648086 5.99273,-3.42041 0.007,-6.97219 v 0 l -6.00018,3.4642 z"
id="path931"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -105,6 +105,9 @@
<file>gnome-fs-directory.png</file> <file>gnome-fs-directory.png</file>
<file>gnome-fs-regular.png</file> <file>gnome-fs-regular.png</file>
</gresource> </gresource>
<gresource prefix="/stack">
<file>stack.ui</file>
</gresource>
<gresource prefix="/shortcuts"> <gresource prefix="/shortcuts">
<file>shortcuts.ui</file> <file>shortcuts.ui</file>
<file>shortcuts-builder.ui</file> <file>shortcuts-builder.ui</file>
@@ -112,21 +115,12 @@
<file>shortcuts-clocks.ui</file> <file>shortcuts-clocks.ui</file>
<file>shortcuts-boxes.ui</file> <file>shortcuts-boxes.ui</file>
</gresource> </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"> <gresource prefix="/revealer">
<file>revealer.ui</file> <file>revealer.ui</file>
</gresource> </gresource>
<gresource prefix="/images"> <gresource prefix="/images">
<file>alphatest.png</file> <file>alphatest.png</file>
<file>floppybuddy.gif</file> <file>floppybuddy.gif</file>
<file>gtk-logo.webm</file>
</gresource> </gresource>
<gresource prefix="/pixbufs"> <gresource prefix="/pixbufs">
<file>apple-red.png</file> <file>apple-red.png</file>
@@ -143,6 +137,7 @@
<file>application_demo.c</file> <file>application_demo.c</file>
<file>assistant.c</file> <file>assistant.c</file>
<file>builder.c</file> <file>builder.c</file>
<file>button_box.c</file>
<file>changedisplay.c</file> <file>changedisplay.c</file>
<file>clipboard.c</file> <file>clipboard.c</file>
<file>colorsel.c</file> <file>colorsel.c</file>
@@ -160,13 +155,14 @@
<file>editable_cells.c</file> <file>editable_cells.c</file>
<file>entry_buffer.c</file> <file>entry_buffer.c</file>
<file>entry_completion.c</file> <file>entry_completion.c</file>
<file>event_axes.c</file>
<file>expander.c</file> <file>expander.c</file>
<file>filtermodel.c</file> <file>filtermodel.c</file>
<file>fishbowl.c</file> <file>fishbowl.c</file>
<file>widgetbowl.c</file>
<file>flowbox.c</file> <file>flowbox.c</file>
<file>foreigndrawing.c</file> <file>foreigndrawing.c</file>
<file>font_features.c</file> <file>font_features.c</file>
<file>fontplane.c</file>
<file>gestures.c</file> <file>gestures.c</file>
<file>glarea.c</file> <file>glarea.c</file>
<file>headerbar.c</file> <file>headerbar.c</file>
@@ -183,13 +179,8 @@
<file>modelbutton.c</file> <file>modelbutton.c</file>
<file>overlay.c</file> <file>overlay.c</file>
<file>overlay2.c</file> <file>overlay2.c</file>
<file>paint.c</file>
<file>pagesetup.c</file> <file>pagesetup.c</file>
<file>paintable.c</file>
<file>paintable_animated.c</file>
<file>paintable_mediastream.c</file>
<file>panes.c</file> <file>panes.c</file>
<file>password_entry.c</file>
<file>pickers.c</file> <file>pickers.c</file>
<file>pixbufs.c</file> <file>pixbufs.c</file>
<file>popover.c</file> <file>popover.c</file>
@@ -202,26 +193,21 @@
<file>shortcuts.c</file> <file>shortcuts.c</file>
<file>sizegroup.c</file> <file>sizegroup.c</file>
<file>sidebar.c</file> <file>sidebar.c</file>
<file>sliding_puzzle.c</file>
<file>stack.c</file> <file>stack.c</file>
<file>spinbutton.c</file> <file>spinbutton.c</file>
<file>spinner.c</file> <file>spinner.c</file>
<file>tabs.c</file> <file>tabs.c</file>
<file>tagged_entry.c</file>
<file>textview.c</file> <file>textview.c</file>
<file>textscroll.c</file> <file>textscroll.c</file>
<file>theming_style_classes.c</file> <file>theming_style_classes.c</file>
<file>toolpalette.c</file>
<file>transparent.c</file> <file>transparent.c</file>
<file>tree_store.c</file> <file>tree_store.c</file>
<file>textmask.c</file> <file>textmask.c</file>
<file>video_player.c</file>
</gresource> </gresource>
<gresource prefix="/textview"> <gresource prefix="/textview">
<file>floppybuddy.gif</file> <file>floppybuddy.gif</file>
</gresource> </gresource>
<gresource prefix="/tagged_entry">
<file>tagstyle.css</file>
</gresource>
<gresource prefix="/listbox"> <gresource prefix="/listbox">
<file>listbox.ui</file> <file>listbox.ui</file>
<file>messages.txt</file> <file>messages.txt</file>
@@ -238,7 +224,6 @@
</gresource> </gresource>
<gresource prefix="/font_features"> <gresource prefix="/font_features">
<file>font-features.ui</file> <file>font-features.ui</file>
<file>fontplane.c</file>
</gresource> </gresource>
<gresource prefix="/spinbutton"> <gresource prefix="/spinbutton">
<file>spinbutton.ui</file> <file>spinbutton.ui</file>
@@ -252,7 +237,6 @@
</gresource> </gresource>
<gresource prefix="/transparent"> <gresource prefix="/transparent">
<file>portland-rose.jpg</file> <file>portland-rose.jpg</file>
<file>bluroverlay.c</file>
</gresource> </gresource>
<gresource prefix="/markup"> <gresource prefix="/markup">
<file>markup.txt</file> <file>markup.txt</file>
@@ -266,27 +250,4 @@
<gresource prefix="/dnd"> <gresource prefix="/dnd">
<file>dnd.css</file> <file>dnd.css</file>
</gresource> </gresource>
<gresource prefix="/tagged_entry">
<file>demotaggedentry.c</file>
<file>demotaggedentry.h</file>
</gresource>
<gresource prefix="/org/gtk/Demo">
<file>icons/16x16/actions/application-exit.png</file>
<file>icons/16x16/actions/document-new.png</file>
<file>icons/16x16/actions/document-open.png</file>
<file>icons/16x16/actions/document-save.png</file>
<file>icons/16x16/actions/edit-copy.png</file>
<file>icons/16x16/actions/edit-cut.png</file>
<file>icons/16x16/actions/edit-paste.png</file>
<file>icons/16x16/actions/process-stop.png</file>
<file>icons/16x16/actions/go-home.png</file>
<file>icons/16x16/actions/go-up.png</file>
<file>icons/16x16/actions/mail-send-receive-symbolic.symbolic.png</file>
<file>icons/16x16/actions/view-fullscreen-symbolic.symbolic.png</file>
<file>icons/16x16/actions/document-edit-symbolic.symbolic.png</file>
<file>icons/16x16/emotes/face-cool.png</file>
<file>icons/16x16/emotes/face-laugh-symbolic.symbolic.png</file>
<file>icons/16x16/status/battery-caution-charging-symbolic.symbolic.png</file>
<file>icons/16x16/categories/applications-other.png</file>
</gresource>
</gresources> </gresources>

View File

@@ -1,3 +1,5 @@
<?xml version="1.0" standalone="no"?>
<!--*- mode: xml -*-->
<interface> <interface>
<object class="GtkListStore" id="liststore1"> <object class="GtkListStore" id="liststore1">
<columns> <columns>
@@ -29,14 +31,16 @@
</accessibility> </accessibility>
</object> </object>
<object class="GtkWindow" id="window1"> <object class="GtkWindow" id="window1">
<property name="default-height">250</property> <property name="default_height">250</property>
<property name="default-width">440</property> <property name="default_width">440</property>
<property name="title" translatable="yes">Builder</property> <property name="title" translatable="yes">Builder</property>
<child> <child>
<object class="GtkBox" id="vbox1"> <object class="GtkBox" id="vbox1">
<property name="visible">1</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkMenuBar" id="menubar1"> <object class="GtkMenuBar" id="menubar1">
<property name="visible">1</property>
<child internal-child="accessible"> <child internal-child="accessible">
<object class="AtkObject" id="a11y-menubar"> <object class="AtkObject" id="a11y-menubar">
<property name="AtkObject::accessible-name">The menubar</property> <property name="AtkObject::accessible-name">The menubar</property>
@@ -44,40 +48,48 @@
</child> </child>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem">
<property name="visible">1</property>
<property name="label" translatable="yes">_File</property> <property name="label" translatable="yes">_File</property>
<property name="use-underline">1</property> <property name="use-underline">1</property>
<child type="submenu"> <child type="submenu">
<object class="GtkMenu"> <object class="GtkMenu">
<child> <child>
<object class="GtkMenuItem" id="new_item"> <object class="GtkMenuItem" id="new_item">
<property name="visible">1</property>
<property name="label" translatable="yes">_New</property> <property name="label" translatable="yes">_New</property>
<property name="use-underline">1</property> <property name="use-underline">1</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="open_item"> <object class="GtkMenuItem" id="open_item">
<property name="visible">1</property>
<property name="label" translatable="yes">_Open</property> <property name="label" translatable="yes">_Open</property>
<property name="use-underline">1</property> <property name="use-underline">1</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="save_item"> <object class="GtkMenuItem" id="save_item">
<property name="visible">1</property>
<property name="label" translatable="yes">_Save</property> <property name="label" translatable="yes">_Save</property>
<property name="use-underline">1</property> <property name="use-underline">1</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="save_as_item"> <object class="GtkMenuItem" id="save_as_item">
<property name="visible">1</property>
<property name="label" translatable="yes">Save _As</property> <property name="label" translatable="yes">Save _As</property>
<property name="use-underline">1</property> <property name="use-underline">1</property>
<accelerator key="s" modifiers="primary | shift-mask" signal="activate"/> <accelerator key="s" modifiers="primary | shift-mask" signal="activate"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkSeparatorMenuItem"/> <object class="GtkSeparatorMenuItem">
<property name="visible">1</property>
</object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="quit_item"> <object class="GtkMenuItem" id="quit_item">
<property name="visible">1</property>
<property name="label" translatable="yes">_Quit</property> <property name="label" translatable="yes">_Quit</property>
<property name="use-underline">1</property> <property name="use-underline">1</property>
<property name="action-name">win.quit</property> <property name="action-name">win.quit</property>
@@ -89,24 +101,28 @@
</child> </child>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem">
<property name="visible">1</property>
<property name="label" translatable="yes">_Edit</property> <property name="label" translatable="yes">_Edit</property>
<property name="use-underline">1</property> <property name="use-underline">1</property>
<child type="submenu"> <child type="submenu">
<object class="GtkMenu"> <object class="GtkMenu">
<child> <child>
<object class="GtkMenuItem" id="copy_item"> <object class="GtkMenuItem" id="copy_item">
<property name="visible">1</property>
<property name="label" translatable="yes">_Copy</property> <property name="label" translatable="yes">_Copy</property>
<property name="use-underline">1</property> <property name="use-underline">1</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="cut_item"> <object class="GtkMenuItem" id="cut_item">
<property name="visible">1</property>
<property name="label" translatable="yes">_Cut</property> <property name="label" translatable="yes">_Cut</property>
<property name="use-underline">1</property> <property name="use-underline">1</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="paste_item"> <object class="GtkMenuItem" id="paste_item">
<property name="visible">1</property>
<property name="label" translatable="yes">_Paste</property> <property name="label" translatable="yes">_Paste</property>
<property name="use-underline">1</property> <property name="use-underline">1</property>
</object> </object>
@@ -117,12 +133,14 @@
</child> </child>
<child> <child>
<object class="GtkMenuItem"> <object class="GtkMenuItem">
<property name="visible">1</property>
<property name="label" translatable="yes">_Help</property> <property name="label" translatable="yes">_Help</property>
<property name="use-underline">1</property> <property name="use-underline">1</property>
<child type="submenu"> <child type="submenu">
<object class="GtkMenu"> <object class="GtkMenu">
<child> <child>
<object class="GtkMenuItem" id="help_item"> <object class="GtkMenuItem" id="help_item">
<property name="visible">1</property>
<property name="label" translatable="yes">_Help</property> <property name="label" translatable="yes">_Help</property>
<property name="use-underline">1</property> <property name="use-underline">1</property>
<property name="action-name">win.help</property> <property name="action-name">win.help</property>
@@ -130,6 +148,7 @@
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="about_item"> <object class="GtkMenuItem" id="about_item">
<property name="visible">1</property>
<property name="label" translatable="yes">_About</property> <property name="label" translatable="yes">_About</property>
<property name="use-underline">1</property> <property name="use-underline">1</property>
<property name="action-name">win.about</property> <property name="action-name">win.about</property>
@@ -143,6 +162,7 @@
</child> </child>
<child> <child>
<object class="GtkToolbar" id="toolbar1"> <object class="GtkToolbar" id="toolbar1">
<property name="visible">1</property>
<child internal-child="accessible"> <child internal-child="accessible">
<object class="AtkObject" id="a11y-toolbar"> <object class="AtkObject" id="a11y-toolbar">
<property name="AtkObject::accessible-name">The toolbar</property> <property name="AtkObject::accessible-name">The toolbar</property>
@@ -150,6 +170,7 @@
</child> </child>
<child> <child>
<object class="GtkToolButton"> <object class="GtkToolButton">
<property name="visible">1</property>
<property name="label" translatable="yes">New</property> <property name="label" translatable="yes">New</property>
<property name="tooltip-text" translatable="yes">Create a new file</property> <property name="tooltip-text" translatable="yes">Create a new file</property>
<property name="icon-name">document-new</property> <property name="icon-name">document-new</property>
@@ -157,6 +178,7 @@
</child> </child>
<child> <child>
<object class="GtkToolButton"> <object class="GtkToolButton">
<property name="visible">1</property>
<property name="label" translatable="yes">Open</property> <property name="label" translatable="yes">Open</property>
<property name="tooltip-text" translatable="yes">Open a file</property> <property name="tooltip-text" translatable="yes">Open a file</property>
<property name="icon-name">document-open</property> <property name="icon-name">document-open</property>
@@ -164,6 +186,7 @@
</child> </child>
<child> <child>
<object class="GtkToolButton"> <object class="GtkToolButton">
<property name="visible">1</property>
<property name="label" translatable="yes">Save</property> <property name="label" translatable="yes">Save</property>
<property name="tooltip-text" translatable="yes">Save a file</property> <property name="tooltip-text" translatable="yes">Save a file</property>
<property name="icon-name">document-save</property> <property name="icon-name">document-save</property>
@@ -171,10 +194,13 @@
</object> </object>
</child> </child>
<child> <child>
<object class="GtkSeparatorToolItem"/> <object class="GtkSeparatorToolItem">
<property name="visible">1</property>
</object>
</child> </child>
<child> <child>
<object class="GtkToolButton"> <object class="GtkToolButton">
<property name="visible">1</property>
<property name="label" translatable="yes">Copy</property> <property name="label" translatable="yes">Copy</property>
<property name="tooltip-text" translatable="yes">Copy selected object into the clipboard</property> <property name="tooltip-text" translatable="yes">Copy selected object into the clipboard</property>
<property name="icon-name">edit-copy</property> <property name="icon-name">edit-copy</property>
@@ -182,6 +208,7 @@
</child> </child>
<child> <child>
<object class="GtkToolButton"> <object class="GtkToolButton">
<property name="visible">1</property>
<property name="label" translatable="yes">Cut</property> <property name="label" translatable="yes">Cut</property>
<property name="tooltip-text" translatable="yes">Cut selected object into the clipboard</property> <property name="tooltip-text" translatable="yes">Cut selected object into the clipboard</property>
<property name="icon-name">edit-cut</property> <property name="icon-name">edit-cut</property>
@@ -189,19 +216,25 @@
</child> </child>
<child> <child>
<object class="GtkToolButton"> <object class="GtkToolButton">
<property name="visible">1</property>
<property name="label" translatable="yes">Paste</property> <property name="label" translatable="yes">Paste</property>
<property name="tooltip-text" translatable="yes">Paste object from the clipboard</property> <property name="tooltip-text" translatable="yes">Paste object from the clipboard</property>
<property name="icon-name">edit-paste</property> <property name="icon-name">edit-paste</property>
</object> </object>
</child> </child>
</object> </object>
<packing>
<property name="position">1</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkScrolledWindow" id="scrolledwindow1"> <object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="shadow-type">in</property> <property name="shadow_type">in</property>
<property name="visible">1</property>
<property name="expand">1</property> <property name="expand">1</property>
<child> <child>
<object class="GtkTreeView" id="treeview1"> <object class="GtkTreeView" id="treeview1">
<property name="visible">1</property>
<property name="model">liststore1</property> <property name="model">liststore1</property>
<property name="tooltip-column">3</property> <property name="tooltip-column">3</property>
<child internal-child="accessible"> <child internal-child="accessible">
@@ -248,9 +281,17 @@
</object> </object>
</child> </child>
</object> </object>
<packing>
<property name="position">2</property>
</packing>
</child> </child>
<child> <child>
<object class="GtkStatusbar" id="statusbar1"/> <object class="GtkStatusbar" id="statusbar1">
<property name="visible">1</property>
</object>
<packing>
<property name="position">3</property>
</packing>
</child> </child>
</object> </object>
</child> </child>

View File

@@ -1,493 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2019 Red Hat, Inc.
*
* Authors:
* - Matthias Clasen <mclasen@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "demotaggedentry.h"
#include <gtk/gtk.h>
#include <gtk/gtk-a11y.h>
typedef struct {
GtkWidget *box;
GtkWidget *entry;
} DemoTaggedEntryPrivate;
static void demo_tagged_entry_editable_init (GtkEditableInterface *iface);
G_DEFINE_TYPE_WITH_CODE (DemoTaggedEntry, demo_tagged_entry, GTK_TYPE_WIDGET,
G_ADD_PRIVATE (DemoTaggedEntry)
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE, demo_tagged_entry_editable_init))
static void
demo_tagged_entry_init (DemoTaggedEntry *entry)
{
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
gtk_widget_set_has_surface (GTK_WIDGET (entry), FALSE);
priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_parent (priv->box, GTK_WIDGET (entry));
priv->entry = gtk_text_new ();
gtk_widget_set_hexpand (priv->entry, TRUE);
gtk_widget_set_vexpand (priv->entry, TRUE);
gtk_widget_set_hexpand (priv->box, FALSE);
gtk_widget_set_vexpand (priv->box, FALSE);
gtk_container_add (GTK_CONTAINER (priv->box), priv->entry);
gtk_editable_init_delegate (GTK_EDITABLE (entry));
}
static void
demo_tagged_entry_dispose (GObject *object)
{
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (object);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
if (priv->entry)
gtk_editable_finish_delegate (GTK_EDITABLE (entry));
g_clear_pointer (&priv->entry, gtk_widget_unparent);
g_clear_pointer (&priv->box, gtk_widget_unparent);
G_OBJECT_CLASS (demo_tagged_entry_parent_class)->dispose (object);
}
static void
demo_tagged_entry_finalize (GObject *object)
{
G_OBJECT_CLASS (demo_tagged_entry_parent_class)->finalize (object);
}
static void
demo_tagged_entry_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
if (gtk_editable_delegate_set_property (object, prop_id, value, pspec))
return;
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
static void
demo_tagged_entry_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
if (gtk_editable_delegate_get_property (object, prop_id, value, pspec))
return;
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
static void
demo_tagged_entry_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
gtk_widget_measure (priv->box, orientation, for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
demo_tagged_entry_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
gtk_widget_size_allocate (priv->box,
&(GtkAllocation) { 0, 0, width, height },
baseline);
}
static void
demo_tagged_entry_grab_focus (GtkWidget *widget)
{
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
gtk_widget_grab_focus (priv->entry);
}
static void
demo_tagged_entry_class_init (DemoTaggedEntryClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = demo_tagged_entry_dispose;
object_class->finalize = demo_tagged_entry_finalize;
object_class->get_property = demo_tagged_entry_get_property;
object_class->set_property = demo_tagged_entry_set_property;
widget_class->measure = demo_tagged_entry_measure;
widget_class->size_allocate = demo_tagged_entry_size_allocate;
widget_class->grab_focus = demo_tagged_entry_grab_focus;
gtk_editable_install_properties (object_class, 1);
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_ENTRY_ACCESSIBLE);
gtk_widget_class_set_css_name (widget_class, "entry");
}
static GtkEditable *
demo_tagged_entry_get_delegate (GtkEditable *editable)
{
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (editable);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
return GTK_EDITABLE (priv->entry);
}
static void
demo_tagged_entry_editable_init (GtkEditableInterface *iface)
{
iface->get_delegate = demo_tagged_entry_get_delegate;
}
GtkWidget *
demo_tagged_entry_new (void)
{
return GTK_WIDGET (g_object_new (DEMO_TYPE_TAGGED_ENTRY, NULL));
}
void
demo_tagged_entry_add_tag (DemoTaggedEntry *entry,
GtkWidget *tag)
{
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
gtk_container_add (GTK_CONTAINER (priv->box), tag);
}
void
demo_tagged_entry_insert_tag_after (DemoTaggedEntry *entry,
GtkWidget *tag,
GtkWidget *sibling)
{
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
if (sibling == NULL)
gtk_container_add (GTK_CONTAINER (priv->box), tag);
else
gtk_box_insert_child_after (GTK_BOX (priv->box), tag, sibling);
}
void
demo_tagged_entry_remove_tag (DemoTaggedEntry *entry,
GtkWidget *tag)
{
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
gtk_container_remove (GTK_CONTAINER (priv->box), tag);
}
struct _DemoTaggedEntryTag
{
GtkWidget parent;
GtkWidget *box;
GtkWidget *label;
GtkWidget *button;
gboolean has_close_button;
char *style;
};
struct _DemoTaggedEntryTagClass
{
GtkWidgetClass parent_class;
};
enum {
PROP_0,
PROP_LABEL,
PROP_HAS_CLOSE_BUTTON,
};
enum {
SIGNAL_CLICKED,
SIGNAL_BUTTON_CLICKED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_TYPE (DemoTaggedEntryTag, demo_tagged_entry_tag, GTK_TYPE_WIDGET)
static void
on_released (GtkGestureMultiPress *gesture,
int n_press,
double x,
double y,
DemoTaggedEntryTag *tag)
{
g_signal_emit (tag, signals[SIGNAL_CLICKED], 0);
}
static void
demo_tagged_entry_tag_init (DemoTaggedEntryTag *tag)
{
GtkGesture *gesture;
GtkCssProvider *provider;
gtk_widget_set_has_surface (GTK_WIDGET (tag), FALSE);
tag->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_parent (tag->box, GTK_WIDGET (tag));
tag->label = gtk_label_new ("");
gtk_container_add (GTK_CONTAINER (tag->box), tag->label);
gesture = gtk_gesture_multi_press_new ();
g_signal_connect (gesture, "released", G_CALLBACK (on_released), tag);
gtk_widget_add_controller (GTK_WIDGET (tag), GTK_EVENT_CONTROLLER (gesture));
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/tagged_entry/tagstyle.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
800);
g_object_unref (provider);
}
static void
demo_tagged_entry_tag_dispose (GObject *object)
{
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (object);
g_clear_pointer (&tag->box, gtk_widget_unparent);
G_OBJECT_CLASS (demo_tagged_entry_tag_parent_class)->dispose (object);
}
static void
demo_tagged_entry_tag_finalize (GObject *object)
{
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (object);
g_clear_pointer (&tag->box, gtk_widget_unparent);
g_clear_pointer (&tag->style, g_free);
G_OBJECT_CLASS (demo_tagged_entry_tag_parent_class)->finalize (object);
}
static void
demo_tagged_entry_tag_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (object);
switch (prop_id)
{
case PROP_LABEL:
demo_tagged_entry_tag_set_label (tag, g_value_get_string (value));
break;
case PROP_HAS_CLOSE_BUTTON:
demo_tagged_entry_tag_set_has_close_button (tag, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
demo_tagged_entry_tag_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (object);
switch (prop_id)
{
case PROP_LABEL:
g_value_set_string (value, demo_tagged_entry_tag_get_label (tag));
break;
case PROP_HAS_CLOSE_BUTTON:
g_value_set_boolean (value, demo_tagged_entry_tag_get_has_close_button (tag));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
demo_tagged_entry_tag_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (widget);
gtk_widget_measure (tag->box, orientation, for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
demo_tagged_entry_tag_size_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (widget);
gtk_widget_size_allocate (tag->box,
&(GtkAllocation) { 0, 0, width, height },
baseline);
}
static void
demo_tagged_entry_tag_class_init (DemoTaggedEntryTagClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = demo_tagged_entry_tag_dispose;
object_class->finalize = demo_tagged_entry_tag_finalize;
object_class->set_property = demo_tagged_entry_tag_set_property;
object_class->get_property = demo_tagged_entry_tag_get_property;
widget_class->measure = demo_tagged_entry_tag_measure;
widget_class->size_allocate = demo_tagged_entry_tag_size_allocate;
signals[SIGNAL_CLICKED] =
g_signal_new ("clicked",
DEMO_TYPE_TAGGED_ENTRY_TAG,
G_SIGNAL_RUN_FIRST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
signals[SIGNAL_BUTTON_CLICKED] =
g_signal_new ("button-clicked",
DEMO_TYPE_TAGGED_ENTRY_TAG,
G_SIGNAL_RUN_FIRST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
g_object_class_install_property (object_class, PROP_LABEL,
g_param_spec_string ("label", "Label", "Label",
NULL, G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_HAS_CLOSE_BUTTON,
g_param_spec_boolean ("has-close-button", "Has close button", "Whether this tag has a close button",
FALSE, G_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
gtk_widget_class_set_css_name (widget_class, "tag");
}
DemoTaggedEntryTag *
demo_tagged_entry_tag_new (const char *label)
{
return DEMO_TAGGED_ENTRY_TAG (g_object_new (DEMO_TYPE_TAGGED_ENTRY_TAG,
"label", label,
NULL));
}
const char *
demo_tagged_entry_tag_get_label (DemoTaggedEntryTag *tag)
{
g_return_val_if_fail (DEMO_IS_TAGGED_ENTRY_TAG (tag), NULL);
return gtk_label_get_label (GTK_LABEL (tag->label));
}
void
demo_tagged_entry_tag_set_label (DemoTaggedEntryTag *tag,
const char *label)
{
g_return_if_fail (DEMO_IS_TAGGED_ENTRY_TAG (tag));
gtk_label_set_label (GTK_LABEL (tag->label), label);
}
static void
on_button_clicked (GtkButton *button,
DemoTaggedEntryTag *tag)
{
g_signal_emit (tag, signals[SIGNAL_BUTTON_CLICKED], 0);
}
void
demo_tagged_entry_tag_set_has_close_button (DemoTaggedEntryTag *tag,
gboolean has_close_button)
{
g_return_if_fail (DEMO_IS_TAGGED_ENTRY_TAG (tag));
if ((tag->button != NULL) == has_close_button)
return;
if (!has_close_button && tag->button)
{
gtk_container_remove (GTK_CONTAINER (tag->box), tag->button);
tag->button = NULL;
}
else if (has_close_button && tag->button == NULL)
{
GtkWidget *image;
image = gtk_image_new_from_icon_name ("window-close-symbolic");
tag->button = gtk_button_new ();
gtk_container_add (GTK_CONTAINER (tag->button), image);
gtk_widget_set_halign (tag->button, GTK_ALIGN_CENTER);
gtk_widget_set_valign (tag->button, GTK_ALIGN_CENTER);
gtk_button_set_relief (GTK_BUTTON (tag->button), GTK_RELIEF_NONE);
gtk_container_add (GTK_CONTAINER (tag->box), tag->button);
g_signal_connect (tag->button, "clicked", G_CALLBACK (on_button_clicked), tag);
}
g_object_notify (G_OBJECT (tag), "has-close-button");
}
gboolean
demo_tagged_entry_tag_get_has_close_button (DemoTaggedEntryTag *tag)
{
g_return_val_if_fail (DEMO_IS_TAGGED_ENTRY_TAG (tag), FALSE);
return tag->button != NULL;
}

View File

@@ -1,89 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2019 Red Hat, Inc.
*
* Authors:
* - Matthias Clasen <mclasen@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __DEMO_TAGGED_ENTRY_H__
#define __DEMO_TAGGED_ENTRY_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define DEMO_TYPE_TAGGED_ENTRY (demo_tagged_entry_get_type ())
#define DEMO_TAGGED_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntry))
#define DEMO_TAGGED_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntryClass))
#define DEMO_IS_TAGGED_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEMO_TYPE_TAGGED_ENTRY))
#define DEMO_IS_TAGGED_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEMO_TYPE_TAGGED_ENTRY))
#define DEMO_TAGGED_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntryClass))
typedef struct _DemoTaggedEntry DemoTaggedEntry;
typedef struct _DemoTaggedEntryClass DemoTaggedEntryClass;
struct _DemoTaggedEntry
{
GtkWidget parent;
};
struct _DemoTaggedEntryClass
{
GtkWidgetClass parent_class;
};
#define DEMO_TYPE_TAGGED_ENTRY_TAG (demo_tagged_entry_tag_get_type ())
#define DEMO_TAGGED_ENTRY_TAG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTag))
#define DEMO_TAGGED_ENTRY_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTag))
#define DEMO_IS_TAGGED_ENTRY_TAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG))
#define DEMO_IS_TAGGED_ENTRY_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEMO_TYPE_TAGGED_ENTRY_TAG))
#define DEMO_TAGGED_ENTRY_TAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTagClass))
typedef struct _DemoTaggedEntryTag DemoTaggedEntryTag;
typedef struct _DemoTaggedEntryTagClass DemoTaggedEntryTagClass;
GType demo_tagged_entry_get_type (void) G_GNUC_CONST;
GType demo_tagged_entry_tag_get_type (void) G_GNUC_CONST;
GtkWidget * demo_tagged_entry_new (void);
void demo_tagged_entry_add_tag (DemoTaggedEntry *entry,
GtkWidget *tag);
void demo_tagged_entry_insert_tag_after (DemoTaggedEntry *entry,
GtkWidget *tag,
GtkWidget *sibling);
void demo_tagged_entry_remove_tag (DemoTaggedEntry *entry,
GtkWidget *tag);
DemoTaggedEntryTag *
demo_tagged_entry_tag_new (const char *label);
const char * demo_tagged_entry_tag_get_label (DemoTaggedEntryTag *tag);
void demo_tagged_entry_tag_set_label (DemoTaggedEntryTag *tag,
const char *label);
gboolean demo_tagged_entry_tag_get_has_close_button (DemoTaggedEntryTag *tag);
void demo_tagged_entry_tag_set_has_close_button (DemoTaggedEntryTag *tag,
gboolean has_close_button);
G_END_DECLS
#endif /* __DEMO_TAGGED_ENTRY_H__ */

View File

@@ -56,20 +56,20 @@ interactive_dialog_clicked (GtkButton *button,
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); 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"); image = gtk_image_new_from_icon_name ("dialog-question");
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE); 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 (); table = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (table), 4); gtk_grid_set_row_spacing (GTK_GRID (table), 4);
gtk_grid_set_column_spacing (GTK_GRID (table), 4); gtk_grid_set_column_spacing (GTK_GRID (table), 4);
gtk_container_add (GTK_CONTAINER (hbox), table); gtk_box_pack_start (GTK_BOX (hbox), table);
label = gtk_label_new_with_mnemonic ("_Entry 1"); label = gtk_label_new_with_mnemonic ("_Entry 1");
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1); gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
local_entry1 = gtk_entry_new (); local_entry1 = gtk_entry_new ();
gtk_editable_set_text (GTK_EDITABLE (local_entry1), gtk_editable_get_text (GTK_EDITABLE (entry1))); gtk_entry_set_text (GTK_ENTRY (local_entry1), gtk_entry_get_text (GTK_ENTRY (entry1)));
gtk_grid_attach (GTK_GRID (table), local_entry1, 1, 0, 1, 1); gtk_grid_attach (GTK_GRID (table), local_entry1, 1, 0, 1, 1);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), local_entry1); gtk_label_set_mnemonic_widget (GTK_LABEL (label), local_entry1);
@@ -77,7 +77,7 @@ interactive_dialog_clicked (GtkButton *button,
gtk_grid_attach (GTK_GRID (table), label, 0, 1, 1, 1); gtk_grid_attach (GTK_GRID (table), label, 0, 1, 1, 1);
local_entry2 = gtk_entry_new (); local_entry2 = gtk_entry_new ();
gtk_editable_set_text (GTK_EDITABLE (local_entry2), gtk_editable_get_text (GTK_EDITABLE (entry2))); gtk_entry_set_text (GTK_ENTRY (local_entry2), gtk_entry_get_text (GTK_ENTRY (entry2)));
gtk_grid_attach (GTK_GRID (table), local_entry2, 1, 1, 1, 1); gtk_grid_attach (GTK_GRID (table), local_entry2, 1, 1, 1, 1);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), local_entry2); gtk_label_set_mnemonic_widget (GTK_LABEL (label), local_entry2);
@@ -85,8 +85,8 @@ interactive_dialog_clicked (GtkButton *button,
if (response == GTK_RESPONSE_OK) if (response == GTK_RESPONSE_OK)
{ {
gtk_editable_set_text (GTK_EDITABLE (entry1), gtk_editable_get_text (GTK_EDITABLE (local_entry1))); gtk_entry_set_text (GTK_ENTRY (entry1), gtk_entry_get_text (GTK_ENTRY (local_entry1)));
gtk_editable_set_text (GTK_EDITABLE (entry2), gtk_editable_get_text (GTK_EDITABLE (local_entry2))); gtk_entry_set_text (GTK_ENTRY (entry2), gtk_entry_get_text (GTK_ENTRY (local_entry2)));
} }
gtk_widget_destroy (dialog); gtk_widget_destroy (dialog);
@@ -123,29 +123,29 @@ do_dialog (GtkWidget *do_widget)
/* Standard message dialog */ /* Standard message dialog */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); 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"); button = gtk_button_new_with_mnemonic ("_Message Dialog");
g_signal_connect (button, "clicked", g_signal_connect (button, "clicked",
G_CALLBACK (message_dialog_clicked), NULL); G_CALLBACK (message_dialog_clicked), NULL);
gtk_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*/ /* Interactive dialog*/
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8); 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); vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
button = gtk_button_new_with_mnemonic ("_Interactive Dialog"); button = gtk_button_new_with_mnemonic ("_Interactive Dialog");
g_signal_connect (button, "clicked", g_signal_connect (button, "clicked",
G_CALLBACK (interactive_dialog_clicked), NULL); G_CALLBACK (interactive_dialog_clicked), NULL);
gtk_container_add (GTK_CONTAINER (hbox), vbox2); gtk_box_pack_start (GTK_BOX (hbox), vbox2);
gtk_container_add (GTK_CONTAINER (vbox2), button); gtk_box_pack_start (GTK_BOX (vbox2), button);
table = gtk_grid_new (); table = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (table), 4); gtk_grid_set_row_spacing (GTK_GRID (table), 4);
gtk_grid_set_column_spacing (GTK_GRID (table), 4); gtk_grid_set_column_spacing (GTK_GRID (table), 4);
gtk_container_add (GTK_CONTAINER (hbox), table); gtk_box_pack_start (GTK_BOX (hbox), table);
label = gtk_label_new_with_mnemonic ("_Entry 1"); label = gtk_label_new_with_mnemonic ("_Entry 1");
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1); gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);

View File

@@ -199,7 +199,7 @@ edit_label_done (GtkWidget *entry, gpointer data)
gtk_container_child_get (GTK_CONTAINER (fixed), entry, "x", &x, "y", &y, NULL); gtk_container_child_get (GTK_CONTAINER (fixed), entry, "x", &x, "y", &y, NULL);
label = GTK_WIDGET (g_object_get_data (G_OBJECT (entry), "label")); label = GTK_WIDGET (g_object_get_data (G_OBJECT (entry), "label"));
gtk_label_set_text (GTK_LABEL (label), gtk_editable_get_text (GTK_EDITABLE (entry))); gtk_label_set_text (GTK_LABEL (label), gtk_entry_get_text (GTK_ENTRY (entry)));
gtk_widget_destroy (entry); gtk_widget_destroy (entry);
} }
@@ -218,7 +218,7 @@ edit_cb (GtkWidget *child)
g_object_set_data (G_OBJECT (entry), "label", child); g_object_set_data (G_OBJECT (entry), "label", child);
gtk_editable_set_text (GTK_EDITABLE (entry), gtk_label_get_text (GTK_LABEL (child))); gtk_entry_set_text (GTK_ENTRY (entry), gtk_label_get_text (GTK_LABEL (child)));
g_signal_connect (entry, "activate", G_CALLBACK (edit_label_done), NULL); g_signal_connect (entry, "activate", G_CALLBACK (edit_label_done), NULL);
gtk_fixed_put (GTK_FIXED (fixed), entry, x, y); gtk_fixed_put (GTK_FIXED (fixed), entry, x, y);
gtk_widget_grab_focus (entry); gtk_widget_grab_focus (entry);
@@ -299,7 +299,7 @@ pressed_cb (GtkGesture *gesture,
rect.height = 0; rect.height = 0;
gtk_menu_popup_at_rect (GTK_MENU (menu), gtk_menu_popup_at_rect (GTK_MENU (menu),
gtk_widget_get_surface (widget), gtk_widget_get_window (widget),
&rect, &rect,
GDK_GRAVITY_NORTH_WEST, GDK_GRAVITY_NORTH_WEST,
GDK_GRAVITY_NORTH_WEST, GDK_GRAVITY_NORTH_WEST,
@@ -352,15 +352,14 @@ do_dnd (GtkWidget *do_widget)
gtk_container_add (GTK_CONTAINER (window), vbox); gtk_container_add (GTK_CONTAINER (window), vbox);
fixed = gtk_fixed_new (); 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_hexpand (fixed, TRUE);
gtk_widget_set_vexpand (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); gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (multipress), 0);
g_signal_connect (multipress, "pressed", G_CALLBACK (pressed_cb), NULL); g_signal_connect (multipress, "pressed", G_CALLBACK (pressed_cb), NULL);
g_signal_connect (multipress, "released", G_CALLBACK (released_cb), NULL); g_signal_connect (multipress, "released", G_CALLBACK (released_cb), NULL);
gtk_widget_add_controller (fixed, GTK_EVENT_CONTROLLER (multipress));
provider = gtk_css_provider_new (); provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/dnd/dnd.css"); gtk_css_provider_load_from_resource (provider, "/dnd/dnd.css");

View File

@@ -4,8 +4,8 @@
* of various kinds. * of various kinds.
* *
* This demo has two drawing areas. The checkerboard area shows * This demo has two drawing areas. The checkerboard area shows
* how you can just draw something; all you have to do is set a function * how you can just draw something; all you have to do is write
* via gtk_drawing_area_set_draw_func(), as shown here. * a signal handler for expose_event, as shown here.
* *
* The "scribble" area is a bit more advanced, and shows how to handle * The "scribble" area is a bit more advanced, and shows how to handle
* events such as button presses and mouse motion. Click the mouse * events such as button presses and mouse motion. Click the mouse
@@ -86,41 +86,45 @@ draw_brush (GtkWidget *widget,
cairo_destroy (cr); 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; static gboolean
static double start_y; scribble_button_press_event (GtkWidget *widget,
GdkEventButton *event,
static void gpointer data)
drag_begin (GtkGestureDrag *gesture,
double x,
double y,
GtkWidget *area)
{ {
start_x = x; double x, y;
start_y = y; guint button;
draw_brush (area, x, y); gdk_event_get_button ((GdkEvent *)event, &button);
gdk_event_get_coords ((GdkEvent *)event, &x, &y);
if (button == GDK_BUTTON_PRIMARY)
draw_brush (widget, x, y);
/* We've handled the event, stop processing */
return TRUE;
} }
static void static gboolean
drag_update (GtkGestureDrag *gesture, scribble_motion_notify_event (GtkWidget *widget,
double x, GdkEventMotion *event,
double y, gpointer data)
GtkWidget *area)
{ {
draw_brush (area, start_x + x, start_y + y); double x, y;
GdkModifierType state;
gdk_event_get_state ((GdkEvent *)event, &state);
gdk_event_get_coords ((GdkEvent *)event, &x, &y);
if (state & GDK_BUTTON1_MASK)
draw_brush (widget, x, y);
/* We've handled it, stop processing */
return TRUE;
} }
static void
drag_end (GtkGestureDrag *gesture,
double x,
double y,
GtkWidget *area)
{
draw_brush (area, start_x + x, start_y + y);
}
static void static void
checkerboard_draw (GtkDrawingArea *da, checkerboard_draw (GtkDrawingArea *da,
@@ -137,7 +141,7 @@ checkerboard_draw (GtkDrawingArea *da,
/* At the start of a draw handler, a clip region has been set on /* At the start of a draw handler, a clip region has been set on
* the Cairo context, and the contents have been cleared to the * the Cairo context, and the contents have been cleared to the
* widget's background color. The docs for * widget's background color. The docs for
* gdk_surface_begin_paint_region() give more details on how this * gdk_window_begin_paint_region() give more details on how this
* works. * works.
*/ */
@@ -185,7 +189,6 @@ do_drawingarea (GtkWidget *do_widget)
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *da; GtkWidget *da;
GtkWidget *label; GtkWidget *label;
GtkGesture *drag;
if (!window) if (!window)
{ {
@@ -208,12 +211,12 @@ do_drawingarea (GtkWidget *do_widget)
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"<u>Checkerboard pattern</u>"); "<u>Checkerboard pattern</u>");
gtk_container_add (GTK_CONTAINER (vbox), label); gtk_box_pack_start (GTK_BOX (vbox), label);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_widget_set_vexpand (frame, TRUE); 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 (); da = gtk_drawing_area_new ();
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100); gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
@@ -228,12 +231,12 @@ do_drawingarea (GtkWidget *do_widget)
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"<u>Scribble area</u>"); "<u>Scribble area</u>");
gtk_container_add (GTK_CONTAINER (vbox), label); gtk_box_pack_start (GTK_BOX (vbox), label);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_widget_set_vexpand (frame, TRUE); gtk_widget_set_vexpand (frame, TRUE);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); 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 (); da = gtk_drawing_area_new ();
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100); gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
@@ -244,14 +247,11 @@ do_drawingarea (GtkWidget *do_widget)
g_signal_connect (da, "size-allocate", g_signal_connect (da, "size-allocate",
G_CALLBACK (scribble_size_allocate), NULL); G_CALLBACK (scribble_size_allocate), NULL);
drag = gtk_gesture_drag_new (); /* Event signals */
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), GDK_BUTTON_PRIMARY); g_signal_connect (da, "motion-notify-event",
gtk_widget_add_controller (da, GTK_EVENT_CONTROLLER (drag)); G_CALLBACK (scribble_motion_notify_event), NULL);
g_signal_connect (da, "button-press-event",
g_signal_connect (drag, "drag-begin", G_CALLBACK (drag_begin), da); G_CALLBACK (scribble_button_press_event), NULL);
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)) if (!gtk_widget_get_visible (window))

View File

@@ -356,7 +356,7 @@ do_editable_cells (GtkWidget *do_widget)
g_object_set (vbox, "margin", 5, NULL); g_object_set (vbox, "margin", 5, NULL);
gtk_container_add (GTK_CONTAINER (window), vbox); 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!)")); gtk_label_new ("Shopping list (you can edit the cells!)"));
sw = gtk_scrolled_window_new (NULL, NULL); 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_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC); GTK_POLICY_AUTOMATIC);
gtk_container_add (GTK_CONTAINER (vbox), sw); gtk_box_pack_start (GTK_BOX (vbox), sw);
/* create models */ /* create models */
items_model = create_items_model (); items_model = create_items_model ();
@@ -387,17 +387,17 @@ do_editable_cells (GtkWidget *do_widget)
/* some buttons */ /* some buttons */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE); gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
gtk_container_add (GTK_CONTAINER (vbox), hbox); gtk_box_pack_start (GTK_BOX (vbox), hbox);
button = gtk_button_new_with_label ("Add item"); button = gtk_button_new_with_label ("Add item");
g_signal_connect (button, "clicked", g_signal_connect (button, "clicked",
G_CALLBACK (add_item), treeview); G_CALLBACK (add_item), treeview);
gtk_container_add (GTK_CONTAINER (hbox), button); gtk_box_pack_start (GTK_BOX (hbox), button);
button = gtk_button_new_with_label ("Remove item"); button = gtk_button_new_with_label ("Remove item");
g_signal_connect (button, "clicked", g_signal_connect (button, "clicked",
G_CALLBACK (remove_item), treeview); G_CALLBACK (remove_item), treeview);
gtk_container_add (GTK_CONTAINER (hbox), button); gtk_box_pack_start (GTK_BOX (hbox), button);
gtk_window_set_default_size (GTK_WINDOW (window), 320, 200); gtk_window_set_default_size (GTK_WINDOW (window), 320, 200);
} }

View File

@@ -34,19 +34,19 @@ do_entry_buffer (GtkWidget *do_widget)
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"Entries share a buffer. Typing in one is reflected in the other."); "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 */ /* Create a buffer */
buffer = gtk_entry_buffer_new (NULL, 0); buffer = gtk_entry_buffer_new (NULL, 0);
/* Create our first entry */ /* Create our first entry */
entry = gtk_entry_new_with_buffer (buffer); 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 */ /* Create the second entry */
entry = gtk_entry_new_with_buffer (buffer); entry = gtk_entry_new_with_buffer (buffer);
gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE); 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); g_object_unref (buffer);
} }

View File

@@ -60,11 +60,11 @@ do_entry_completion (GtkWidget *do_widget)
label = gtk_label_new (NULL); 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_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 */ /* Create our entry */
entry = gtk_entry_new (); entry = gtk_entry_new ();
gtk_container_add (GTK_CONTAINER (vbox), entry); gtk_box_pack_start (GTK_BOX (vbox), entry);
/* Create the completion object */ /* Create the completion object */
completion = gtk_entry_completion_new (); completion = gtk_entry_completion_new ();

668
demos/gtk-demo/event_axes.c Normal file
View 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;
}

View File

@@ -73,7 +73,7 @@ do_expander (GtkWidget *do_widget)
"resize the window. Do it already !", -1); "resize the window. Do it already !", -1);
gtk_container_add (GTK_CONTAINER (sw), tv); gtk_container_add (GTK_CONTAINER (sw), tv);
gtk_container_add (GTK_CONTAINER (expander), sw); 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_signal_connect (expander, "notify::expanded",
G_CALLBACK (expander_cb), window); G_CALLBACK (expander_cb), window);

View File

@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.1 -->
<interface> <interface>
<requires lib="gtk+" version="3.16"/> <requires lib="gtk+" version="3.16"/>
<object class="GtkListStore" id="liststore1"> <object class="GtkListStore" id="liststore1">
<columns> <columns>
<!-- column-name width -->
<column type="gint"/> <column type="gint"/>
<!-- column-name height -->
<column type="gint"/> <column type="gint"/>
</columns> </columns>
<data> <data>
@@ -30,31 +34,31 @@
<property name="title" translatable="yes">Filter Model</property> <property name="title" translatable="yes">Filter Model</property>
<child> <child>
<object class="GtkGrid" id="grid1"> <object class="GtkGrid" id="grid1">
<property name="visible">1</property>
<property name="margin">10</property> <property name="margin">10</property>
<property name="row-spacing">10</property> <property name="row_spacing">10</property>
<property name="column-spacing">10</property> <property name="column_spacing">10</property>
<property name="column-homogeneous">1</property> <property name="column_homogeneous">1</property>
<child> <child>
<object class="GtkLabel" id="label1"> <object class="GtkLabel" id="label1">
<property name="visible">1</property>
<property name="label" translatable="yes">Original</property> <property name="label" translatable="yes">Original</property>
<property name="xalign">0</property> <property name="xalign">0</property>
<attributes> <attributes>
<attribute name="weight" value="bold"></attribute> <attribute name="weight" value="bold"/>
</attributes> </attributes>
<accessibility>
<relation type="label-for" target="treeview1"/>
</accessibility>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left_attach">0</property>
<property name="top-attach">0</property> <property name="top_attach">0</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkTreeView" id="treeview1"> <object class="GtkTreeView" id="treeview1">
<property name="can-focus">1</property> <property name="visible">1</property>
<property name="can_focus">1</property>
<property name="model">liststore1</property> <property name="model">liststore1</property>
<property name="headers-clickable">0</property> <property name="headers_clickable">0</property>
<child internal-child="selection"> <child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1"/> <object class="GtkTreeSelection" id="treeview-selection1"/>
</child> </child>
@@ -80,20 +84,18 @@
</child> </child>
</object> </object>
</child> </child>
<accessibility>
<relation type="labelled-by" target="label1"/>
</accessibility>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left_attach">0</property>
<property name="top-attach">1</property> <property name="top_attach">1</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkTreeView" id="treeview2"> <object class="GtkTreeView" id="treeview2">
<property name="can-focus">1</property> <property name="visible">1</property>
<property name="headers-clickable">0</property> <property name="can_focus">1</property>
<property name="search-column">0</property> <property name="headers_clickable">0</property>
<property name="search_column">0</property>
<child internal-child="selection"> <child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection3"/> <object class="GtkTreeSelection" id="treeview-selection3"/>
</child> </child>
@@ -131,52 +133,46 @@
</child> </child>
</object> </object>
</child> </child>
<accessibility>
<relation type="labelled-by" target="label2"/>
</accessibility>
</object> </object>
<packing> <packing>
<property name="left-attach">1</property> <property name="left_attach">1</property>
<property name="top-attach">1</property> <property name="top_attach">1</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="label2"> <object class="GtkLabel" id="label2">
<property name="visible">1</property>
<property name="label" translatable="yes">Computed Columns</property> <property name="label" translatable="yes">Computed Columns</property>
<property name="xalign">0</property> <property name="xalign">0</property>
<attributes> <attributes>
<attribute name="weight" value="bold"></attribute> <attribute name="weight" value="bold"/>
</attributes> </attributes>
<accessibility>
<relation type="label-for" target="treeview2"/>
</accessibility>
</object> </object>
<packing> <packing>
<property name="left-attach">1</property> <property name="left_attach">1</property>
<property name="top-attach">0</property> <property name="top_attach">0</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="label3"> <object class="GtkLabel" id="label3">
<property name="visible">1</property>
<property name="label" translatable="yes">Filtered</property> <property name="label" translatable="yes">Filtered</property>
<property name="xalign">0</property> <property name="xalign">0</property>
<attributes> <attributes>
<attribute name="weight" value="bold"></attribute> <attribute name="weight" value="bold"/>
</attributes> </attributes>
<accessibility>
<relation type="label-for" target="treeview3"/>
</accessibility>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left_attach">0</property>
<property name="top-attach">2</property> <property name="top_attach">2</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkTreeView" id="treeview3"> <object class="GtkTreeView" id="treeview3">
<property name="can-focus">1</property> <property name="visible">1</property>
<property name="headers-clickable">0</property> <property name="can_focus">1</property>
<property name="search-column">0</property> <property name="headers_clickable">0</property>
<property name="search_column">0</property>
<child internal-child="selection"> <child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection5"/> <object class="GtkTreeSelection" id="treeview-selection5"/>
</child> </child>
@@ -196,13 +192,10 @@
</child> </child>
</object> </object>
</child> </child>
<accessibility>
<relation type="labelled-by" target="label3"/>
</accessibility>
</object> </object>
<packing> <packing>
<property name="left-attach">0</property> <property name="left_attach">0</property>
<property name="top-attach">3</property> <property name="top_attach">3</property>
</packing> </packing>
</child> </child>
</object> </object>

View File

@@ -8,273 +8,165 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "gtkfishbowl.h" #include "gtkfishbowl.h"
#include "gtkgears.h"
const char *const css = GtkWidget *allow_changes;
".blurred-button {"
" box-shadow: 0px 0px 5px 10px rgba(0, 0, 0, 0.5);"
"}"
"";
char **icon_names = NULL; #define N_STATS 5
gsize n_icon_names = 0;
static void #define STATS_UPDATE_TIME G_USEC_PER_SEC
init_icon_names (GtkIconTheme *theme)
{
GPtrArray *icons;
GList *l, *icon_list;
if (icon_names) typedef struct _Stats Stats;
return; struct _Stats {
gint64 last_stats;
gint64 last_frame;
gint last_suggestion;
guint frame_counter_max;
icon_list = gtk_icon_theme_list_icons (theme, NULL); guint stats_index;
icons = g_ptr_array_new (); guint frame_counter[N_STATS];
guint item_counter[N_STATS];
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 },
}; };
static int selected_widget_type = -1; static Stats *
static const int N_WIDGET_TYPES = G_N_ELEMENTS (widget_types); 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 static void
set_widget_type (GtkFishbowl *fishbowl, do_stats (GtkWidget *widget,
int widget_type_index) GtkWidget *info_label,
gint *suggested_change)
{ {
GtkWidget *window, *headerbar; Stats *stats;
gint64 frame_time;
if (widget_type_index == selected_widget_type) stats = get_stats (widget);
return; 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, n_frames = 0;
widget_types[selected_widget_type].create_func); 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)); if (stats->frame_counter[stats->stats_index] >= 19 * stats->frame_counter_max / 20)
headerbar = gtk_window_get_titlebar (GTK_WINDOW (window)); {
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar), if (stats->last_suggestion > 0)
widget_types[selected_widget_type].name); 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 stats->stats_index = (stats->stats_index + 1) % N_STATS;
next_button_clicked_cb (GtkButton *source, stats->frame_counter[stats->stats_index] = 0;
gpointer user_data) stats->item_counter[stats->stats_index] = stats->item_counter[(stats->stats_index + N_STATS - 1) % N_STATS];
{ stats->last_stats = frame_time;
GtkFishbowl *fishbowl = user_data;
int new_index; if (suggested_change)
*suggested_change = stats->last_suggestion;
if (selected_widget_type + 1 >= N_WIDGET_TYPES) else
new_index = 0; stats->last_suggestion = 0;
}
else 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 static void
prev_button_clicked_cb (GtkButton *source, stats_update (GtkWidget *widget)
gpointer user_data)
{ {
GtkFishbowl *fishbowl = user_data; Stats *stats;
int new_index;
if (selected_widget_type - 1 < 0) stats = get_stats (widget);
new_index = N_WIDGET_TYPES - 1;
else
new_index = selected_widget_type - 1;
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 * GtkWidget *
do_fishbowl (GtkWidget *do_widget) do_fishbowl (GtkWidget *do_widget)
{ {
static GtkWidget *window = NULL; 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) if (!window)
{ {
GtkBuilder *builder; GtkBuilder *builder;
GtkWidget *bowl; GtkWidget *bowl, *info_label;
g_type_ensure (GTK_TYPE_FISHBOWL); g_type_ensure (GTK_TYPE_FISHBOWL);
builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui"); 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); gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window")); window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl")); bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl"));
selected_widget_type = -1; gtk_fishbowl_set_use_icons (GTK_FISHBOWL (bowl), TRUE);
set_widget_type (GTK_FISHBOWL (bowl), 0); 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_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget)); gtk_widget_get_display (do_widget));
g_signal_connect (window, "destroy", g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window); G_CALLBACK (gtk_widget_destroyed), &window);
gtk_widget_realize (window); gtk_widget_realize (window);
gtk_widget_add_tick_callback (bowl, move_fish, info_label, NULL);
} }
if (!gtk_widget_get_visible (window)) if (!gtk_widget_get_visible (window))
@@ -282,5 +174,6 @@ do_fishbowl (GtkWidget *do_widget)
else else
gtk_widget_destroy (window); gtk_widget_destroy (window);
return window; return window;
} }

View File

@@ -1,79 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<!-- interface-requires gtk+ 3.6 -->
<object class="GtkWindow" id="window"> <object class="GtkWindow" id="window">
<property name="title" translatable="yes">Fishbowl</property> <property name="title" translatable="yes">Fishbowl</property>
<child type="titlebar"> <child type="titlebar">
<object class="GtkHeaderBar" id=""> <object class="GtkHeaderBar" id="">
<property name="show-title-buttons">1</property> <property name="visible">True</property>
<property name="show-title-buttons">True</property>
<child> <child>
<object class="GtkBox"> <object class="GtkLabel" id="info_label">
<style> <property name="visible">True</property>
<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> </object>
<packing> <packing>
<property name="pack-type">end</property> <property name="pack_type">end</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" bind-source="bowl" bind-property="framerate"/> <property name="visible">True</property>
<property name="label" bind-source="bowl" bind-property="count">0</property>
</object> </object>
<packing> <packing>
<property name="pack-type">end</property> <property name="pack_type">end</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label">Icons, </property>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" bind-source="bowl" bind-property="count"/>
</object>
<packing>
<property name="pack-type">end</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkToggleButton" id="changes_allow"> <object class="GtkToggleButton" id="changes_allow">
<property name="visible" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean"/> <property name="active">False</property>
<property name="visible" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean">True</property>
<property name="icon-name">changes-allow</property> <property name="icon-name">changes-allow</property>
<property name="relief">none</property> <property name="relief">none</property>
</object> </object>
<packing> <packing>
<property name="pack-type">end</property> <property name="pack_type">end</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkToggleButton" id="changes_prevent"> <object class="GtkToggleButton" id="changes_prevent">
<property name="active" bind-source="changes_allow" bind-property="active" bind-flags="bidirectional|invert-boolean">1</property> <property name="active" bind-source="changes_allow" bind-property="active" bind-flags="bidirectional|invert-boolean">True</property>
<property name="visible" bind-source="changes_prevent" bind-property="active" bind-flags="invert-boolean">0</property> <property name="visible" bind-source="changes_prevent" bind-property="active" bind-flags="invert-boolean">False</property>
<property name="icon-name">changes-prevent</property> <property name="icon-name">changes-prevent</property>
<property name="relief">none</property> <property name="relief">none</property>
</object> </object>
<packing> <packing>
<property name="pack-type">end</property> <property name="pack_type">end</property>
</packing> </packing>
</child> </child>
</object> </object>
@@ -82,7 +52,6 @@
<object class="GtkFishbowl" id="bowl"> <object class="GtkFishbowl" id="bowl">
<property name="visible">True</property> <property name="visible">True</property>
<property name="animating">True</property> <property name="animating">True</property>
<property name="benchmark" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean">1</property>
</object> </object>
</child> </child>
</object> </object>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,315 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2012 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "fontplane.h"
#include "gtk.h"
enum {
PROP_0,
PROP_WEIGHT_ADJUSTMENT,
PROP_WIDTH_ADJUSTMENT
};
G_DEFINE_TYPE (GtkFontPlane, gtk_font_plane, GTK_TYPE_WIDGET)
static double
adjustment_get_normalized_value (GtkAdjustment *adj)
{
return (gtk_adjustment_get_value (adj) - gtk_adjustment_get_lower (adj)) /
(gtk_adjustment_get_upper (adj) - gtk_adjustment_get_lower (adj));
}
static void
val_to_xy (GtkFontPlane *plane,
gint *x,
gint *y)
{
gdouble u, v;
gint width, height;
width = gtk_widget_get_allocated_width (GTK_WIDGET (plane));
height = gtk_widget_get_allocated_height (GTK_WIDGET (plane));
u = adjustment_get_normalized_value (plane->width_adj);
v = adjustment_get_normalized_value (plane->weight_adj);
*x = CLAMP (width * u, 0, width - 1);
*y = CLAMP (height * (1 - v), 0, height - 1);
}
static void
plane_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkFontPlane *plane = GTK_FONT_PLANE (widget);
gint x, y;
gint width, height;
cairo_t *cr;
val_to_xy (plane, &x, &y);
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
cr = gtk_snapshot_append_cairo (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height));
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_rectangle (cr, 0, 0, width, height);
cairo_paint (cr);
cairo_move_to (cr, 0, y + 0.5);
cairo_line_to (cr, width, y + 0.5);
cairo_move_to (cr, x + 0.5, 0);
cairo_line_to (cr, x + 0.5, height);
if (gtk_widget_has_visible_focus (widget))
{
cairo_set_line_width (cr, 3.0);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.6);
cairo_stroke_preserve (cr);
cairo_set_line_width (cr, 1.0);
cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.8);
cairo_stroke (cr);
}
else
{
cairo_set_line_width (cr, 1.0);
cairo_set_source_rgba (cr, 0.8, 0.8, 0.8, 0.8);
cairo_stroke (cr);
}
cairo_destroy (cr);
}
static void
set_cross_cursor (GtkWidget *widget,
gboolean enabled)
{
if (enabled)
gtk_widget_set_cursor_from_name (widget, "crosshair");
else
gtk_widget_set_cursor (widget, NULL);
}
static void
adj_changed (GtkFontPlane *plane)
{
gtk_widget_queue_draw (GTK_WIDGET (plane));
}
static void
adjustment_set_normalized_value (GtkAdjustment *adj,
double val)
{
gtk_adjustment_set_value (adj,
gtk_adjustment_get_lower (adj) +
val * (gtk_adjustment_get_upper (adj) - gtk_adjustment_get_lower (adj)));
}
static void
update_value (GtkFontPlane *plane,
gint x,
gint y)
{
GtkWidget *widget = GTK_WIDGET (plane);
gdouble u, v;
u = CLAMP (x * (1.0 / gtk_widget_get_allocated_width (widget)), 0, 1);
v = CLAMP (1 - y * (1.0 / gtk_widget_get_allocated_height (widget)), 0, 1);
adjustment_set_normalized_value (plane->width_adj, u);
adjustment_set_normalized_value (plane->weight_adj, v);
gtk_widget_queue_draw (widget);
}
static void
hold_action (GtkGestureLongPress *gesture,
gdouble x,
gdouble y,
GtkFontPlane *plane)
{
gboolean handled;
g_signal_emit_by_name (plane, "popup-menu", &handled);
}
static void
plane_drag_gesture_begin (GtkGestureDrag *gesture,
gdouble start_x,
gdouble start_y,
GtkFontPlane *plane)
{
guint button;
button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
if (button == GDK_BUTTON_SECONDARY)
{
gboolean handled;
g_signal_emit_by_name (plane, "popup-menu", &handled);
}
if (button != GDK_BUTTON_PRIMARY)
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
return;
}
set_cross_cursor (GTK_WIDGET (plane), TRUE);
update_value (plane, start_x, start_y);
gtk_widget_grab_focus (GTK_WIDGET (plane));
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
}
static void
plane_drag_gesture_update (GtkGestureDrag *gesture,
gdouble offset_x,
gdouble offset_y,
GtkFontPlane *plane)
{
gdouble start_x, start_y;
gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (gesture),
&start_x, &start_y);
update_value (plane, start_x + offset_x, start_y + offset_y);
}
static void
plane_drag_gesture_end (GtkGestureDrag *gesture,
gdouble offset_x,
gdouble offset_y,
GtkFontPlane *plane)
{
set_cross_cursor (GTK_WIDGET (plane), FALSE);
}
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",
G_CALLBACK (plane_drag_gesture_begin), plane);
g_signal_connect (gesture, "drag-update",
G_CALLBACK (plane_drag_gesture_update), plane);
g_signal_connect (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));
gesture = gtk_gesture_long_press_new ();
g_signal_connect (gesture, "pressed",
G_CALLBACK (hold_action), plane);
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (gesture),
TRUE);
gtk_widget_add_controller (GTK_WIDGET (plane), GTK_EVENT_CONTROLLER (gesture));
}
static void
plane_finalize (GObject *object)
{
GtkFontPlane *plane = GTK_FONT_PLANE (object);
g_clear_object (&plane->weight_adj);
g_clear_object (&plane->width_adj);
G_OBJECT_CLASS (gtk_font_plane_parent_class)->finalize (object);
}
static void
plane_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkFontPlane *plane = GTK_FONT_PLANE (object);
GtkAdjustment *adjustment;
switch (prop_id)
{
case PROP_WEIGHT_ADJUSTMENT:
adjustment = GTK_ADJUSTMENT (g_value_get_object (value));
if (adjustment)
{
plane->weight_adj = g_object_ref_sink (adjustment);
g_signal_connect_swapped (adjustment, "value-changed", G_CALLBACK (adj_changed), plane);
}
break;
case PROP_WIDTH_ADJUSTMENT:
adjustment = GTK_ADJUSTMENT (g_value_get_object (value));
if (adjustment)
{
plane->width_adj = g_object_ref_sink (adjustment);
g_signal_connect_swapped (adjustment, "value-changed", G_CALLBACK (adj_changed), plane);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_font_plane_class_init (GtkFontPlaneClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->finalize = plane_finalize;
object_class->set_property = plane_set_property;
widget_class->snapshot = plane_snapshot;
g_object_class_install_property (object_class,
PROP_WEIGHT_ADJUSTMENT,
g_param_spec_object ("weight-adjustment",
NULL,
NULL,
GTK_TYPE_ADJUSTMENT,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
PROP_WIDTH_ADJUSTMENT,
g_param_spec_object ("width-adjustment",
NULL,
NULL,
GTK_TYPE_ADJUSTMENT,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY));
}
GtkWidget *
gtk_font_plane_new (GtkAdjustment *weight_adj,
GtkAdjustment *width_adj)
{
return g_object_new (GTK_TYPE_FONT_PLANE,
"weight-adjustment", weight_adj,
"width-adjustment", width_adj,
NULL);
}

View File

@@ -1,64 +0,0 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2012 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_FONT_PLANE_H__
#define __GTK_FONT_PLANE_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GTK_TYPE_FONT_PLANE (gtk_font_plane_get_type ())
#define GTK_FONT_PLANE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FONT_PLANE, GtkFontPlane))
#define GTK_FONT_PLANE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FONT_PLANE, GtkFontPlaneClass))
#define GTK_IS_FONT_PLANE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_COLOR_PLANE))
#define GTK_IS_FONT_PLANE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_COLOR_PLANE))
#define GTK_FONT_PLANE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FONT_PLANE, GtkFontPlaneClass))
typedef struct _GtkFontPlane GtkFontPlane;
typedef struct _GtkFontPlaneClass GtkFontPlaneClass;
struct _GtkFontPlane
{
GtkWidget parent_instance;
GtkAdjustment *weight_adj;
GtkAdjustment *width_adj;
GtkGesture *drag_gesture;
};
struct _GtkFontPlaneClass
{
GtkWidgetClass parent_class;
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
};
GType gtk_font_plane_get_type (void) G_GNUC_CONST;
GtkWidget * gtk_font_plane_new (GtkAdjustment *width_adj,
GtkAdjustment *weight_adj);
G_END_DECLS
#endif /* __GTK_FONT_PLANE_H__ */

View File

@@ -1,8 +1,8 @@
/* Foreign drawing /* 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 * 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. * use GtkStyleContext and the gtk_render_ APIs to achieve this.
* *
* Note that this is a very simple, non-interactive example. * Note that this is a very simple, non-interactive example.

View File

@@ -33,7 +33,7 @@ demos = []
for demo_file in in_files: for demo_file in in_files:
filename = demo_file[demo_file.rfind('/')+1:] filename = demo_file[demo_file.rfind('/')+1:]
demo_name = filename.replace(".c", "") demo_name = filename.replace(".c", "")
with open(demo_file, 'r', encoding='utf-8') as f: with open(demo_file, 'r') as f:
title = f.readline().replace("/*", "").strip() title = f.readline().replace("/*", "").strip()

View File

@@ -157,15 +157,16 @@ do_gestures (GtkWidget *do_widget)
NULL, NULL); NULL, NULL);
/* Swipe */ /* Swipe */
gesture = gtk_gesture_swipe_new (); gesture = gtk_gesture_swipe_new (drawing_area);
g_signal_connect (gesture, "swipe", g_signal_connect (gesture, "swipe",
G_CALLBACK (swipe_gesture_swept), drawing_area); G_CALLBACK (swipe_gesture_swept), drawing_area);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
GTK_PHASE_BUBBLE); 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 */ /* 3fg swipe for touchpads */
gesture = g_object_new (GTK_TYPE_GESTURE_SWIPE, gesture = g_object_new (GTK_TYPE_GESTURE_SWIPE,
"widget", drawing_area,
"n-points", 3, "n-points", 3,
NULL); NULL);
g_signal_connect (gesture, "begin", g_signal_connect (gesture, "begin",
@@ -174,34 +175,33 @@ do_gestures (GtkWidget *do_widget)
G_CALLBACK (swipe_gesture_swept), drawing_area); G_CALLBACK (swipe_gesture_swept), drawing_area);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
GTK_PHASE_BUBBLE); 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 */ /* Long press */
gesture = gtk_gesture_long_press_new (); gesture = gtk_gesture_long_press_new (drawing_area);
g_signal_connect (gesture, "pressed", g_signal_connect (gesture, "pressed",
G_CALLBACK (long_press_gesture_pressed), drawing_area); G_CALLBACK (long_press_gesture_pressed), drawing_area);
g_signal_connect (gesture, "end", g_signal_connect (gesture, "end",
G_CALLBACK (long_press_gesture_end), drawing_area); G_CALLBACK (long_press_gesture_end), drawing_area);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
GTK_PHASE_BUBBLE); 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 */
rotate = gesture = gtk_gesture_rotate_new (); rotate = gesture = gtk_gesture_rotate_new (drawing_area);
g_signal_connect (gesture, "angle-changed", g_signal_connect (gesture, "angle-changed",
G_CALLBACK (rotation_angle_changed), drawing_area); G_CALLBACK (rotation_angle_changed), drawing_area);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
GTK_PHASE_BUBBLE); 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 */
zoom = gesture = gtk_gesture_zoom_new (); zoom = gesture = gtk_gesture_zoom_new (drawing_area);
g_signal_connect (gesture, "scale-changed", g_signal_connect (gesture, "scale-changed",
G_CALLBACK (zoom_scale_changed), drawing_area); G_CALLBACK (zoom_scale_changed), drawing_area);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
GTK_PHASE_BUBBLE); 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)) if (!gtk_widget_get_visible (window))

Binary file not shown.

View File

@@ -1,8 +1,8 @@
[Desktop Entry] [Desktop Entry]
Name=GTK Demo Name=GTK+ Demo
Comment=GTK code examples and demonstrations Comment=GTK+ code examples and demonstrations
Exec=gtk4-demo Exec=gtk4-demo
Icon=org.gtk.Demo Icon=gtk4-demo
Terminal=false Terminal=false
Type=Application Type=Application
StartupNotify=true StartupNotify=true

View File

@@ -24,18 +24,13 @@ typedef struct _GtkFishbowlChild GtkFishbowlChild;
struct _GtkFishbowlPrivate struct _GtkFishbowlPrivate
{ {
GtkFishCreationFunc creation_func;
GList *children; GList *children;
guint count; guint count;
gint64 last_frame_time; gint64 last_frame_time;
gint64 update_delay;
guint tick_id; guint tick_id;
double framerate; guint use_icons: 1;
int last_benchmark_change;
guint benchmark : 1;
}; };
struct _GtkFishbowlChild struct _GtkFishbowlChild
@@ -50,25 +45,18 @@ struct _GtkFishbowlChild
enum { enum {
PROP_0, PROP_0,
PROP_ANIMATING, PROP_ANIMATING,
PROP_BENCHMARK,
PROP_COUNT, PROP_COUNT,
PROP_FRAMERATE,
PROP_UPDATE_DELAY,
NUM_PROPERTIES NUM_PROPERTIES
}; };
static GParamSpec *props[NUM_PROPERTIES] = { NULL, }; 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 static void
gtk_fishbowl_init (GtkFishbowl *fishbowl) gtk_fishbowl_init (GtkFishbowl *fishbowl)
{ {
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl); gtk_widget_set_has_window (GTK_WIDGET (fishbowl), FALSE);
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); 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 static void
gtk_fishbowl_measure (GtkWidget *widget, gtk_fishbowl_measure (GtkWidget *widget,
GtkOrientation orientation, GtkOrientation orientation,
@@ -128,10 +125,10 @@ gtk_fishbowl_measure (GtkWidget *widget,
} }
static void static void
gtk_fishbowl_size_allocate (GtkWidget *widget, gtk_fishbowl_size_allocate (GtkWidget *widget,
int width, const GtkAllocation *allocation,
int height, int baseline,
int baseline) GtkAllocation *out_clip)
{ {
GtkFishbowl *fishbowl = GTK_FISHBOWL (widget); GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl); GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
@@ -142,18 +139,20 @@ gtk_fishbowl_size_allocate (GtkWidget *widget,
for (children = priv->children; children; children = children->next) for (children = priv->children; children; children = children->next)
{ {
GtkAllocation child_clip;
child = children->data; child = children->data;
if (!gtk_widget_get_visible (child->widget)) if (!gtk_widget_get_visible (child->widget))
continue; continue;
gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL); gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
child_allocation.x = round (child->x * (width - child_requisition.width)); child_allocation.x = allocation->x + round (child->x * (allocation->width - child_requisition.width));
child_allocation.y = round (child->y * (height - child_requisition.height)); child_allocation.y = allocation->y + round (child->y * (allocation->height - child_requisition.height));
child_allocation.width = child_requisition.width; child_allocation.width = child_requisition.width;
child_allocation.height = child_requisition.height; 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 static void
gtk_fishbowl_add (GtkFishbowl *fishbowl, gtk_fishbowl_add (GtkContainer *container,
GtkWidget *widget) GtkWidget *widget)
{ {
GtkFishbowl *fishbowl = GTK_FISHBOWL (container);
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl); GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
GtkFishbowlChild *child_info; GtkFishbowlChild *child_info;
@@ -189,12 +189,13 @@ gtk_fishbowl_add (GtkFishbowl *fishbowl,
} }
static void static void
gtk_fishbowl_remove (GtkFishbowl *fishbowl, gtk_fishbowl_remove (GtkContainer *container,
GtkWidget *widget) GtkWidget *widget)
{ {
GtkFishbowl *fishbowl = GTK_FISHBOWL (container);
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl); GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
GtkFishbowlChild *child; GtkFishbowlChild *child;
GtkWidget *widget_bowl = GTK_WIDGET (fishbowl); GtkWidget *widget_container = GTK_WIDGET (container);
GList *children; GList *children;
for (children = priv->children; children; children = children->next) for (children = priv->children; children; children = children->next)
@@ -211,8 +212,8 @@ gtk_fishbowl_remove (GtkFishbowl *fishbowl,
g_list_free (children); g_list_free (children);
g_free (child); g_free (child);
if (was_visible && gtk_widget_get_visible (widget_bowl)) if (was_visible && gtk_widget_get_visible (widget_container))
gtk_widget_queue_resize (widget_bowl); gtk_widget_queue_resize (widget_container);
priv->count--; priv->count--;
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]); g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
@@ -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 static void
gtk_fishbowl_dispose (GObject *object) 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)); gtk_fishbowl_set_animating (fishbowl, g_value_get_boolean (value));
break; break;
case PROP_BENCHMARK:
gtk_fishbowl_set_benchmark (fishbowl, g_value_get_boolean (value));
break;
case PROP_COUNT: case PROP_COUNT:
gtk_fishbowl_set_count (fishbowl, g_value_get_uint (value)); gtk_fishbowl_set_count (fishbowl, g_value_get_uint (value));
break; break;
case PROP_UPDATE_DELAY:
gtk_fishbowl_set_update_delay (fishbowl, g_value_get_int64 (value));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@@ -278,22 +291,10 @@ gtk_fishbowl_get_property (GObject *object,
g_value_set_boolean (value, gtk_fishbowl_get_animating (fishbowl)); g_value_set_boolean (value, gtk_fishbowl_get_animating (fishbowl));
break; break;
case PROP_BENCHMARK:
g_value_set_boolean (value, gtk_fishbowl_get_benchmark (fishbowl));
break;
case PROP_COUNT: case PROP_COUNT:
g_value_set_uint (value, gtk_fishbowl_get_count (fishbowl)); g_value_set_uint (value, gtk_fishbowl_get_count (fishbowl));
break; 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: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@@ -305,6 +306,7 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
object_class->dispose = gtk_fishbowl_dispose; object_class->dispose = gtk_fishbowl_dispose;
object_class->set_property = gtk_fishbowl_set_property; object_class->set_property = gtk_fishbowl_set_property;
@@ -313,6 +315,10 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
widget_class->measure = gtk_fishbowl_measure; widget_class->measure = gtk_fishbowl_measure;
widget_class->size_allocate = gtk_fishbowl_size_allocate; 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] = props[PROP_ANIMATING] =
g_param_spec_boolean ("animating", g_param_spec_boolean ("animating",
"animating", "animating",
@@ -320,36 +326,13 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
FALSE, FALSE,
G_PARAM_READWRITE); 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] = props[PROP_COUNT] =
g_param_spec_uint ("count", g_param_spec_uint ("count",
"Count", "Count",
"Number of widgets", "Number of widgets",
0, G_MAXUINT, 0, G_MAXUINT,
0, 0,
G_PARAM_READWRITE); G_PARAM_READABLE);
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_object_class_install_properties (object_class, NUM_PROPERTIES, props); g_object_class_install_properties (object_class, NUM_PROPERTIES, props);
} }
@@ -362,58 +345,96 @@ gtk_fishbowl_get_count (GtkFishbowl *fishbowl)
return priv->count; 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 void
gtk_fishbowl_set_count (GtkFishbowl *fishbowl, gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
guint count) guint count)
{ {
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl); GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
if (priv->count == count)
return;
g_object_freeze_notify (G_OBJECT (fishbowl)); g_object_freeze_notify (G_OBJECT (fishbowl));
while (priv->count > count) 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) while (priv->count < count)
{ {
GtkWidget *new_widget; 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)); 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 gboolean
gtk_fishbowl_get_animating (GtkFishbowl *fishbowl) gtk_fishbowl_get_animating (GtkFishbowl *fishbowl)
{ {
@@ -422,111 +443,6 @@ gtk_fishbowl_get_animating (GtkFishbowl *fishbowl)
return priv->tick_id != 0; 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 static gboolean
gtk_fishbowl_tick (GtkWidget *widget, gtk_fishbowl_tick (GtkWidget *widget,
GdkFrameClock *frame_clock, GdkFrameClock *frame_clock,
@@ -537,11 +453,9 @@ gtk_fishbowl_tick (GtkWidget *widget,
GtkFishbowlChild *child; GtkFishbowlChild *child;
GList *l; GList *l;
gint64 frame_time, elapsed; gint64 frame_time, elapsed;
gboolean do_update;
frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget)); frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
elapsed = frame_time - priv->last_frame_time; 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; priv->last_frame_time = frame_time;
/* last frame was 0, so we're just starting to animate */ /* 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); gtk_widget_queue_allocate (widget);
if (do_update)
gtk_fishbowl_do_update (fishbowl);
return G_SOURCE_CONTINUE; return G_SOURCE_CONTINUE;
} }
@@ -607,57 +518,8 @@ gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
priv->last_frame_time = 0; priv->last_frame_time = 0;
gtk_widget_remove_tick_callback (GTK_WIDGET (fishbowl), priv->tick_id); gtk_widget_remove_tick_callback (GTK_WIDGET (fishbowl), priv->tick_id);
priv->tick_id = 0; 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]); 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));
}

View File

@@ -32,37 +32,29 @@ G_BEGIN_DECLS
typedef struct _GtkFishbowl GtkFishbowl; typedef struct _GtkFishbowl GtkFishbowl;
typedef struct _GtkFishbowlClass GtkFishbowlClass; typedef struct _GtkFishbowlClass GtkFishbowlClass;
typedef GtkWidget * (* GtkFishCreationFunc) (void);
struct _GtkFishbowl struct _GtkFishbowl
{ {
GtkWidget parent; GtkContainer container;
}; };
struct _GtkFishbowlClass struct _GtkFishbowlClass
{ {
GtkWidgetClass parent_class; GtkContainerClass parent_class;
}; };
GType gtk_fishbowl_get_type (void) G_GNUC_CONST; GType gtk_fishbowl_get_type (void) G_GNUC_CONST;
GtkWidget* gtk_fishbowl_new (void); GtkWidget* gtk_fishbowl_new (void);
void gtk_fishbowl_set_use_icons (GtkFishbowl *fishbowl,
gboolean use_icons);
guint gtk_fishbowl_get_count (GtkFishbowl *fishbowl); guint gtk_fishbowl_get_count (GtkFishbowl *fishbowl);
void gtk_fishbowl_set_count (GtkFishbowl *fishbowl, void gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
guint count); guint count);
gboolean gtk_fishbowl_get_animating (GtkFishbowl *fishbowl); gboolean gtk_fishbowl_get_animating (GtkFishbowl *fishbowl);
void gtk_fishbowl_set_animating (GtkFishbowl *fishbowl, void gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
gboolean animating); 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 G_END_DECLS

View File

@@ -1,960 +0,0 @@
/* The rendering code in here is taken from es2gears, which has the
* following copyright notice:
*
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Ported to GLES2.
* Kristian Høgsberg <krh@bitplanet.net>
* May 3, 2010
*
* Improve GLES2 port:
* * Refactor gear drawing.
* * Use correct normals for surfaces.
* * Improve shader.
* * Use perspective projection transformation.
* * Add FPS count.
* * Add comments.
* Alexandros Frantzis <alexandros.frantzis@linaro.org>
* Jul 13, 2010
*/
#include "config.h"
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <epoxy/gl.h>
#include "gtkgears.h"
#define STRIPS_PER_TOOTH 7
#define VERTICES_PER_TOOTH 34
#define GEAR_VERTEX_STRIDE 6
#ifndef HAVE_SINCOS
static void
sincos (double x, double *_sin, double *_cos)
{
*_sin = sin (x);
*_cos = cos (x);
}
#endif
/**
* Struct describing the vertices in triangle strip
*/
struct vertex_strip {
/** The first vertex in the strip */
GLint first;
/** The number of consecutive vertices in the strip after the first */
GLint count;
};
/* Each vertex consist of GEAR_VERTEX_STRIDE GLfloat attributes */
typedef GLfloat GearVertex[GEAR_VERTEX_STRIDE];
/**
* Struct representing a gear.
*/
struct gear {
/** The array of vertices comprising the gear */
GearVertex *vertices;
/** The number of vertices comprising the gear */
int nvertices;
/** The array of triangle strips comprising the gear */
struct vertex_strip *strips;
/** The number of triangle strips comprising the gear */
int nstrips;
};
typedef struct {
/* The view rotation [x, y, z] */
GLfloat view_rot[GTK_GEARS_N_AXIS];
/* The Vertex Array Object */
GLuint vao;
/* The shader program */
GLuint program;
/* The gears */
struct gear *gear1;
struct gear *gear2;
struct gear *gear3;
/** The Vertex Buffer Object holding the vertices in the graphics card */
GLuint gear_vbo[3];
/** The location of the shader uniforms */
GLuint ModelViewProjectionMatrix_location;
GLuint NormalMatrix_location;
GLuint LightSourcePosition_location;
GLuint MaterialColor_location;
/* The current gear rotation angle */
GLfloat angle;
/* The projection matrix */
GLfloat ProjectionMatrix[16];
/* The direction of the directional light for the scene */
GLfloat LightSourcePosition[4];
gint64 first_frame_time;
guint tick;
GtkLabel *fps_label;
} GtkGearsPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (GtkGears, gtk_gears, GTK_TYPE_GL_AREA)
static gboolean gtk_gears_render (GtkGLArea *area,
GdkGLContext *context);
static void gtk_gears_reshape (GtkGLArea *area,
int width,
int height);
static void gtk_gears_realize (GtkWidget *widget);
static void gtk_gears_unrealize (GtkWidget *widget);
static gboolean gtk_gears_tick (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data);
static void destroy_gear (struct gear *g);
GtkWidget *
gtk_gears_new (void)
{
return g_object_new (gtk_gears_get_type (),
"has-depth-buffer", TRUE,
NULL);
}
static void
gtk_gears_init (GtkGears *gears)
{
GtkGearsPrivate *priv = gtk_gears_get_instance_private (gears);
priv->view_rot[GTK_GEARS_X_AXIS] = 20.0;
priv->view_rot[GTK_GEARS_Y_AXIS] = 30.0;
priv->view_rot[GTK_GEARS_Z_AXIS] = 20.0;
priv->LightSourcePosition[0] = 5.0;
priv->LightSourcePosition[1] = 5.0;
priv->LightSourcePosition[2] = 10.0;
priv->LightSourcePosition[3] = 1.0;
priv->tick = gtk_widget_add_tick_callback (GTK_WIDGET (gears), gtk_gears_tick, gears, NULL);
}
static void
gtk_gears_finalize (GObject *obj)
{
GtkGears *gears = GTK_GEARS (obj);
GtkGearsPrivate *priv = gtk_gears_get_instance_private (gears);
gtk_widget_remove_tick_callback (GTK_WIDGET (gears), priv->tick);
g_clear_object (&priv->fps_label);
g_clear_pointer (&priv->gear1, destroy_gear);
g_clear_pointer (&priv->gear2, destroy_gear);
g_clear_pointer (&priv->gear3, destroy_gear);
G_OBJECT_CLASS (gtk_gears_parent_class)->finalize (obj);
}
static void
gtk_gears_class_init (GtkGearsClass *klass)
{
GTK_GL_AREA_CLASS (klass)->render = gtk_gears_render;
GTK_GL_AREA_CLASS (klass)->resize = gtk_gears_reshape;
GTK_WIDGET_CLASS (klass)->realize = gtk_gears_realize;
GTK_WIDGET_CLASS (klass)->unrealize = gtk_gears_unrealize;
G_OBJECT_CLASS (klass)->finalize = gtk_gears_finalize;
}
/*
* Fills a gear vertex.
*
* @param v the vertex to fill
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coortinate
* @param n pointer to the normal table
*
* @return the operation error code
*/
static GearVertex *
vert (GearVertex *v,
GLfloat x,
GLfloat y,
GLfloat z,
GLfloat n[3])
{
v[0][0] = x;
v[0][1] = y;
v[0][2] = z;
v[0][3] = n[0];
v[0][4] = n[1];
v[0][5] = n[2];
return v + 1;
}
static void
destroy_gear (struct gear *g)
{
g_free (g->strips);
g_free (g);
}
/**
* Create a gear wheel.
*
* @param inner_radius radius of hole at center
* @param outer_radius radius at center of teeth
* @param width width of gear
* @param teeth number of teeth
* @param tooth_depth depth of tooth
*
* @return pointer to the constructed struct gear
*/
static struct gear *
create_gear (GLfloat inner_radius,
GLfloat outer_radius,
GLfloat width,
GLint teeth,
GLfloat tooth_depth)
{
GLfloat r0, r1, r2;
GLfloat da;
GearVertex *v;
struct gear *gear;
double s[5], c[5];
GLfloat normal[3];
int cur_strip = 0;
int i;
/* Allocate memory for the gear */
gear = g_malloc (sizeof *gear);
/* Calculate the radii used in the gear */
r0 = inner_radius;
r1 = outer_radius - tooth_depth / 2.0;
r2 = outer_radius + tooth_depth / 2.0;
da = 2.0 * M_PI / teeth / 4.0;
/* Allocate memory for the triangle strip information */
gear->nstrips = STRIPS_PER_TOOTH * teeth;
gear->strips = g_malloc0_n (gear->nstrips, sizeof (*gear->strips));
/* Allocate memory for the vertices */
gear->vertices = g_malloc0_n (VERTICES_PER_TOOTH * teeth, sizeof(*gear->vertices));
v = gear->vertices;
for (i = 0; i < teeth; i++) {
/* A set of macros for making the creation of the gears easier */
#define GEAR_POINT(p, r, da) do { p.x = (r) * c[(da)]; p.y = (r) * s[(da)]; } while(0)
#define SET_NORMAL(x, y, z) do { \
normal[0] = (x); normal[1] = (y); normal[2] = (z); \
} while(0)
#define GEAR_VERT(v, point, sign) vert((v), p[(point)].x, p[(point)].y, (sign) * width * 0.5, normal)
#define START_STRIP do { \
gear->strips[cur_strip].first = v - gear->vertices; \
} while(0);
#define END_STRIP do { \
int _tmp = (v - gear->vertices); \
gear->strips[cur_strip].count = _tmp - gear->strips[cur_strip].first; \
cur_strip++; \
} while (0)
#define QUAD_WITH_NORMAL(p1, p2) do { \
SET_NORMAL((p[(p1)].y - p[(p2)].y), -(p[(p1)].x - p[(p2)].x), 0); \
v = GEAR_VERT(v, (p1), -1); \
v = GEAR_VERT(v, (p1), 1); \
v = GEAR_VERT(v, (p2), -1); \
v = GEAR_VERT(v, (p2), 1); \
} while(0)
struct point {
GLfloat x;
GLfloat y;
};
/* Create the 7 points (only x,y coords) used to draw a tooth */
struct point p[7];
/* Calculate needed sin/cos for varius angles */
sincos(i * 2.0 * G_PI / teeth + da * 0, &s[0], &c[0]);
sincos(i * 2.0 * M_PI / teeth + da * 1, &s[1], &c[1]);
sincos(i * 2.0 * M_PI / teeth + da * 2, &s[2], &c[2]);
sincos(i * 2.0 * M_PI / teeth + da * 3, &s[3], &c[3]);
sincos(i * 2.0 * M_PI / teeth + da * 4, &s[4], &c[4]);
GEAR_POINT(p[0], r2, 1);
GEAR_POINT(p[1], r2, 2);
GEAR_POINT(p[2], r1, 0);
GEAR_POINT(p[3], r1, 3);
GEAR_POINT(p[4], r0, 0);
GEAR_POINT(p[5], r1, 4);
GEAR_POINT(p[6], r0, 4);
/* Front face */
START_STRIP;
SET_NORMAL(0, 0, 1.0);
v = GEAR_VERT(v, 0, +1);
v = GEAR_VERT(v, 1, +1);
v = GEAR_VERT(v, 2, +1);
v = GEAR_VERT(v, 3, +1);
v = GEAR_VERT(v, 4, +1);
v = GEAR_VERT(v, 5, +1);
v = GEAR_VERT(v, 6, +1);
END_STRIP;
/* Inner face */
START_STRIP;
QUAD_WITH_NORMAL(4, 6);
END_STRIP;
/* Back face */
START_STRIP;
SET_NORMAL(0, 0, -1.0);
v = GEAR_VERT(v, 6, -1);
v = GEAR_VERT(v, 5, -1);
v = GEAR_VERT(v, 4, -1);
v = GEAR_VERT(v, 3, -1);
v = GEAR_VERT(v, 2, -1);
v = GEAR_VERT(v, 1, -1);
v = GEAR_VERT(v, 0, -1);
END_STRIP;
/* Outer face */
START_STRIP;
QUAD_WITH_NORMAL(0, 2);
END_STRIP;
START_STRIP;
QUAD_WITH_NORMAL(1, 0);
END_STRIP;
START_STRIP;
QUAD_WITH_NORMAL(3, 1);
END_STRIP;
START_STRIP;
QUAD_WITH_NORMAL(5, 3);
END_STRIP;
}
gear->nvertices = (v - gear->vertices);
return gear;
}
/**
* Multiplies two 4x4 matrices.
*
* The result is stored in matrix m.
*
* @param m the first matrix to multiply
* @param n the second matrix to multiply
*/
static void
multiply (GLfloat *m, const GLfloat *n)
{
GLfloat tmp[16];
const GLfloat *row, *column;
div_t d;
int i, j;
for (i = 0; i < 16; i++) {
tmp[i] = 0;
d = div(i, 4);
row = n + d.quot * 4;
column = m + d.rem;
for (j = 0; j < 4; j++)
tmp[i] += row[j] * column[j * 4];
}
memcpy(m, &tmp, sizeof tmp);
}
/**
* Rotates a 4x4 matrix.
*
* @param[in,out] m the matrix to rotate
* @param angle the angle to rotate
* @param x the x component of the direction to rotate to
* @param y the y component of the direction to rotate to
* @param z the z component of the direction to rotate to
*/
static void
rotate(GLfloat *m, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
{
double s = sin (angle);
double c = cos (angle);
GLfloat r[16] = {
x * x * (1 - c) + c, y * x * (1 - c) + z * s, x * z * (1 - c) - y * s, 0,
x * y * (1 - c) - z * s, y * y * (1 - c) + c, y * z * (1 - c) + x * s, 0,
x * z * (1 - c) + y * s, y * z * (1 - c) - x * s, z * z * (1 - c) + c, 0,
0, 0, 0, 1
};
multiply(m, r);
}
/**
* Translates a 4x4 matrix.
*
* @param[in,out] m the matrix to translate
* @param x the x component of the direction to translate to
* @param y the y component of the direction to translate to
* @param z the z component of the direction to translate to
*/
static void
translate(GLfloat *m, GLfloat x, GLfloat y, GLfloat z)
{
GLfloat t[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1 };
multiply(m, t);
}
/**
* Creates an identity 4x4 matrix.
*
* @param m the matrix make an identity matrix
*/
static void
identity(GLfloat *m)
{
GLfloat t[16] = {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
};
memcpy(m, t, sizeof(t));
}
/**
* Transposes a 4x4 matrix.
*
* @param m the matrix to transpose
*/
static void
transpose(GLfloat *m)
{
GLfloat t[16] = {
m[0], m[4], m[8], m[12],
m[1], m[5], m[9], m[13],
m[2], m[6], m[10], m[14],
m[3], m[7], m[11], m[15]};
memcpy(m, t, sizeof(t));
}
/**
* Inverts a 4x4 matrix.
*
* This function can currently handle only pure translation-rotation matrices.
* Read http://www.gamedev.net/community/forums/topic.asp?topic_id=425118
* for an explanation.
*/
static void
invert(GLfloat *m)
{
GLfloat t[16];
identity(t);
// Extract and invert the translation part 't'. The inverse of a
// translation matrix can be calculated by negating the translation
// coordinates.
t[12] = -m[12]; t[13] = -m[13]; t[14] = -m[14];
// Invert the rotation part 'r'. The inverse of a rotation matrix is
// equal to its transpose.
m[12] = m[13] = m[14] = 0;
transpose(m);
// inv(m) = inv(r) * inv(t)
multiply(m, t);
}
/**
* Calculate a perspective projection transformation.
*
* @param m the matrix to save the transformation in
* @param fovy the field of view in the y direction
* @param aspect the view aspect ratio
* @param zNear the near clipping plane
* @param zFar the far clipping plane
*/
void perspective(GLfloat *m, GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar)
{
GLfloat tmp[16];
double sine, cosine, cotangent, deltaZ;
GLfloat radians = fovy / 2 * M_PI / 180;
identity(tmp);
deltaZ = zFar - zNear;
sincos(radians, &sine, &cosine);
if ((deltaZ == 0) || (sine == 0) || (aspect == 0))
return;
cotangent = cosine / sine;
tmp[0] = cotangent / aspect;
tmp[5] = cotangent;
tmp[10] = -(zFar + zNear) / deltaZ;
tmp[11] = -1;
tmp[14] = -2 * zNear * zFar / deltaZ;
tmp[15] = 0;
memcpy(m, tmp, sizeof(tmp));
}
/**
* Draws a gear.
*
* @param gear the gear to draw
* @param transform the current transformation matrix
* @param x the x position to draw the gear at
* @param y the y position to draw the gear at
* @param angle the rotation angle of the gear
* @param color the color of the gear
*/
static void
draw_gear(GtkGears *self,
struct gear *gear,
GLuint gear_vbo,
GLfloat *transform,
GLfloat x,
GLfloat y,
GLfloat angle,
const GLfloat color[4])
{
GtkGearsPrivate *priv = gtk_gears_get_instance_private (self);
GLfloat model_view[16];
GLfloat normal_matrix[16];
GLfloat model_view_projection[16];
int n;
/* Translate and rotate the gear */
memcpy(model_view, transform, sizeof (model_view));
translate(model_view, x, y, 0);
rotate(model_view, 2 * G_PI * angle / 360.0, 0, 0, 1);
/* Create and set the ModelViewProjectionMatrix */
memcpy(model_view_projection, priv->ProjectionMatrix, sizeof(model_view_projection));
multiply(model_view_projection, model_view);
glUniformMatrix4fv(priv->ModelViewProjectionMatrix_location, 1, GL_FALSE,
model_view_projection);
/*
* Create and set the NormalMatrix. It's the inverse transpose of the
* ModelView matrix.
*/
memcpy(normal_matrix, model_view, sizeof (normal_matrix));
invert(normal_matrix);
transpose(normal_matrix);
glUniformMatrix4fv(priv->NormalMatrix_location, 1, GL_FALSE, normal_matrix);
/* Set the gear color */
glUniform4fv(priv->MaterialColor_location, 1, color);
/* Set the vertex buffer object to use */
glBindBuffer(GL_ARRAY_BUFFER, gear_vbo);
/* Set up the position of the attributes in the vertex buffer object */
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), NULL);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLfloat *) 0 + 3);
/* Enable the attributes */
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
/* Draw the triangle strips that comprise the gear */
for (n = 0; n < gear->nstrips; n++) {
glDrawArrays(GL_TRIANGLE_STRIP, gear->strips[n].first, gear->strips[n].count);
}
/* Disable the attributes */
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
}
/* new window size or exposure */
static void
gtk_gears_reshape (GtkGLArea *area, int width, int height)
{
GtkGearsPrivate *priv = gtk_gears_get_instance_private ((GtkGears *) area);
/* Update the projection matrix */
perspective (priv->ProjectionMatrix, 60.0, width / (float)height, 1.0, 1024.0);
/* Set the viewport */
glViewport (0, 0, (GLint) width, (GLint) height);
}
static gboolean
gtk_gears_render (GtkGLArea *area,
GdkGLContext *context)
{
static const GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
static const GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
static const GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
GtkGears *self = GTK_GEARS (area);
GtkGearsPrivate *priv = gtk_gears_get_instance_private (self);
GLfloat transform[16];
identity (transform);
glClearColor (0.0, 0.0, 0.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* Translate and rotate the view */
translate (transform, 0, 0, -20);
rotate (transform, 2 * G_PI * priv->view_rot[0] / 360.0, 1, 0, 0);
rotate (transform, 2 * G_PI * priv->view_rot[1] / 360.0, 0, 1, 0);
rotate (transform, 2 * G_PI * priv->view_rot[2] / 360.0, 0, 0, 1);
/* Draw the gears */
draw_gear (self, priv->gear1, priv->gear_vbo[0], transform, -3.0, -2.0, priv->angle, red);
draw_gear (self, priv->gear2, priv->gear_vbo[1], transform, 3.1, -2.0, -2 * priv->angle - 9.0, green);
draw_gear (self, priv->gear3, priv->gear_vbo[2], transform, -3.1, 4.2, -2 * priv->angle - 25.0, blue);
return TRUE;
}
static const char vertex_shader_gl[] =
"#version 150\n"
"\n"
"in vec3 position;\n"
"in vec3 normal;\n"
"\n"
"uniform mat4 ModelViewProjectionMatrix;\n"
"uniform mat4 NormalMatrix;\n"
"uniform vec4 LightSourcePosition;\n"
"uniform vec4 MaterialColor;\n"
"\n"
"smooth out vec4 Color;\n"
"\n"
"void main(void)\n"
"{\n"
" // Transform the normal to eye coordinates\n"
" vec3 N = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));\n"
"\n"
" // The LightSourcePosition is actually its direction for directional light\n"
" vec3 L = normalize(LightSourcePosition.xyz);\n"
"\n"
" // Multiply the diffuse value by the vertex color (which is fixed in this case)\n"
" // to get the actual color that we will use to draw this vertex with\n"
" float diffuse = max(dot(N, L), 0.0);\n"
" Color = diffuse * MaterialColor;\n"
"\n"
" // Transform the position to clip coordinates\n"
" gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);\n"
"}";
static const char fragment_shader_gl[] =
"#version 150\n"
"\n"
"smooth in vec4 Color;\n"
"\n"
"void main(void)\n"
"{\n"
" gl_FragColor = Color;\n"
"}";
static const char vertex_shader_gles[] =
"attribute vec3 position;\n"
"attribute vec3 normal;\n"
"\n"
"uniform mat4 ModelViewProjectionMatrix;\n"
"uniform mat4 NormalMatrix;\n"
"uniform vec4 LightSourcePosition;\n"
"uniform vec4 MaterialColor;\n"
"\n"
"varying vec4 Color;\n"
"\n"
"void main(void)\n"
"{\n"
" // Transform the normal to eye coordinates\n"
" vec3 N = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));\n"
"\n"
" // The LightSourcePosition is actually its direction for directional light\n"
" vec3 L = normalize(LightSourcePosition.xyz);\n"
"\n"
" // Multiply the diffuse value by the vertex color (which is fixed in this case)\n"
" // to get the actual color that we will use to draw this vertex with\n"
" float diffuse = max(dot(N, L), 0.0);\n"
" Color = diffuse * MaterialColor;\n"
"\n"
" // Transform the position to clip coordinates\n"
" gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);\n"
"}";
static const char fragment_shader_gles[] =
"precision mediump float;\n"
"varying vec4 Color;\n"
"\n"
"void main(void)\n"
"{\n"
" gl_FragColor = Color;\n"
"}";
static void
gtk_gears_realize (GtkWidget *widget)
{
GtkGLArea *glarea = GTK_GL_AREA (widget);
GtkGears *gears = GTK_GEARS (widget);
GtkGearsPrivate *priv = gtk_gears_get_instance_private (gears);
GdkGLContext *context;
GLuint vao, v, f, program;
const char *p;
char msg[512];
GTK_WIDGET_CLASS (gtk_gears_parent_class)->realize (widget);
gtk_gl_area_make_current (glarea);
if (gtk_gl_area_get_error (glarea) != NULL)
return;
context = gtk_gl_area_get_context (glarea);
glEnable (GL_CULL_FACE);
glEnable (GL_DEPTH_TEST);
/* Create the VAO */
glGenVertexArrays (1, &vao);
glBindVertexArray (vao);
priv->vao = vao;
/* Compile the vertex shader */
if (gdk_gl_context_get_use_es (context))
p = vertex_shader_gles;
else
p = vertex_shader_gl;
v = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(v, 1, &p, NULL);
glCompileShader(v);
glGetShaderInfoLog(v, sizeof msg, NULL, msg);
g_print ("vertex shader info: %s\n", msg);
/* Compile the fragment shader */
if (gdk_gl_context_get_use_es (context))
p = fragment_shader_gles;
else
p = fragment_shader_gl;
f = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(f, 1, &p, NULL);
glCompileShader(f);
glGetShaderInfoLog(f, sizeof msg, NULL, msg);
g_print ("fragment shader info: %s\n", msg);
/* Create and link the shader program */
program = glCreateProgram();
glAttachShader(program, v);
glAttachShader(program, f);
glBindAttribLocation(program, 0, "position");
glBindAttribLocation(program, 1, "normal");
glLinkProgram(program);
glGetProgramInfoLog(program, sizeof msg, NULL, msg);
g_print ("program info: %s\n", msg);
glDeleteShader (v);
glDeleteShader (f);
/* Enable the shaders */
glUseProgram(program);
priv->program = program;
/* Get the locations of the uniforms so we can access them */
priv->ModelViewProjectionMatrix_location = glGetUniformLocation(program, "ModelViewProjectionMatrix");
priv->NormalMatrix_location = glGetUniformLocation(program, "NormalMatrix");
priv->LightSourcePosition_location = glGetUniformLocation(program, "LightSourcePosition");
priv->MaterialColor_location = glGetUniformLocation(program, "MaterialColor");
/* Set the LightSourcePosition uniform which is constant throught the program */
glUniform4fv(priv->LightSourcePosition_location, 1, priv->LightSourcePosition);
/* make the gears */
priv->gear1 = create_gear(1.0, 4.0, 1.0, 20, 0.7);
/* Store the vertices in a vertex buffer object (VBO) */
glGenBuffers (1, &(priv->gear_vbo[0]));
glBindBuffer (GL_ARRAY_BUFFER, priv->gear_vbo[0]);
glBufferData (GL_ARRAY_BUFFER,
priv->gear1->nvertices * sizeof(GearVertex),
priv->gear1->vertices,
GL_STATIC_DRAW);
priv->gear2 = create_gear(0.5, 2.0, 2.0, 10, 0.7);
glGenBuffers (1, &(priv->gear_vbo[1]));
glBindBuffer (GL_ARRAY_BUFFER, priv->gear_vbo[1]);
glBufferData (GL_ARRAY_BUFFER,
priv->gear2->nvertices * sizeof(GearVertex),
priv->gear2->vertices,
GL_STATIC_DRAW);
priv->gear3 = create_gear(1.3, 2.0, 0.5, 10, 0.7);
glGenBuffers (1, &(priv->gear_vbo[2]));
glBindBuffer (GL_ARRAY_BUFFER, priv->gear_vbo[2]);
glBufferData (GL_ARRAY_BUFFER,
priv->gear3->nvertices * sizeof(GearVertex),
priv->gear3->vertices,
GL_STATIC_DRAW);
}
static void
gtk_gears_unrealize (GtkWidget *widget)
{
GtkGLArea *glarea = GTK_GL_AREA (widget);
GtkGearsPrivate *priv = gtk_gears_get_instance_private ((GtkGears *) widget);
gtk_gl_area_make_current (glarea);
if (gtk_gl_area_get_error (glarea) != NULL)
return;
/* Release the resources associated with OpenGL */
if (priv->gear_vbo[0] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[0]));
if (priv->gear_vbo[1] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[1]));
if (priv->gear_vbo[2] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[2]));
if (priv->vao != 0)
glDeleteVertexArrays (1, &priv->vao);
if (priv->program != 0)
glDeleteProgram (priv->program);
priv->ModelViewProjectionMatrix_location = 0;
priv->NormalMatrix_location = 0;
priv->LightSourcePosition_location = 0;
priv->MaterialColor_location = 0;
GTK_WIDGET_CLASS (gtk_gears_parent_class)->unrealize (widget);
}
static gboolean
gtk_gears_tick (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GtkGears *gears = GTK_GEARS (widget);
GtkGearsPrivate *priv = gtk_gears_get_instance_private (gears);
GdkFrameTimings *timings, *previous_timings;
gint64 previous_frame_time = 0;
gint64 frame_time;
gint64 history_start, history_len;
gint64 frame;
char *s;
frame = gdk_frame_clock_get_frame_counter (frame_clock);
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
if (priv->first_frame_time == 0)
{
/* No need for changes on first frame */
priv->first_frame_time = frame_time;
if (priv->fps_label)
gtk_label_set_label (priv->fps_label, "FPS: ---");
return G_SOURCE_CONTINUE;
}
/* glxgears advances 70 degrees per second, so do the same */
priv->angle = fmod ((frame_time - priv->first_frame_time) / (double)G_USEC_PER_SEC * 70.0, 360.0);
gtk_widget_queue_draw (widget);
history_start = gdk_frame_clock_get_history_start (frame_clock);
if (priv->fps_label && frame % 60 == 0)
{
history_len = frame - history_start;
if (history_len > 0)
{
previous_timings = gdk_frame_clock_get_timings (frame_clock, frame - history_len);
previous_frame_time = gdk_frame_timings_get_frame_time (previous_timings);
s = g_strdup_printf ("FPS: %-4.1f", (G_USEC_PER_SEC * history_len) / (double)(frame_time - previous_frame_time));
gtk_label_set_label (priv->fps_label, s);
g_free (s);
}
}
timings = gdk_frame_clock_get_current_timings (frame_clock);
previous_timings = gdk_frame_clock_get_timings (frame_clock,
gdk_frame_timings_get_frame_counter (timings) - 1);
if (previous_timings != NULL)
previous_frame_time = gdk_frame_timings_get_frame_time (previous_timings);
return G_SOURCE_CONTINUE;
}
void
gtk_gears_set_axis (GtkGears *gears, int axis, double value)
{
GtkGearsPrivate *priv = gtk_gears_get_instance_private (gears);
if (axis < 0 || axis >= GTK_GEARS_N_AXIS)
return;
priv->view_rot[axis] = value;
gtk_widget_queue_draw (GTK_WIDGET (gears));
}
double
gtk_gears_get_axis (GtkGears *gears, int axis)
{
GtkGearsPrivate *priv = gtk_gears_get_instance_private (gears);
if (axis < 0 || axis >= GTK_GEARS_N_AXIS)
return 0.0;
return priv->view_rot[axis];
}
void
gtk_gears_set_fps_label (GtkGears *gears, GtkLabel *label)
{
GtkGearsPrivate *priv = gtk_gears_get_instance_private (gears);
if (label)
g_object_ref (label);
g_clear_object (&priv->fps_label);
priv->fps_label = label;
}

View File

@@ -1,48 +0,0 @@
#ifndef __GTK_GEARS_H__
#define __GTK_GEARS_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
enum {
GTK_GEARS_X_AXIS,
GTK_GEARS_Y_AXIS,
GTK_GEARS_Z_AXIS,
GTK_GEARS_N_AXIS
};
#define GTK_TYPE_GEARS (gtk_gears_get_type ())
#define GTK_GEARS(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
GTK_TYPE_GEARS, \
GtkGears))
#define GTK_IS_GEARS(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
GTK_TYPE_GEARS))
typedef struct _GtkGears GtkGears;
typedef struct _GtkGearsClass GtkGearsClass;
struct _GtkGears {
GtkGLArea parent;
};
struct _GtkGearsClass {
GtkGLAreaClass parent_class;
};
GType gtk_gears_get_type (void) G_GNUC_CONST;
GtkWidget *gtk_gears_new (void);
void gtk_gears_set_axis (GtkGears *gears,
int axis,
double value);
double gtk_gears_get_axis (GtkGears *gears,
int axis);
void gtk_gears_set_fps_label (GtkGears *gears,
GtkLabel *label);
G_END_DECLS
#endif /* __GTK_GEARS_H__ */

View File

@@ -105,14 +105,14 @@ follow_if_link (GtkWidget *text_view,
/* Links can be activated by pressing Enter. /* Links can be activated by pressing Enter.
*/ */
static gboolean static gboolean
key_pressed (GtkEventController *controller, key_press_event (GtkWidget *text_view,
guint keyval, GdkEventKey *event)
guint keycode,
GdkModifierType modifiers,
GtkWidget *text_view)
{ {
GtkTextIter iter; GtkTextIter iter;
GtkTextBuffer *buffer; GtkTextBuffer *buffer;
guint keyval;
gdk_event_get_keyval ((GdkEvent *)event, &keyval);
switch (keyval) switch (keyval)
{ {
@@ -128,49 +128,54 @@ key_pressed (GtkEventController *controller,
break; break;
} }
return GDK_EVENT_PROPAGATE; return FALSE;
} }
static void set_cursor_if_appropriate (GtkTextView *text_view, /* Links can also be activated by clicking or tapping.
gint x, */
gint y); static gboolean
event_after (GtkWidget *text_view,
static void GdkEvent *ev)
released_cb (GtkGestureMultiPress *gesture,
guint n_press,
gdouble x,
gdouble y,
GtkWidget *text_view)
{ {
GtkTextIter start, end, iter; GtkTextIter start, end, iter;
GtkTextBuffer *buffer; GtkTextBuffer *buffer;
int tx, ty; gdouble ex, ey;
int x, y;
GdkEventType type;
if (gtk_gesture_single_get_button (GTK_GESTURE_SINGLE (gesture)) > 1) type = gdk_event_get_event_type (ev);
return;
gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), if (type == GDK_BUTTON_RELEASE)
GTK_TEXT_WINDOW_WIDGET, {
x, y, &tx, &ty); guint button;
gdk_event_get_button (ev, &button);
if (button != GDK_BUTTON_PRIMARY)
return FALSE;
}
else if (type == GDK_TOUCH_END)
{
}
else
return FALSE;
gdk_event_get_coords (ev, &ex, &ey);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
/* we shouldn't follow a link if the user has selected something */ /* we shouldn't follow a link if the user has selected something */
gtk_text_buffer_get_selection_bounds (buffer, &start, &end); gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end)) if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
return; return FALSE;
gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
GTK_TEXT_WINDOW_WIDGET,
ex, ey, &x, &y);
if (gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y)) if (gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y))
follow_if_link (text_view, &iter); follow_if_link (text_view, &iter);
}
static void return TRUE;
motion_cb (GtkEventControllerMotion *controller,
gdouble x,
gdouble y,
GtkTextView *text_view)
{
set_cursor_if_appropriate (text_view, x, y);
} }
static gboolean hovering_over_link = FALSE; static gboolean hovering_over_link = FALSE;
@@ -218,6 +223,25 @@ set_cursor_if_appropriate (GtkTextView *text_view,
g_slist_free (tags); g_slist_free (tags);
} }
/* Update the cursor image if the pointer moved.
*/
static gboolean
motion_notify_event (GtkWidget *text_view,
GdkEventMotion *event)
{
gdouble ex, ey;
gint x, y;
gdk_event_get_coords ((GdkEvent *)event, &ex, &ey);
gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
GTK_TEXT_WINDOW_WIDGET,
ex, ey, &x, &y);
set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y);
return FALSE;
}
GtkWidget * GtkWidget *
do_hypertext (GtkWidget *do_widget) do_hypertext (GtkWidget *do_widget)
{ {
@@ -228,7 +252,6 @@ do_hypertext (GtkWidget *do_widget)
GtkWidget *view; GtkWidget *view;
GtkWidget *sw; GtkWidget *sw;
GtkTextBuffer *buffer; GtkTextBuffer *buffer;
GtkEventController *controller;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL); window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Hypertext"); gtk_window_set_title (GTK_WINDOW (window), "Hypertext");
@@ -243,19 +266,12 @@ do_hypertext (GtkWidget *do_widget)
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD); gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 20); gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 20);
gtk_text_view_set_right_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 (view, "key-press-event",
g_signal_connect (controller, "key-pressed", G_CALLBACK (key_pressed), view); G_CALLBACK (key_press_event), NULL);
gtk_widget_add_controller (view, controller); g_signal_connect (view, "event-after",
G_CALLBACK (event_after), NULL);
controller = GTK_EVENT_CONTROLLER (gtk_gesture_multi_press_new ()); g_signal_connect (view, "motion-notify-event",
g_signal_connect (controller, "released", G_CALLBACK (motion_notify_event), NULL);
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);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));

Binary file not shown.

Before

Width:  |  Height:  |  Size: 659 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 459 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 682 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 845 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 239 B

View File

@@ -266,7 +266,7 @@ do_iconview (GtkWidget *do_widget)
gtk_container_add (GTK_CONTAINER (window), vbox); gtk_container_add (GTK_CONTAINER (window), vbox);
tool_bar = gtk_toolbar_new (); 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); up_button = gtk_tool_button_new (NULL, NULL);
gtk_tool_button_set_label (GTK_TOOL_BUTTON (up_button), _("_Up")); gtk_tool_button_set_label (GTK_TOOL_BUTTON (up_button), _("_Up"));
@@ -292,7 +292,7 @@ do_iconview (GtkWidget *do_widget)
GTK_POLICY_AUTOMATIC); GTK_POLICY_AUTOMATIC);
gtk_widget_set_vexpand (sw, TRUE); 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 '/' */ /* Create the store and fill it with the contents of '/' */
parent = g_strdup ("/"); parent = g_strdup ("/");

View File

@@ -1,15 +1,15 @@
/* Images /* Images
* *
* GtkImage and GtkPicture are used to display an image; the image can be * GtkImage is used to display an image; the image can be in a number of formats.
* in a number of formats. * Typically, you load an image into a GdkPixbuf, then display the pixbuf.
*
* 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.
* *
* This demo code shows some of the more obscure cases, in the simple * This demo code shows some of the more obscure cases, in the simple
* case a call to gtk_picture_new_for_file() or * case a call to gtk_image_new_from_file() is all you need.
* gtk_image_new_from_icon_name() 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> #include <gtk/gtk.h>
@@ -27,9 +27,9 @@ progressive_prepared_callback (GdkPixbufLoader *loader,
gpointer data) gpointer data)
{ {
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
GtkWidget *picture; GtkWidget *image;
picture = GTK_WIDGET (data); image = GTK_WIDGET (data);
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
@@ -38,7 +38,7 @@ progressive_prepared_callback (GdkPixbufLoader *loader,
*/ */
gdk_pixbuf_fill (pixbuf, 0xaaaaaaff); gdk_pixbuf_fill (pixbuf, 0xaaaaaaff);
gtk_picture_set_pixbuf (GTK_PICTURE (picture), pixbuf); gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
} }
static void static void
@@ -49,21 +49,21 @@ progressive_updated_callback (GdkPixbufLoader *loader,
gint height, gint height,
gpointer data) gpointer data)
{ {
GtkWidget *picture; GtkWidget *image;
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
picture = GTK_WIDGET (data); image = GTK_WIDGET (data);
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); 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 static gint
progressive_timeout (gpointer data) 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. /* This shows off fully-paranoid error handling, so looks scary.
* You could factor out the error handling code into a nice separate * 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 (); pixbuf_loader = gdk_pixbuf_loader_new ();
g_signal_connect (pixbuf_loader, "area-prepared", 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_signal_connect (pixbuf_loader, "area-updated",
G_CALLBACK (progressive_updated_callback), picture); G_CALLBACK (progressive_updated_callback), image);
} }
/* leave timeout installed */ /* leave timeout installed */
@@ -252,7 +252,7 @@ progressive_timeout (gpointer data)
} }
static void static void
start_progressive_loading (GtkWidget *picture) start_progressive_loading (GtkWidget *image)
{ {
/* This is obviously totally contrived (we slow down loading /* This is obviously totally contrived (we slow down loading
* on purpose to show how incremental loading works). * on purpose to show how incremental loading works).
@@ -261,8 +261,10 @@ start_progressive_loading (GtkWidget *picture)
* The timeout simply simulates a slow data source by inserting * The timeout simply simulates a slow data source by inserting
* pauses in the reading process. * pauses in the reading process.
*/ */
load_timeout = g_timeout_add (150, progressive_timeout, picture); load_timeout = gdk_threads_add_timeout (150,
g_source_set_name_by_id (load_timeout, "[gtk] progressive_timeout"); progressive_timeout,
image);
g_source_set_name_by_id (load_timeout, "[gtk+] progressive_timeout");
} }
static void static void
@@ -317,17 +319,12 @@ toggle_sensitivity_callback (GtkWidget *togglebutton,
GtkWidget * GtkWidget *
do_images (GtkWidget *do_widget) do_images (GtkWidget *do_widget)
{ {
GtkWidget *video;
GtkWidget *frame; GtkWidget *frame;
GtkWidget *vbox; GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *base_vbox;
GtkWidget *image; GtkWidget *image;
GtkWidget *picture;
GtkWidget *label; GtkWidget *label;
GtkWidget *button; GtkWidget *button;
GdkPaintable *paintable; GIcon *gicon;
GIcon *gicon;
if (!window) if (!window)
{ {
@@ -341,26 +338,20 @@ do_images (GtkWidget *do_widget)
g_signal_connect (window, "destroy", g_signal_connect (window, "destroy",
G_CALLBACK (cleanup_callback), NULL); G_CALLBACK (cleanup_callback), NULL);
base_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
g_object_set (base_vbox, "margin", 16, NULL);
gtk_container_add (GTK_CONTAINER (window), base_vbox);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 16);
gtk_container_add (GTK_CONTAINER (base_vbox), hbox);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8); vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
gtk_container_add (GTK_CONTAINER (hbox), vbox); g_object_set (vbox, "margin", 16, NULL);
gtk_container_add (GTK_CONTAINER (window), vbox);
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"<u>Image loaded from a file</u>"); "<u>Image loaded from a file</u>");
gtk_container_add (GTK_CONTAINER (vbox), label); gtk_box_pack_start (GTK_BOX (vbox), label);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER); gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER); gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
gtk_container_add (GTK_CONTAINER (vbox), frame); gtk_box_pack_start (GTK_BOX (vbox), frame);
image = gtk_image_new_from_icon_name ("gtk3-demo"); image = gtk_image_new_from_icon_name ("gtk3-demo");
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE); gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
@@ -373,30 +364,30 @@ do_images (GtkWidget *do_widget)
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"<u>Animation loaded from a file</u>"); "<u>Animation loaded from a file</u>");
gtk_container_add (GTK_CONTAINER (vbox), label); gtk_box_pack_start (GTK_BOX (vbox), label);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER); gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER); gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
gtk_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 */ /* Symbolic icon */
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"<u>Symbolic themed icon</u>"); "<u>Symbolic themed icon</u>");
gtk_container_add (GTK_CONTAINER (vbox), label); gtk_box_pack_start (GTK_BOX (vbox), label);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER); gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER); gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
gtk_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"); gicon = g_themed_icon_new_with_default_fallbacks ("battery-caution-charging-symbolic");
image = gtk_image_new_from_gicon (gicon); image = gtk_image_new_from_gicon (gicon);
@@ -406,69 +397,33 @@ do_images (GtkWidget *do_widget)
/* Progressive */ /* Progressive */
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
gtk_container_add (GTK_CONTAINER (hbox), vbox);
label = gtk_label_new (NULL); label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label), gtk_label_set_markup (GTK_LABEL (label),
"<u>Progressive image loading</u>"); "<u>Progressive image loading</u>");
gtk_container_add (GTK_CONTAINER (vbox), label); gtk_box_pack_start (GTK_BOX (vbox), label);
frame = gtk_frame_new (NULL); frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_widget_set_halign (frame, GTK_ALIGN_CENTER); gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
gtk_widget_set_valign (frame, GTK_ALIGN_CENTER); gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
gtk_container_add (GTK_CONTAINER (vbox), frame); gtk_box_pack_start (GTK_BOX (vbox), frame);
/* Create an empty image for now; the progressive loader /* Create an empty image for now; the progressive loader
* will create the pixbuf and fill it in. * will create the pixbuf and fill it in.
*/ */
picture = gtk_picture_new (); image = gtk_image_new_from_pixbuf (NULL);
gtk_container_add (GTK_CONTAINER (frame), picture); gtk_container_add (GTK_CONTAINER (frame), image);
start_progressive_loading (picture); start_progressive_loading (image);
/* Video */
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>Displaying video</u>");
gtk_container_add (GTK_CONTAINER (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);
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 */ /* Sensitivity control */
button = gtk_toggle_button_new_with_mnemonic ("_Insensitive"); button = gtk_toggle_button_new_with_mnemonic ("_Insensitive");
gtk_container_add (GTK_CONTAINER (base_vbox), button); gtk_box_pack_start (GTK_BOX (vbox), button);
g_signal_connect (button, "toggled", g_signal_connect (button, "toggled",
G_CALLBACK (toggle_sensitivity_callback), G_CALLBACK (toggle_sensitivity_callback),
base_vbox); vbox);
} }
if (!gtk_widget_get_visible (window)) if (!gtk_widget_get_visible (window))

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