Compare commits

..

55 Commits

Author SHA1 Message Date
Matthias Clasen
f3d8055722 glyphy: Add a few comments
Make this a bit more understandable.
2023-07-18 13:51:45 -04:00
Matthias Clasen
330fd220ad gsk: Make glyphy opt-in for now
Set GSK_DEBUG=glyphy in the environment
to try out font rendering with glyphy.

Keeping this optional will make it easier to
debug issues and compare output.

We may want to flip it to opt-out at some point.
2023-07-18 13:51:45 -04:00
Matthias Clasen
fbc8996830 Add an animated text example 2023-07-18 13:51:45 -04:00
Matthias Clasen
fb65628e9f Add a font rendering test 2023-07-18 13:51:44 -04:00
Matthias Clasen
4ca8911d2a glyphy: Implement synthetic italic
Use the font matrix found in the FcPattern to
transform the quads we use to render the glyphs.

This makes Cantarell Italic come out just like
it does with freetype.
2023-07-18 13:51:15 -04:00
Matthias Clasen
86481ebb91 glyphy: Update for api changes in glyphy
With this, synthetic bold fonts work as well
as they do with freetype.
2023-07-18 13:51:15 -04:00
Matthias Clasen
1c72bee109 glyphy: Implement synthetic bold
When the font appears to be synthetic bold (as
indicated by th embolden property in FcPattern),
use glyphys boldness uniform to render the font
bolder.
2023-07-18 13:51:15 -04:00
Matthias Clasen
4d9ee3883f glyphy: Remove glyphy debug code
We don't have a knob to turn this on, and it is
not really useful outside of glyphy itself, so
remove it.
2023-07-18 13:51:15 -04:00
Matthias Clasen
c0ec993f12 glyphy: Simplify the path
Use path ops to simplify the path we get from
harfbuzz, since variable fonts often have overlapping
contours, and the glyphy shader can't handle those.
2023-07-18 13:51:15 -04:00
Matthias Clasen
db7f38e550 build: Bump the harfbuzz requirement to 4.0
The hb_font_get_glyph_shape api was introduced
in 4.0.
2023-07-18 13:51:15 -04:00
Matthias Clasen
59e4f7b0da glyphy: Pencil in outline rendering 2023-07-18 13:51:15 -04:00
Christian Hergert
b7d9dbf6a5 gsk/gl: Fix output color of glyphy fragment shader
This copied more or less what the coloring vertex shader
was doing in that we premultiply alpha. That changes how
we apply alpha in the fragment shader to match.

This fixes a white halo around the fonts.
2023-07-18 13:51:15 -04:00
Matthias Clasen
09caa0632f glyphy: Make glyphy cache size-independent
Use a hb font at nominal size when generating sdf
contours, and use a cache key that is independent
of the size.
2023-07-18 13:51:15 -04:00
Christian Hergert
adcef23069 gsk/gl: Start on basic glyphy renderjob integration
This doesn't work correctly yet, as there are lots of
bumps along the way to still smooth out.
2023-07-18 13:51:15 -04:00
Christian Hergert
30b5186177 gsk/gl: Add a texture library for Glyphy
This adds a new texture library that can upload SDF data
from libglyphy into regions of a texture atlas so that it
can be accessed by Glyphy shaders in the appropriate place
and format.

Some of the placement positioning may seem odd in that it
needs to follow a certain format to be decoded from the
Glyphy shaders.
2023-07-18 13:51:15 -04:00
Christian Hergert
7020211944 gsk/gl: Dispatch text_node to legacy vs glyphy
If the text node has color glyphs, then we need to dispatch
to the legacy form of rendering which uses FreeType/Cairo/etc
to upload glyphs to a rendered glyph cache.

Otherwise, we can dispatch to a new function which will
eventually use Glyphy to shape to SDF content and upload
to an alternate texture atlas.
2023-07-18 13:51:15 -04:00
Matthias Clasen
a1c76751ab build: Add a dependency on glyphy
We have a subproject, and we link statically
if we can, to avoid depending on a project
that is not generally packaged in distros.
2023-07-18 13:51:15 -04:00
Matthias Clasen
3d33636795 ci: Add glut and glew to Fedora image
glyphy requires these.
2023-07-18 13:51:15 -04:00
Matthias Clasen
d116a04a9d tools: Add more commands to gtk4-path-tool
Add pathops.
2023-07-08 20:47:09 -04:00
Matthias Clasen
7c90961174 gtk-demo: Add a demo for path ops
This demo is called Glyphs, since that is what
it works with.
2023-07-08 20:47:09 -04:00
Matthias Clasen
a767a0495f Add API for boolean operations on paths
The new APIs here are:
gsk_path_union
gsk_path_intersection
gsk_path_difference
gsk_path_symmetric_difference
gsk_path_simplify
2023-07-08 20:46:53 -04:00
Matthias Clasen
a2c35d8682 Implement boolean operations on paths
Implement union, intersection, difference and
symmetric difference of two paths, as well as
simplification of a single path.
2023-07-08 20:45:42 -04:00
Matthias Clasen
0e6da01d05 gsk: Add gsk_stroke_node_get_stroke_path
We will implement stroking by filling the stroke path.

Compute the stroke path ahead of time, so we don't have
to do it over and over.

This may change in the future, at least for simple
strokes, so keep this private.
2023-07-08 20:44:37 -04:00
Matthias Clasen
ea28b804ce gtk-demo: Add a curve editor demo
This demo is called Curve, for obvious reasons.
2023-07-08 20:44:37 -04:00
Matthias Clasen
4a000213cd gtk-demo: Add a few path benchmarks
The Tiger and Graph examples in the fishbowl test
path handling.
2023-07-08 20:44:37 -04:00
Matthias Clasen
33c5dbf8c6 Add a gallery of tough strokes
Each of these defeated the stroker at some point.
2023-07-08 20:44:37 -04:00
Matthias Clasen
e2e6e6a8e5 Add an interactive path test
This one is for interactive exploring of svg paths.

You can enter an SVG path in the entry and hit Enter
to see how GSK renders it. If you click the button
in the headerbar, you can see what GTK thinks the
closest point, tangent and distance are wrt. to the
mouse position, and the bounding box of the path.

There's also stroke parameters to play with.
2023-07-08 20:44:37 -04:00
Matthias Clasen
124b76e6da tools: Add more commands to gtk4-path-tool
Add stroking and offsetting.
2023-07-08 20:44:37 -04:00
Matthias Clasen
fd714fb8be Add gsk_path_offset
Add a function that takes a path, and offsets it
by some distance, applying line-join parameters
as needed. The implementation is reusing the
infrastructure of the stroker.
2023-07-08 20:44:37 -04:00
Matthias Clasen
da354c08ff Add gsk_path_stroke
Implement stroking for paths.

The current implementation does not try to handle short
segments in the vicinity of sharp joins in any special
way, so there can be some artifacts in that situation.

There are special-case implementations for rectangle
and circle contours, since in many cases the outlines
of these contours just consist of two of the same
shapes.
2023-07-08 20:44:37 -04:00
Matthias Clasen
038b3ca184 Add more curve tests
These tests check that gsk_curve_intersect finds
the intersections we want and get_bounds returns
proper bounding boxes.

We also check a few simple cases of offset curves.
2023-07-08 20:44:37 -04:00
Matthias Clasen
c020eeac70 curve: Add gsk_curve_offset
This method creates an offset curve from an existing
curve by just moving the control points laterally.

This will be used in stroking.
2023-07-08 20:44:37 -04:00
Matthias Clasen
e5c97cc7fb curve: Add gsk_curve_intersect
Add a way to find the intersections of two curves.
We can handle some curve-line intersections directly,
the general case is handled via bisecting.

This will be used in stroking and path ops.
2023-07-08 20:44:37 -04:00
Matthias Clasen
ad01a9910e curve: Add utilities for cusps and inflections
Add functions to find cusps and inflection points of cubics.
These will be used for intersections and in the stroker.
2023-07-08 20:44:23 -04:00
Matthias Clasen
ac18bbe5ac curve: Add gsk_curve_get_bounds
Add getters for bounding boxes of curves.

We have cheap ones, which are just the bounding
box of the control points, and tighter ones, which
require finding the actual extrema.

Bounding boxes are needed to implement intersection
via bisecting.
2023-07-08 20:43:07 -04:00
Matthias Clasen
9f05e9357d Add a bounding box type
graphene_rect_t does not quite work for this purpose.
2023-07-08 20:41:37 -04:00
Matthias Clasen
3ae6e842aa tools: Add gtk4-path-tool
This comes in handy for testing, among other things.

For now, this supports decomposing,
reversing, restricting, rendering and preview.
2023-07-08 20:41:37 -04:00
Benjamin Otte
9b253738e4 demos: Add cute maze demo 2023-07-08 20:41:37 -04:00
Benjamin Otte
7065bc8efc demos: Add a text-on-path demo 2023-07-08 20:41:37 -04:00
Benjamin Otte
1eef220b19 demos: Add a simple demo filling a path 2023-07-08 20:41:37 -04:00
Benjamin Otte
739f4a699e WIP: css: Replace border rendering code with GskPath
The weight is wrong still, I need to compute the correct one to get real
45deg circle corners and not just roughly correct ones.
2023-07-08 20:41:37 -04:00
Matthias Clasen
4ced06d21c gsk: Add tests for gsk_path_dash 2023-07-08 20:41:37 -04:00
Matthias Clasen
94b34a2254 Add gsk_path_dash 2023-07-08 20:41:37 -04:00
Benjamin Otte
57263c6c6e snapshot: Add gtk_snapshot_push_stroke()
This is the obvious GtkSnapshot API to go
along with the new stroke nodes.
2023-07-08 20:41:37 -04:00
Benjamin Otte
7583851d1e gsk: Add GskStrokeNode
Take a rendernode as source and a GskPath and GskStroke,
and fill the area that is covered when stroking the path
with the given stroke parameters, like cairo_stroke() would.
2023-07-08 20:41:37 -04:00
Matthias Clasen
25842d9809 Add gsk_path_get_stroke_bounds
This is a help to compute the bounds for
stroke nodes. We keep it private for now.
2023-07-08 20:41:15 -04:00
Matthias Clasen
296230920b Add GskStroke
A GskStroke struct collects the parameters that are
needed for stroking a path.
2023-07-08 19:55:02 -04:00
Matthias Clasen
a473450930 Add another curve decomposition test
This one uses GskPathMeasure to check that
our conic approximations look roughly right.
2023-07-08 19:55:02 -04:00
Matthias Clasen
57a93b299a Add tests for GskPathMeasure 2023-07-08 19:55:02 -04:00
Matthias Clasen
ab7d9b0ef8 Add GskPathMeasure
An object to do measuring operations on paths - determining
their length, cutting off subpaths, things like that.
2023-07-08 19:55:01 -04:00
Benjamin Otte
1566c023c1 gtk: Add gtk_snapshot_push_fill()
This is the obvious GtkSnapshot API to go
along with the new fill nodes.
2023-07-08 19:53:59 -04:00
Benjamin Otte
d5e7eeeb6a gsk: Add GskFillNode
Take a rendernode as source and a GskPath and fill
the region in the path just like cairo_fill() would.
2023-07-08 19:53:59 -04:00
Matthias Clasen
6d667b6db6 gsk: Add tests for GskPath 2023-07-08 19:53:59 -04:00
Matthias Clasen
df482842de gsk: Add tests for GskCurve 2023-07-08 19:53:59 -04:00
Matthias Clasen
0366f40623 Add GskPath and GskPathBuilder
GskPath is a data structure for paths that consists
of contours, which in turn might contain Bézier curves.

The data structure is inspired by Skia, with separate
arrays for points and operations. One advantage of this
arrangement is that start and end points are shared
between adjacent curves.

In addition to the usual contours comprised of Bézier
segments, GskPath supports certain special contours
directly, such as rectangles, rounded rectangles and
circles.
2023-07-08 19:53:50 -04:00
848 changed files with 72809 additions and 121310 deletions

View File

@@ -1,2 +0,0 @@
[flake8]
ignore = E501

View File

@@ -26,20 +26,12 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Dbuild-testsuite=true -Dintrospection=enabled"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v48"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v47"
workflow:
rules:
# run merge request pipelines
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# do not run branch pipelines if corresponding merge requests exist...
# (this avoids duplicate pipelines)
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
# ...but otherwise run branch pipelines
- if: $CI_COMMIT_BRANCH
# run tag pipelines
- if: $CI_COMMIT_TAG
- if: $CI_COMMIT_BRANCH
default:
retry:
@@ -205,44 +197,28 @@ msys2-mingw64:
paths:
- "${CI_PROJECT_DIR}/_build/gtkdll.tar.gz"
macos-x86_64:
macos:
# Sadly, this fails regularly, and its failure is never enlightening
allow_failure: true
rules:
# Do not run in forks as the runner is not available there.
- if: $CI_PROJECT_NAMESPACE == "GNOME"
stage: build
tags:
- macosintel
- macos
needs: []
variables:
MESON_FORCE_BACKTRACKE: 1
TMPDIR: /Users/Shared/work/tmp
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
PIP_CACHE_DIR: /Users/Shared/build/cache
PIPENV_CACHE_DIR: $PIP_CACHE_DIR
PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR
EXTRA_MESON_FLAGS: "-Dgobject-introspection:werror=false"
before_script:
# Not using ccache on purpose as it accelerates the build so much that it
# can trigger race conditions in the gobject-introspection subproject.
- bash .gitlab-ci/show-info-osx.sh
- /opt/macports/bin/python3.10 -m venv .venv
- ln -s /opt/cmake/CMake.app/Contents/bin/cmake .venv/bin
- ln -s /opt/pkg-config/bin/pkg-config .venv/bin
- ln -s /opt/bison/bin/bison .venv/bin
- source .venv/bin/activate
- pip3 install meson==1.2.0
- pip3 install ninja==1.11.1
- pip3 install /Users/Shared/build/pkgs/PyGObject-3.44.0-cp310-cp310-macosx_10_13_x86_64.whl
/Users/Shared/build/pkgs/pycairo-1.23.0-cp310-cp310-macosx_10_13_x86_64.whl
- pip3 install --user meson~=1.0
- pip3 install --user ninja
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
- export MESON_FORCE_BACKTRACE=1
script:
- meson setup
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
- meson setup ${COMMON_MESON_FLAGS}
-Dx11-backend=false
-Dbroadway-backend=true
-Dmacos-backend=true
-Dmedia-gstreamer=disabled
-Dintrospection=enabled
-Dintrospection=disabled
-Dcpp_std=c++11
-Dpixman:tests=disabled
-Dlibjpeg-turbo:simd=disabled
@@ -442,11 +418,10 @@ reference:
--buildtype=release
--force-fallback-for=gdk-pixbuf,pango
-Dintrospection=enabled
-Ddocumentation=true
-Dgtk_doc=true
-Dgdk-pixbuf:gtk_doc=true
-Dpango:gtk_doc=true
-Dbuild-demos=false
-Ddemos=false
-Dbuild-examples=false
-Dbuild-tests=false
-Dbuild-testsuite=false

View File

@@ -28,11 +28,12 @@ RUN dnf -y install \
gdk-pixbuf2-modules \
gettext \
git \
glew-devel \
glib2-devel \
glib2-static \
glibc-devel \
glibc-headers \
glslc \
glut-devel \
gnupg2 \
gobject-introspection-devel \
graphene-devel \

View File

@@ -23,8 +23,8 @@ flatpak build ${builddir} meson \
-Dbuild-testsuite=false \
-Dbuild-examples=false \
-Dintrospection=disabled \
-Dbuild-demos=true \
-Ddemo-profile=devel \
-Ddemos=true \
-Dprofile=devel \
_flatpak_build
flatpak build ${builddir} ninja -C _flatpak_build install

View File

@@ -1,32 +0,0 @@
#!/usr/bin/sh
#
builddir=$1
suite=$2
unit=$3
echo "** builddir: ${builddir}"
echo "** suite: ${suite}"
echo "** unit: ${unit}"
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
weston --backend=headless-backend.so --socket=wayland-5 --idle-time=0 &
compositor=$!
export WAYLAND_DISPLAY=wayland-5
meson test -C ${builddir} \
--print-errorlogs \
--setup=wayland \
--suite=${suite} \
--no-suite=failing \
--no-suite=flaky \
--no-suite=wayland_failing \
--no-suite=gsk-compare-broadway \
--verbose \
"${unit}"
exit_code=$?
kill ${compositor}
exit ${exit_code}

View File

@@ -23,7 +23,6 @@ case "${backend}" in
--suite=gtk \
--no-suite=failing \
--no-suite=flaky \
--no-suite=headless \
--no-suite=gsk-compare-broadway
# Store the exit code for the CI run, but always
@@ -46,7 +45,6 @@ case "${backend}" in
--suite=gtk \
--no-suite=failing \
--no-suite=flaky \
--no-suite=headless \
--no-suite=${backend}_failing \
--no-suite=gsk-compare-broadway
exit_code=$?
@@ -69,7 +67,6 @@ case "${backend}" in
--suite=gtk \
--no-suite=failing \
--no-suite=flaky \
--no-suite=headless \
--no-suite=gsk-compare-opengl
kill ${server}

View File

@@ -6,7 +6,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
:: FIXME: make warnings fatal
pip3 install --upgrade --user meson~=0.64 || goto :error
meson setup -Dbackend_max_links=1 -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error
meson -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error
ninja -C _build || goto :error
goto :EOF

View File

@@ -32,8 +32,7 @@ pacman --noconfirm -S --needed \
mingw-w64-$MSYS2_ARCH-fribidi \
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
mingw-w64-$MSYS2_ARCH-shared-mime-info \
mingw-w64-$MSYS2_ARCH-python-gobject \
mingw-w64-$MSYS2_ARCH-shaderc
mingw-w64-$MSYS2_ARCH-python-gobject
mkdir -p _ccache
export CCACHE_BASEDIR="$(pwd)"

45
AUTHORS
View File

@@ -7,7 +7,7 @@ Peter Mattis <petm@xcf.berkeley.edu>
Spencer Kimball <spencer@xcf.berkeley.edu>
Josh MacDonald <jmacd@xcf.berkeley.edu>
The team that build GTK 2 (in alphabetical order)
The Team that build GTK 2 (in alphabetical order)
-------------------------------------------------
Shawn T. Amundson <amundson@gtk.org>
Jerome Bolliet <bolliet@gtk.org>
@@ -28,8 +28,9 @@ Jay Painter <jpaint@gtk.org>
Manish Singh <manish@gtk.org>
Owen Taylor <otaylor@gtk.org>
The team that built GTK 3
-------------------------
The current team (GTK 3 and 4)
------------------------------
Jonas Ådahl <jadahl@gmail.com>
Tim Bäder <mail@baedert.org>
Emmanuele Bassi <ebassi@gnome.org>
@@ -39,16 +40,6 @@ Carlos Garnacho <mrgarnacho@gmail.com>
Alexander Larsson <alexl@redhat.com>
Benjamin Otte <otte@gnome.org>
The current team (GTK 4)
------------------------
Jonas Ådahl <jadahl@gmail.com>
Emmanuele Bassi <ebassi@gnome.org>
Christian Hergert <chergert@gnome.org>
Chun-wei Fan <fanchunwei@src.gnome.org>
Matthias Clasen <mclasen@redhat.com>
Carlos Garnacho <mrgarnacho@gmail.com>
Benjamin Otte <otte@gnome.org>
There are many others who have contributed patches; we thank them,
GTK is much better because of them.
@@ -58,15 +49,35 @@ Over time, GTK has incorporated some pieces of software which
started as independent projects. We list the original authors here:
MS-Windows theme engine
-----------------------
Raymond Penners
Dom Lachowicz
Pixbuf theme engine
-------------------
Owen Taylor
IME input method
----------------
Takuro Ashie
Kazuki IWAMOTO
MacOS backend
-------------
Mac OS X backend
----------------
Anders Carlsson
GtkInspector (originally gtkparasite)
-------------------------------------
DirectFB backend
----------------
Denis Oliver Kropp
Sven Neumann
Mike Emmel
gtkparasite
-----------
Christian Hammond

View File

@@ -35,7 +35,8 @@ The issue tracker is meant to be used for actionable issues only.
You should not open a new issue for security related questions.
When in doubt, follow [security](https://security.gnome.org/).
When in doubt, send an email to the [security](mailto:security@gnome.org)
mailing list.
### Bug reports
@@ -243,11 +244,13 @@ people committing to GTK to follow a few rules:
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.
The `gtk` [room on matrix](https://matrix.to/#/#gtk: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, the [gtk tag on the GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
is the most certain and preferred method.
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_.

384
NEWS
View File

@@ -1,388 +1,6 @@
Overview of Changes in 4.13.2, xx-xx-xxxx
Overview of Changes in 4.11.4, xx-xx-xxxx
=========================================
Overview of Changes in 4.13.1, 28-09-2023
=========================================
* GtkTooltip:
- Don't cross native boundaries when looking for tooltips
* GtkCenterLayout, GtkEntry, GtkSearchEntry:
- Fix some issues with baseline handling
* GtkColorButton, GtkFontButton:
- Propagate focus-on-click
* GtkFileChooser:
- Make "Visit file" scroll to the file
* GtkSwitch:
- Respect text direction
* GtkWindow:
- Don't assume titlebars are GtkHeaderBars
* Printing:
- Fix some problems with the portal implementation
- Add a new simple print API: GtkPrintDialog
* Paths:
- GskPathMeasure performance has been improved
- Add custom contours for circles, rounded rectangles and rectangles
- Simplify GskPathPoint handling
- gsk_path_point_get_closest_point now returns the distance as well
- Make GskPathBuilder simplify curves
* Input:
- Handle (some) single-key compose sequences
- Fix active state tracking with sensitivity changes and grabs
* GSK:
- Make the repeated gradients match between GL and cairo
- Make rounded rect shrinking match between Vulkan, GL and cairo
- Fix parsing of text nodes with color glyphs
- Restrict an optimization to the cases where it is crrect
- Fix rendering of shadows with opacity
- The Vulkan renderer now requires Vulkan 1.2
- GL: Transition gradients unpremultiplied
- GL: Fix clipping of shadows
- GL: Some optimizations
- Broadway: Fix memory leaks in the renderer
* Wayland:
- Make activation more reliable
* macOS:
- Clamp damage regions to the surface size
* Tools:
- gtk4-path-tool gained restrict and reverse commands
- gtk4-path-tool show and render can show control points
* Demos:
- Add a demo for hit testing with paths
* Build:
- Fix build problems with C++ compilers
* Deprecations:
- gtk_window_present_with_time
* Translation updates
Brazilian Portuguese
British English
Catalan
Chinese (China)
Czech
Danish
Dutch
Esperanto
Galician
Georgian
Italian
Korean
Latvian
Lithuanian
Persian
Polish
Punjabi
Slovenian
Turkish
Overview of Changes in 4.13.0, 25-08-2023
=========================================
* GskPath, GskPathBuilder, GskPathMeasure:
Data types and APIs for path rendering. These APIs are still
considered experimental, and may change until 4.14. Please try
them out and give us feedback. Documentation can be found
here: https://docs.gtk.org/gsk4/paths.html
* GtkGridView:
- Fix a crash when scrolling
* GtkColumnView:
- Fix a refcounting issue in the new scroll_to api
* GtkTreeView
- Fix style classes for sort arrows
* GtkEntry:
- Improve tracking of user changes (for undo)
* GtkNotebook:
- Fix a critical when switching pages
* GtkColor/FontDialogButton:
- Make these widgets activatable
* GtkMenuButton:
- Fix problems with focus handling
- Fix problems with DND
- Make flags a settable property
* GtkShortcutsWindow:
- Add API to build shortcuts windows programmatically
* Printing
- Fix the cpdb backend build
* MacOS:
- Make file filters work again
* GSK:
- Fix issues with color matrix nodes
* Wayland:
- Fix a crash with compositors other than gnome-shell
* Deprecations:
- Remaining GtkTreeModel-related types
* Demos:
- Add a few path demos to gtk4-demo
* Tools:
- gtk4-path-tool provides a commandline interface for paths
* Translation updates:
Basque
Catalan
Finnish
Galician
Georgian
German
Greek
Indonesian
Kazakh
Persian
Polish
Romanian
Spanish
Swedish
Turkish
Ukrainian
Overview of Changes in 4.12.0, 05-08-2023
=========================================
* List widgets:
- Add scroll_to APIs
* GtkFileLauncher:
- Add an always-ask property
* GtkTextView:
- Make backspace behavior match GtkEntry
* gsk:
- Fix handling of luminance in mask nodes
* Text rendering:
- Automate the setting of gtk-hint-font-metrics from the
scale factor. This improves font rendering in flatpaks
* Wayland:
- Fix behavior of stylus buttons
- Support suspended window state
* Vulkan:
- Many improvements
* Tools:
- Add gtk4-rendernode-tool
* Debugging:
- Drop the GTK_DEBUG_TOUCHSCREEN flag
* Build:
- Some build options have been renamed:
gtk_doc -> documentation
update_screenshots -> screenshots
The old names still work
* Translation updates:
Georgian
Greek
Hebrew
Persian
Vietnamese
* Contributors:
Aleksandr Melman
Alexander Mikhaylenko
Alexander Shopov
Alexandre Franke
Alice Mikhaylenko
António Fernandes
Arjan Molenaar
Asier Sarasua Garmendia
Balázs Meskó
Balázs Úr
Barnabás Pőcze
Bart Jacobs
Benjamin Otte
Bilal Elmoussaoui
Boyuan Yang
Bruce Cowan
Calvin Walton
Cam Cook
Chris Mayo
Christian Hergert
Christopher Davis
Chun-wei Fan
Corey Berla
Danial Behzadi
Daniel Boles
Daniel Rusek
Efstathios Iosifidis
Ekaterine Papava
Emin Tufan Çetin
Emmanuele Bassi
Erik Schilling
Fabio Tomat
FeRD (Frank Dana)
Fina Wilke
FineFindus
Fran Dieguez
G.Willems
Georges Basile Stavracas Neto
Guillaume Bernard
Hugo Carvalho
Ivan Molodetskikh
Jason Francis
Jonas Ådahl
Jordan Petridis
Jordi Mas
José Expósito
José Roberto de Souza
Khalid Abu Shawarib
Kévin Commaille
Leônidas Araújo
Luca Bacci
Ludovico de Nittis
Lukáš Tyrychtr
Marc-André Lureau
Marco Trevisan (Treviño)
Matt Turner
Matthias Clasen
Maximiliano Sandoval R
Michael Catanzaro
Michel Dänzer
Mohammed Sadiq
Nathan Follens
Nelson Benítez León
Ngọc Quân Trần
Niels De Graef
Olivier Crête
Patrick Griffis
Piotr Drąg
Sabri Ünal
Sebastian Keller
Sophie Herold
Sébastien Le Roux
Takao Fujiwara
Thomas Lange
Yiğit Burak
Yosef Or Boczko
Yuri Chornoivan
Zander Brown
al_SeveR
dgsasha
sumibi-yakitori
tszymanski
velsinki
Алексей Шилин
Арсений Засыпкин
Overview of Changes in 4.11.4, 03-07-2023
=========================================
* GtkFileChooser:
- Default to sorting folders first
- Fix a crash when visiting recent files
* GtkTextView:
- Fix corner cases in word navigation
* GtkMenuButton:
- Normalize label layout
* GtkDropDown:
- Add support for sections
* GtkVideo:
- Make the overlay icon clickable
* GtkWindow:
- Clear the resize cursors to avoid artifacts
* GtkFileDialog:
- Always set initial-folder
* GtkDropDown:
- Update on expression changes
* GtkMapListModel:
- Implement GtkSectionModel
* Accessibility:
- Improvements all over the place: GtkButton, GtkPasswordEntry,
GtkFontChooserDialog, GtkColorChooserDialog, GtkShortcutsWindow,
GtkMenuButton, GtkAboutDialog, GtkFileChooserDialog, GtkStackSidebar,
GtkStackSwitcher, GtkMediaControls, GtkColorDialogButton, GtkDropDown,
GtkInfoBar, GtkNotebook, GtkPrintUnixDialog, GtkModelButton
- Make name computation follow the ARIA spec more closely
- Adapt name computation for the common 'nested button' scenario
- Change many containers to use `generic` instead of `group`
- Use `generic` as the default role
- Use `application` instead of `window` for windows
- Add properties for accessible names of not directly exposed
widgets in GtkListView, GtkGridView and GtkColumnView
* DND:
- Fix criticals when drops are rejected
* X11:
- Fix regressions in GLX setup
* Windows:
- Center newly created transient windows
* Vulkan:
- Add antialising for gradients
- Do less work on clipped away nodes
- Redo image uploading
- Support different image depths and formats
- Add a pipeline cache
* Demos:
- gtk4-demo: Improve window sizing
- gtk4-demo: Improve focus behavior
- gtk4-demo: Add many missing a11y properties
* Tools:
- gtk4-builder-tool: Make render an alias screenshot
* Inspector:
- Show more information in the a11y tab
- Add an accessibility overlay with warnings and recommendations
- Limit the width of the a11y tab
* Build:
- Require GLib 2.76
- Make asan builds work again
- Fix the build if ld is not ld.bdf
* Translation updates:
Brazilian Portuguese
Catalan
Czech
Georgian
Overview of Changes in 4.11.3, 05-06-2023
=========================================

View File

@@ -67,13 +67,6 @@ building for:
- [Graphene](https://github.com/ebassi/graphene)
- [Xkb-common](https://github.com/xkbcommon/libxkbcommon)
If you are building the Wayland backend, you will also need:
- Wayland-client
- Wayland-protocols
- Wayland-cursor
- Wayland-EGL
If you are building the X11 backend, you will also need:
- Xlib, and the following X extensions:
@@ -86,24 +79,32 @@ If you are building the X11 backend, you will also need:
- xdamage
- xcomposite
If you are building the Wayland backend, you will also need:
- Wayland-client
- Wayland-protocols
- Wayland-cursor
- Wayland-EGL
Once you have all the necessary dependencies, you can build GTK by using
Meson:
```sh
$ meson setup _build
$ meson compile -C_build
$ meson _build .
$ cd _build
$ ninja
```
You can run the test suite using:
```sh
$ meson test -C_build
$ meson test
```
And, finally, you can install GTK using:
```
$ sudo meson install -C_build
$ sudo ninja install
```
Complete information about installing GTK and related libraries

View File

@@ -483,8 +483,6 @@ constraint_editor_window_class_init (ConstraintEditorWindowClass *class)
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
g_type_ensure (CONSTRAINT_VIEW_TYPE);
object_class->dispose = constraint_editor_window_dispose;
gtk_widget_class_set_template_from_resource (widget_class,

View File

@@ -20,7 +20,8 @@
#include "config.h"
#include "constraint-editor.h"
#include "constraint-view.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
struct _ConstraintEditor
{
@@ -65,7 +66,7 @@ static const char *
get_target_name (GtkConstraintTarget *target)
{
if (target == NULL)
return "Super";
return "super";
else if (GTK_IS_WIDGET (target))
return gtk_widget_get_name (GTK_WIDGET (target));
else if (GTK_IS_CONSTRAINT_GUIDE (target))
@@ -79,29 +80,62 @@ constraint_target_combo (GListModel *model,
GtkWidget *combo,
gboolean is_source)
{
GtkStringList *targets;
int i;
targets = gtk_string_list_new (NULL);
gtk_string_list_append (targets, "Super");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "super", "Super");
if (model)
{
for (i = 0; i < g_list_model_get_n_items (model); i++)
{
GObject *item = g_list_model_get_object (model, i);
const char *name;
if (GTK_IS_CONSTRAINT (item))
continue;
gtk_string_list_append (targets, get_target_name (GTK_CONSTRAINT_TARGET (item)));
name = get_target_name (GTK_CONSTRAINT_TARGET (item));
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), name, name);
g_object_unref (item);
}
}
}
gtk_drop_down_set_model (GTK_DROP_DOWN (combo), G_LIST_MODEL (targets));
g_object_unref (targets);
static void
constraint_attribute_combo (GtkWidget *combo,
gboolean is_source)
{
if (is_source)
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "none", "None");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "left", "Left");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "right", "Right");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "top", "Top");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "bottom", "Bottom");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "start", "Start");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "end", "End");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "width", "Width");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "height", "Height");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "center-x", "Center X");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "center-y", "Center Y");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "baseline", "Baseline");
}
static void
constraint_relation_combo (GtkWidget *combo)
{
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "le", "");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "eq", "=");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "ge", "");
}
static void
constraint_strength_combo (GtkWidget *combo)
{
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "weak", "Weak");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "medium", "Medium");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "strong", "Strong");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "required", "Required");
}
static gpointer
@@ -113,7 +147,7 @@ get_target (GListModel *model,
if (id == NULL)
return NULL;
if (strcmp ("Super", id) == 0)
if (strcmp ("super", id) == 0)
return NULL;
for (i = 0; i < g_list_model_get_n_items (model); i++)
@@ -137,65 +171,16 @@ get_target (GListModel *model,
return NULL;
}
static void
select_target (GtkDropDown *combo,
const char *target_name)
{
GListModel *model = gtk_drop_down_get_model (combo);
for (unsigned int i = 0; i < g_list_model_get_n_items (model); i++)
{
GtkStringObject *s = g_list_model_get_item (model, i);
g_object_unref (s);
if (strcmp (target_name, gtk_string_object_get_string (s)) == 0)
{
gtk_drop_down_set_selected (GTK_DROP_DOWN (combo), i);
return;
}
}
}
static GtkConstraintAttribute
get_attr (unsigned int id)
get_target_attr (const char *id)
{
switch (id)
{
case 0: return GTK_CONSTRAINT_ATTRIBUTE_NONE;
case 1: return GTK_CONSTRAINT_ATTRIBUTE_LEFT;
case 2: return GTK_CONSTRAINT_ATTRIBUTE_RIGHT;
case 3: return GTK_CONSTRAINT_ATTRIBUTE_TOP;
case 4: return GTK_CONSTRAINT_ATTRIBUTE_BOTTOM;
case 5: return GTK_CONSTRAINT_ATTRIBUTE_START;
case 6: return GTK_CONSTRAINT_ATTRIBUTE_END;
case 7: return GTK_CONSTRAINT_ATTRIBUTE_WIDTH;
case 8: return GTK_CONSTRAINT_ATTRIBUTE_HEIGHT;
case 9: return GTK_CONSTRAINT_ATTRIBUTE_CENTER_X;
case 10: return GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y;
case 11: return GTK_CONSTRAINT_ATTRIBUTE_BASELINE;
default: g_assert_not_reached ();
}
}
GtkConstraintAttribute attr;
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_ATTRIBUTE);
GEnumValue *value = g_enum_get_value_by_nick (class, id);
attr = value->value;
g_type_class_unref (class);
static unsigned int
get_attr_id (GtkConstraintAttribute attr)
{
switch (attr)
{
case GTK_CONSTRAINT_ATTRIBUTE_NONE: return 0;
case GTK_CONSTRAINT_ATTRIBUTE_LEFT: return 1;
case GTK_CONSTRAINT_ATTRIBUTE_RIGHT: return 2;
case GTK_CONSTRAINT_ATTRIBUTE_TOP: return 3;
case GTK_CONSTRAINT_ATTRIBUTE_BOTTOM: return 4;
case GTK_CONSTRAINT_ATTRIBUTE_START: return 5;
case GTK_CONSTRAINT_ATTRIBUTE_END: return 6;
case GTK_CONSTRAINT_ATTRIBUTE_WIDTH: return 7;
case GTK_CONSTRAINT_ATTRIBUTE_HEIGHT: return 8;
case GTK_CONSTRAINT_ATTRIBUTE_CENTER_X: return 9;
case GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y: return 10;
case GTK_CONSTRAINT_ATTRIBUTE_BASELINE: return 11;
default: g_assert_not_reached ();
}
return attr;
}
static const char *
@@ -210,27 +195,15 @@ get_attr_nick (GtkConstraintAttribute attr)
}
static GtkConstraintRelation
get_relation (unsigned int id)
get_relation (const char *id)
{
switch (id)
{
case 0: return GTK_CONSTRAINT_RELATION_LE;
case 1: return GTK_CONSTRAINT_RELATION_EQ;
case 2: return GTK_CONSTRAINT_RELATION_GE;
default: g_assert_not_reached ();
}
}
GtkConstraintRelation relation;
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_RELATION);
GEnumValue *value = g_enum_get_value_by_nick (class, id);
relation = value->value;
g_type_class_unref (class);
static unsigned int
get_relation_id (GtkConstraintRelation relation)
{
switch (relation)
{
case GTK_CONSTRAINT_RELATION_LE: return 0;
case GTK_CONSTRAINT_RELATION_EQ: return 1;
case GTK_CONSTRAINT_RELATION_GE: return 2;
default: g_assert_not_reached ();
}
return relation;
}
static const char *
@@ -261,29 +234,15 @@ get_relation_display_name (GtkConstraintRelation relation)
}
static GtkConstraintStrength
get_strength (unsigned int id)
{
switch (id)
{
case 0: return GTK_CONSTRAINT_STRENGTH_WEAK;
case 1: return GTK_CONSTRAINT_STRENGTH_MEDIUM;
case 2: return GTK_CONSTRAINT_STRENGTH_STRONG;
case 3: return GTK_CONSTRAINT_STRENGTH_REQUIRED;
default: g_assert_not_reached ();
}
}
static unsigned int
get_strength_id (GtkConstraintStrength strength)
get_strength (const char *id)
{
switch (strength)
{
case GTK_CONSTRAINT_STRENGTH_WEAK: return 0;
case GTK_CONSTRAINT_STRENGTH_MEDIUM: return 1;
case GTK_CONSTRAINT_STRENGTH_STRONG: return 2;
case GTK_CONSTRAINT_STRENGTH_REQUIRED: return 3;
default: g_assert_not_reached ();
}
GtkConstraintStrength strength;
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
GEnumValue *value = g_enum_get_value_by_nick (class, id);
strength = value->value;
g_type_class_unref (class);
return strength;
}
static const char *
@@ -335,7 +294,7 @@ static void
create_constraint (GtkButton *button,
ConstraintEditor *editor)
{
gpointer obj;
const char *id;
gpointer target;
GtkConstraintAttribute target_attr;
gpointer source;
@@ -346,27 +305,25 @@ create_constraint (GtkButton *button,
int strength;
GtkConstraint *constraint;
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->target));
if (obj)
target = get_target (editor->model, gtk_string_object_get_string (GTK_STRING_OBJECT (obj)));
else
target = NULL;
target_attr = get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->target_attr)));
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target));
target = get_target (editor->model, id);
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target_attr));
target_attr = get_target_attr (id);
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->source));
if (obj)
source = get_target (editor->model, gtk_string_object_get_string (GTK_STRING_OBJECT (obj)));
else
source = NULL;
source_attr = get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN(editor->source_attr)));
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
source = get_target (editor->model, id);
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
source_attr = get_target_attr (id);
relation = get_relation (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->relation)));
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->relation));
relation = get_relation (id);
multiplier = g_ascii_strtod (gtk_editable_get_text (GTK_EDITABLE (editor->multiplier)), NULL);
constant = g_ascii_strtod (gtk_editable_get_text (GTK_EDITABLE (editor->constant)), NULL);
strength = get_strength (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->strength)));
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->strength));
strength = get_strength (id);
constraint = gtk_constraint_new (target, target_attr,
relation,
@@ -381,9 +338,12 @@ create_constraint (GtkButton *button,
static void
source_attr_changed (ConstraintEditor *editor)
{
if (get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->source_attr))) == GTK_CONSTRAINT_ATTRIBUTE_NONE)
const char *id;
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
if (strcmp (id, "none") == 0)
{
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->source), GTK_INVALID_LIST_POSITION);
gtk_combo_box_set_active (GTK_COMBO_BOX (editor->source), -1);
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "");
gtk_widget_set_sensitive (editor->source, FALSE);
gtk_widget_set_sensitive (editor->multiplier, FALSE);
@@ -449,7 +409,7 @@ update_preview (ConstraintEditor *editor)
GString *str;
const char *name;
const char *attr;
const char *relation;
char *relation;
const char *multiplier;
const char *constant;
double c, m;
@@ -459,22 +419,23 @@ update_preview (ConstraintEditor *editor)
str = g_string_new ("");
name = gtk_string_object_get_string (GTK_STRING_OBJECT (gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->target))));
attr = get_attr_nick (get_attr (gtk_drop_down_get_selected ((GTK_DROP_DOWN (editor->target_attr)))));
relation = get_relation_nick (get_relation (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->relation))));
name = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target));
attr = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target_attr));
relation = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (editor->relation));
if (name == NULL)
name = "[ ]";
g_string_append_printf (str, "%s.%s %s ", name, attr, relation);
g_free (relation);
constant = gtk_editable_get_text (GTK_EDITABLE (editor->constant));
c = g_ascii_strtod (constant, NULL);
attr = get_attr_nick (get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->source_attr))));
attr = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
if (strcmp (attr, "none") != 0)
{
name = gtk_string_object_get_string (GTK_STRING_OBJECT (gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->source))));
name = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
multiplier = gtk_editable_get_text (GTK_EDITABLE (editor->multiplier));
m = g_ascii_strtod (multiplier, NULL);
@@ -502,18 +463,12 @@ update_preview (ConstraintEditor *editor)
static void
update_button (ConstraintEditor *editor)
{
gpointer obj;
const char *target;
const char *source;
GtkConstraintAttribute source_attr = get_attr (gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->source_attr)));
const char *target = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target));
const char *source = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
const char *source_attr = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->target));
target = obj ? gtk_string_object_get_string (GTK_STRING_OBJECT (obj)) : NULL;
obj = gtk_drop_down_get_selected_item (GTK_DROP_DOWN (editor->source));
source = obj ? gtk_string_object_get_string (GTK_STRING_OBJECT (obj)) : NULL;
if (target && (source || (source_attr == GTK_CONSTRAINT_ATTRIBUTE_NONE)))
if (target &&
(source || (source_attr && get_target_attr (source_attr) == GTK_CONSTRAINT_ATTRIBUTE_NONE)))
gtk_widget_set_sensitive (editor->button, TRUE);
else
gtk_widget_set_sensitive (editor->button, FALSE);
@@ -531,7 +486,12 @@ constraint_editor_constructed (GObject *object)
ConstraintEditor *editor = CONSTRAINT_EDITOR (object);
constraint_target_combo (editor->model, editor->target, FALSE);
constraint_attribute_combo (editor->target_attr, FALSE);
constraint_relation_combo (editor->relation);
constraint_target_combo (editor->model, editor->source, TRUE);
constraint_attribute_combo (editor->source_attr, TRUE);
constraint_strength_combo (editor->strength);
if (editor->constraint)
{
@@ -539,24 +499,30 @@ constraint_editor_constructed (GObject *object)
GtkConstraintAttribute attr;
GtkConstraintRelation relation;
GtkConstraintStrength strength;
const char *nick;
char *val;
double multiplier;
double constant;
target = gtk_constraint_get_target (editor->constraint);
select_target (GTK_DROP_DOWN (editor->target), get_target_name (target));
nick = get_target_name (target);
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target), nick);
attr = gtk_constraint_get_target_attribute (editor->constraint);
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->target_attr), get_attr_id (attr));
nick = get_attr_nick (attr);
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target_attr), nick);
target = gtk_constraint_get_source (editor->constraint);
select_target (GTK_DROP_DOWN (editor->source), get_target_name (target));
nick = get_target_name (target);
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source), nick);
attr = gtk_constraint_get_source_attribute (editor->constraint);
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->source_attr), get_attr_id (attr));
nick = get_attr_nick (attr);
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source_attr), nick);
relation = gtk_constraint_get_relation (editor->constraint);
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->relation), get_relation_id (relation));
nick = get_relation_nick (relation);
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->relation), nick);
multiplier = gtk_constraint_get_multiplier (editor->constraint);
val = g_strdup_printf ("%g", multiplier);
@@ -569,16 +535,17 @@ constraint_editor_constructed (GObject *object)
g_free (val);
strength = gtk_constraint_get_strength (editor->constraint);
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (strength));
nick = get_strength_nick (strength);
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), nick);
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
}
else
{
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->target_attr), get_attr_id (GTK_CONSTRAINT_ATTRIBUTE_LEFT));
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->source_attr), get_attr_id (GTK_CONSTRAINT_ATTRIBUTE_LEFT));
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->relation), get_relation_id (GTK_CONSTRAINT_RELATION_EQ));
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target_attr), "left");
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source_attr), "left");
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->relation), "eq");
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), "required");
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "1.0");
gtk_editable_set_text (GTK_EDITABLE (editor->constant), "0.0");

View File

@@ -1,21 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkStringList" id="targets">
<items>
<item>None</item>
<item>Left</item>
<item>Right</item>
<item>Top</item>
<item>Bottom</item>
<item>Start</item>
<item>End</item>
<item>Width</item>
<item>Height</item>
<item>Center X</item>
<item>Center Y</item>
<item>Baseline</item>
</items>
</object>
<template class="ConstraintEditor" parent="GtkWidget">
<child>
<object class="GtkGrid" id="grid">
@@ -35,9 +19,9 @@
</object>
</child>
<child>
<object class="GtkDropDown" id="target">
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<signal name="notify::selected" handler="update_button" swapped="yes"/>
<object class="GtkComboBoxText" id="target">
<signal name="changed" handler="update_preview" swapped="yes"/>
<signal name="changed" handler="update_button" swapped="yes"/>
<layout>
<property name="column">1</property>
<property name="row">1</property>
@@ -45,9 +29,8 @@
</object>
</child>
<child>
<object class="GtkDropDown" id="target_attr">
<property name="model">targets</property>
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<object class="GtkComboBoxText" id="target_attr">
<signal name="changed" handler="update_preview" swapped="yes"/>
<layout>
<property name="column">2</property>
<property name="row">1</property>
@@ -64,17 +47,8 @@
</object>
</child>
<child>
<object class="GtkDropDown" id="relation">
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<property name="model">
<object class="GtkStringList">
<items>
<item>≤</item>
<item>=</item>
<item>≥</item>
</items>
</object>
</property>
<object class="GtkComboBoxText" id="relation">
<signal name="changed" handler="update_preview" swapped="yes"/>
<layout>
<property name="column">1</property>
<property name="row">2</property>
@@ -91,9 +65,9 @@
</object>
</child>
<child>
<object class="GtkDropDown" id="source">
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<signal name="notify::selected" handler="update_button" swapped="yes"/>
<object class="GtkComboBoxText" id="source">
<signal name="changed" handler="update_preview" swapped="yes"/>
<signal name="changed" handler="update_button" swapped="yes"/>
<layout>
<property name="column">1</property>
<property name="row">3</property>
@@ -101,11 +75,10 @@
</object>
</child>
<child>
<object class="GtkDropDown" id="source_attr">
<property name="model">targets</property>
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<signal name="notify::selected" handler="source_attr_changed" swapped="yes"/>
<signal name="notify::selected" handler="update_button" swapped="yes"/>
<object class="GtkComboBoxText" id="source_attr">
<signal name="changed" handler="update_preview" swapped="yes"/>
<signal name="changed" handler="source_attr_changed" swapped="yes"/>
<signal name="changed" handler="update_button" swapped="yes"/>
<layout>
<property name="column">2</property>
<property name="row">3</property>
@@ -158,17 +131,7 @@
</object>
</child>
<child>
<object class="GtkDropDown" id="strength">
<property name="model">
<object class="GtkStringList">
<items>
<item>Weak</item>
<item>Medium</item>
<item>Strong</item>
<item>Required</item>
</items>
</object>
</property>
<object class="GtkComboBoxText" id="strength">
<layout>
<property name="column">1</property>
<property name="row">6</property>

View File

@@ -21,6 +21,8 @@
#include "guide-editor.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
struct _GuideEditor
{
GtkWidget parent_instance;
@@ -57,30 +59,25 @@ static guint signals[LAST_SIGNAL];
G_DEFINE_TYPE(GuideEditor, guide_editor, GTK_TYPE_WIDGET);
static GtkConstraintStrength
get_strength (unsigned int id)
static void
guide_strength_combo (GtkWidget *combo)
{
switch (id)
{
case 0: return GTK_CONSTRAINT_STRENGTH_WEAK;
case 1: return GTK_CONSTRAINT_STRENGTH_MEDIUM;
case 2: return GTK_CONSTRAINT_STRENGTH_STRONG;
case 3: return GTK_CONSTRAINT_STRENGTH_REQUIRED;
default: g_assert_not_reached ();
}
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "weak", "Weak");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "medium", "Medium");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "strong", "Strong");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "required", "Required");
}
static unsigned int
get_strength_id (GtkConstraintStrength strength)
static GtkConstraintStrength
get_strength (const char *id)
{
switch (strength)
{
case GTK_CONSTRAINT_STRENGTH_WEAK: return 0;
case GTK_CONSTRAINT_STRENGTH_MEDIUM: return 1;
case GTK_CONSTRAINT_STRENGTH_STRONG: return 2;
case GTK_CONSTRAINT_STRENGTH_REQUIRED: return 3;
default: g_assert_not_reached ();
}
GtkConstraintStrength strength;
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
GEnumValue *value = g_enum_get_value_by_nick (class, id);
strength = value->value;
g_type_class_unref (class);
return strength;
}
static const char *
@@ -121,11 +118,11 @@ static void
create_guide (GtkButton *button,
GuideEditor *editor)
{
const char *id;
int strength;
const char *name;
int w, h;
GtkConstraintGuide *guide;
unsigned int id;
if (editor->guide)
guide = g_object_ref (editor->guide);
@@ -147,7 +144,7 @@ create_guide (GtkButton *button,
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->max_height));
gtk_constraint_guide_set_max_size (guide, w, h);
id = gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->strength));
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->strength));
strength = get_strength (id);
gtk_constraint_guide_set_strength (guide, strength);
@@ -194,9 +191,14 @@ guide_editor_constructed (GObject *object)
{
GuideEditor *editor = GUIDE_EDITOR (object);
guide_strength_combo (editor->strength);
g_signal_connect (editor->min_width, "input", G_CALLBACK (min_input), NULL);
g_signal_connect (editor->min_height, "input", G_CALLBACK (min_input), NULL);
g_signal_connect (editor->max_width, "input", G_CALLBACK (max_input), NULL);
g_signal_connect (editor->max_height, "input", G_CALLBACK (max_input), NULL);
if (editor->guide)
@@ -222,7 +224,8 @@ guide_editor_constructed (GObject *object)
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), h);
strength = gtk_constraint_guide_get_strength (editor->guide);
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (strength));
nick = get_strength_nick (strength);
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), nick);
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
}
@@ -242,7 +245,7 @@ guide_editor_constructed (GObject *object)
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_width), G_MAXINT);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), G_MAXINT);
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (GTK_CONSTRAINT_STRENGTH_MEDIUM));
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), "medium");
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
}

View File

@@ -167,17 +167,7 @@
</object>
</child>
<child>
<object class="GtkDropDown" id="strength">
<property name="model">
<object class="GtkStringList">
<items>
<item>Weak</item>
<item>Medium</item>
<item>Strong</item>
<item>Required</item>
</items>
</object>
</property>
<object class="GtkComboBoxText" id="strength">
<layout>
<property name="column">1</property>
<property name="row">4</property>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -2,6 +2,8 @@
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
typedef GtkApplication DemoApplication;
typedef GtkApplicationClass DemoApplicationClass;
@@ -214,41 +216,6 @@ activate_quit (GSimpleAction *action,
}
}
static void
delete_messages (gpointer data)
{
g_list_free_full ((GList *)data, g_free);
}
static void
pop_message (GtkWidget *status)
{
GList *messages = (GList *) g_object_steal_data (G_OBJECT (status), "messages");
if (messages)
{
char *message = messages->data;
messages = g_list_remove (messages, message);
g_object_set_data_full (G_OBJECT (status), "messages",
messages, delete_messages);
gtk_label_set_label (GTK_LABEL (status), message);
}
}
static void
push_message (GtkWidget *status,
const char *message)
{
GList *messages = (GList *) g_object_steal_data (G_OBJECT (status), "messages");
gtk_label_set_label (GTK_LABEL (status), message);
messages = g_list_prepend (messages, g_strdup (message));
g_object_set_data_full (G_OBJECT (status), "messages",
messages, delete_messages);
}
static void
update_statusbar (GtkTextBuffer *buffer,
DemoApplicationWindow *window)
@@ -259,7 +226,7 @@ update_statusbar (GtkTextBuffer *buffer,
GtkTextIter iter;
/* clear any previous message, underflow is allowed */
pop_message (window->status);
gtk_statusbar_pop (GTK_STATUSBAR (window->status), 0);
count = gtk_text_buffer_get_char_count (buffer);
@@ -273,7 +240,7 @@ update_statusbar (GtkTextBuffer *buffer,
msg = g_strdup_printf ("Cursor at row %d column %d - %d chars in document",
row, col, count);
push_message (window->status, msg);
gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, msg);
g_free (msg);
}

View File

@@ -76,13 +76,8 @@
</object>
</child>
<child>
<object class="GtkLabel" id="status">
<object class="GtkStatusbar" id="status">
<property name="hexpand">1</property>
<property name="xalign">0</property>
<property name="margin-start">2</property>
<property name="margin-end">2</property>
<property name="margin-top">2</property>
<property name="margin-bottom">2</property>
<layout>
<property name="column">0</property>
<property name="row">3</property>

View File

@@ -1,5 +1,5 @@
/* Builder
* #Keywords: GMenu, GtkPopoverMenuBar, GtkBuilder, GtkShortcutController, toolbar
* #Keywords: GMenu, GtkPopoverMenuBar, GtkBuilder, GtkStatusBar, GtkShortcutController, toolbar
*
* Demonstrates a traditional interface, loaded from a XML description,
* and shows how to connect actions to the menu items and toolbar buttons.
@@ -37,34 +37,30 @@ remove_timeout (gpointer data)
g_source_remove (id);
}
static int
pop_message (gpointer data)
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static gboolean
pop_status (gpointer data)
{
GtkWidget *status = data;
gtk_label_set_label (GTK_LABEL (status), "");
g_object_set_data (G_OBJECT (status), "timeout", GUINT_TO_POINTER (0));
gtk_statusbar_pop (GTK_STATUSBAR (data), 0);
g_object_set_data (G_OBJECT (data), "timeout", NULL);
return G_SOURCE_REMOVE;
}
static void
status_message (GtkWidget *status,
const char *text)
status_message (GtkStatusbar *status,
const char *text)
{
guint id;
id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (status), "timeout"));
if (id)
g_source_remove (id);
gtk_label_set_text (GTK_LABEL (status), text);
id = g_timeout_add (5000, pop_message, status);
gtk_statusbar_push (GTK_STATUSBAR (status), 0, text);
id = g_timeout_add (5000, pop_status, status);
g_object_set_data_full (G_OBJECT (status), "timeout", GUINT_TO_POINTER (id), remove_timeout);
}
G_GNUC_END_IGNORE_DEPRECATIONS
static void
help_activate (GSimpleAction *action,
GVariant *parameter,
@@ -73,7 +69,7 @@ help_activate (GSimpleAction *action,
GtkWidget *status;
status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status"));
status_message (status, "Help not available");
status_message (GTK_STATUSBAR (status), "Help not available");
}
static void
@@ -86,7 +82,7 @@ not_implemented (GSimpleAction *action,
text = g_strdup_printf ("Action “%s” not implemented", g_action_get_name (G_ACTION (action)));
status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status"));
status_message (status, text);
status_message (GTK_STATUSBAR (status), text);
g_free (text);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1019 B

After

Width:  |  Height:  |  Size: 985 B

View File

@@ -6,6 +6,8 @@
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static void
show_parsing_error (GtkCssProvider *provider,
GtkCssSection *section,
@@ -47,23 +49,20 @@ css_text_changed (GtkTextBuffer *buffer,
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
gtk_css_provider_load_from_string (provider, text);
gtk_css_provider_load_from_data (provider, text, -1);
g_free (text);
}
static void
clear_provider (gpointer data)
{
GtkStyleProvider *provider = data;
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
}
static void
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
{
gtk_style_context_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
GtkWidget *child;
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
apply_css (child, provider);
}
GtkWidget *
@@ -82,7 +81,6 @@ do_css_basics (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "CSS Basics");
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
gtk_widget_add_css_class (window, "demo");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
text = gtk_text_buffer_new (NULL);

View File

@@ -4,24 +4,23 @@
* anymore. :)
*/
/* This resets all properties to their defaults values
* and overrides all user settings and the theme in use
*/
@import url("resource://css_shadows/reset.css");
/* This CSS resets all properties to their defaults values
* and overrides all user settings and the theme in use */
@import url("resource://css_basics/reset.css");
/* Set a very futuristic style by default */
.demo * {
* {
color: green;
font-family: Monospace;
border: 1px solid;
}
window.demo {
window {
background-color: white;
}
/* Make sure selections are visible */
.demo selection {
selection {
background-color: darkGreen;
color: black;
}

View File

@@ -6,6 +6,8 @@
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static void
show_parsing_error (GtkCssProvider *provider,
GtkCssSection *section,
@@ -48,23 +50,33 @@ css_text_changed (GtkTextBuffer *buffer,
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
gtk_css_provider_load_from_string (provider, text);
gtk_css_provider_load_from_data (provider, text, -1);
g_free (text);
}
static void
clear_provider (gpointer data)
drawing_area_draw (GtkDrawingArea *da,
cairo_t *cr,
int width,
int height,
gpointer data)
{
GtkStyleProvider *provider = data;
GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET (da));
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
gtk_render_background (context, cr, 0, 0, width, height);
gtk_render_frame (context, cr, 0, 0, width, height);
}
static void
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
{
gtk_style_context_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
GtkWidget *child;
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
apply_css (child, provider);
}
GtkWidget *
@@ -83,17 +95,16 @@ do_css_multiplebgs (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Multiple Backgrounds");
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
gtk_widget_add_css_class (window, "demo");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
overlay = gtk_overlay_new ();
gtk_window_set_child (GTK_WINDOW (window), overlay);
child = gtk_drawing_area_new ();
/* Don't set a draw_func, since we are only interested in CSS drawing,
* which happens automatically.
*/
gtk_widget_set_name (child, "canvas");
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (child),
drawing_area_draw,
NULL, NULL);
gtk_overlay_set_child (GTK_OVERLAY (overlay), child);
child = gtk_button_new ();

View File

@@ -7,6 +7,8 @@
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static void
show_parsing_error (GtkCssProvider *provider,
GtkCssSection *section,
@@ -49,23 +51,20 @@ css_text_changed (GtkTextBuffer *buffer,
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
gtk_css_provider_load_from_string (provider, text);
gtk_css_provider_load_from_data (provider, text, -1);
g_free (text);
}
static void
clear_provider (gpointer data)
{
GtkStyleProvider *provider = data;
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
}
static void
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
{
gtk_style_context_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
GtkWidget *child;
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
apply_css (child, provider);
}
GtkWidget *
@@ -84,7 +83,6 @@ do_css_pixbufs (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Animated Backgrounds");
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
gtk_widget_add_css_class (window, "demo");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);

View File

@@ -50,7 +50,7 @@
100% { background-size: 12px, 96px, 12px, 96px, 12px, 96px, 12px, 96px, auto; }
}
window.demo {
window {
background-image: url("resource://css_pixbufs/images/apple-red.png"),
url("resource://css_pixbufs/images/gnome-applets.png"),
url("resource://css_pixbufs/images/gnome-calendar.png"),
@@ -66,11 +66,11 @@ window.demo {
}
/* Make the text editor has a nice style */
window.demo .view, scrollbar, separator {
.view, scrollbar, separator {
color: black;
background-color: rgba(255,255,255,0.5);
}
window.demo .view:selected {
.view:selected {
background-color: rgba(127,127,255,0.5);
}

View File

@@ -5,6 +5,8 @@
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static void
show_parsing_error (GtkCssProvider *provider,
GtkCssSection *section,
@@ -46,23 +48,20 @@ css_text_changed (GtkTextBuffer *buffer,
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
gtk_css_provider_load_from_string (provider, text);
gtk_css_provider_load_from_data (provider, text, -1);
g_free (text);
}
static void
clear_provider (gpointer data)
{
GtkStyleProvider *provider = data;
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
}
static void
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
{
gtk_style_context_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
GtkWidget *child;
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
apply_css (child, provider);
}
static GtkWidget *
@@ -102,7 +101,6 @@ do_css_shadows (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Shadows");
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
gtk_widget_add_css_class (window, "demo");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
@@ -144,7 +142,7 @@ do_css_shadows (GtkWidget *do_widget)
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
gtk_widget_set_visible (window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (window));

View File

@@ -5,13 +5,12 @@
*/
/* This CSS resets all properties to their defaults values
* and overrides all user settings and the theme in use
*/
* and overrides all user settings and the theme in use */
@import url("resource://css_shadows/reset.css");
@import url("resource://css_shadows/cssview.css");
/* Get a nice background for the window */
window.demo.background {
.background {
background-color: #4870bc;
background-image: linear-gradient(to left, transparent, rgba(255,255,255,.07) 50%, transparent 50%),
linear-gradient(to left, transparent, rgba(255,255,255,.13) 50%, transparent 50%),
@@ -20,7 +19,7 @@ window.demo.background {
background-size: 29px, 59px, 73px, 109px;
}
window.demo button {
button {
color: black;
padding: 10px;
border-radius: 5px;
@@ -28,15 +27,18 @@ window.demo button {
border: 1px transparent solid;
}
window.demo button:hover {
button:hover {
text-shadow: 3px 3px 5px alpha(black, 0.75);
-gtk-icon-shadow: 3px 3px 5px alpha(black, 0.75);
box-shadow: 3px 3px 5px alpha(black, 0.5) inset;
border: solid 1px alpha(black, 0.75);
}
window.demo button:active {
button:active {
padding: 11px 9px 9px 11px;
text-shadow: 1px 1px 2.5px alpha(black, 0.6);
-gtk-icon-shadow: 1px 1px 2.5px alpha(black, 0.6);
}

View File

@@ -1,21 +1,21 @@
/* Make the text editor has a nice style */
window.demo .view {
.view {
color: #2e3436;
font-family: Monospace;
background-color: alpha(white, 0.30);
}
window.demo .view:selected {
.view:selected {
color: white;
background-color: #4a90d9;
}
window.demo scrollbar trough,
scrollbar trough,
.scrollbars-junction {
background-color: alpha(white, 0.80);
}
window.demo scrollbar slider {
scrollbar slider {
border-width: 3px;
border-style: solid;
border-radius: 10px;
@@ -24,11 +24,11 @@ window.demo scrollbar slider {
background-color: #999;
}
window.demo scrollbar slider:hover {
scrollbar slider:hover {
background-color: #555;
}
window.demo paned separator {
paned separator {
background-color: alpha(white, 0.80);
background-image: linear-gradient(transparent, transparent 1px, #999 1px, #999 4px, transparent 4px);
background-size: 40px auto;
@@ -36,6 +36,6 @@ window.demo paned separator {
background-position: center;
}
window.demo paned separator:hover {
paned separator:hover {
background-image: linear-gradient(transparent, transparent 1px, #555 1px, #555 4px, transparent 4px);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,36 @@
#pragma once
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define CURVE_TYPE_EDITOR (curve_editor_get_type ())
G_DECLARE_FINAL_TYPE (CurveEditor, curve_editor, CURVE, EDITOR, GtkWidget)
GtkWidget * curve_editor_new (void);
void curve_editor_set_edit (CurveEditor *self,
gboolean edit);
void curve_editor_set_path (CurveEditor *self,
GskPath *path);
GskPath * curve_editor_get_path (CurveEditor *self);
void curve_editor_set_stroke (CurveEditor *self,
GskStroke *stroke);
const GskStroke * curve_editor_get_stroke (CurveEditor *self);
void curve_editor_set_color (CurveEditor *self,
const GdkRGBA *color);
const GdkRGBA * curve_editor_get_color (CurveEditor *self);
gboolean curve_editor_get_show_outline (CurveEditor *self);
void curve_editor_set_show_outline (CurveEditor *self,
gboolean show_outline);
G_END_DECLS

269
demos/gtk-demo/curve.c Normal file
View File

@@ -0,0 +1,269 @@
/* Path/Curve Editor
*
* This demo shows an elaborate curve editor that you would expect to find
* in a vector graphics editor. It is built on top of GTK's path APIs.
*/
#include <gtk/gtk.h>
#include "curve-editor.h"
static GskPath *
make_circle_path (void)
{
float w = 310;
float h = 310;
float cx = w / 2;
float cy = h / 2;
float pad = 20;
float r = (w - 2 * pad) / 2;
float k = 0.55228;
float kr = k * r;
GskPathBuilder *builder;
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder, cx, pad);
gsk_path_builder_cubic_to (builder, cx + kr, pad,
w - pad, cy - kr,
w - pad, cy);
gsk_path_builder_cubic_to (builder, w - pad, cy + kr,
cx + kr, h - pad,
cx, h - pad);
gsk_path_builder_cubic_to (builder, cx - kr, h - pad,
pad, cy + kr,
pad, cy);
gsk_path_builder_cubic_to (builder, pad, cy - kr,
cx - kr, pad,
cx, pad);
gsk_path_builder_close (builder);
return gsk_path_builder_free_to_path (builder);
}
static void
edit_changed (GtkToggleButton *button,
GParamSpec *pspec,
CurveEditor *editor)
{
curve_editor_set_edit (editor, gtk_toggle_button_get_active (button));
}
static void
reset (GtkButton *button,
CurveEditor *editor)
{
GskPath *path;
path = make_circle_path ();
curve_editor_set_path (editor, path);
gsk_path_unref (path);
}
static void
line_width_changed (GtkSpinButton *spin,
CurveEditor *editor)
{
GskStroke *stroke;
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_line_width (stroke, gtk_spin_button_get_value (spin));
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
}
static void
cap_changed (GtkDropDown *combo,
GParamSpec *pspec,
CurveEditor *editor)
{
GskStroke *stroke;
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_line_cap (stroke, (GskLineCap)gtk_drop_down_get_selected (combo));
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
}
static void
join_changed (GtkDropDown *combo,
GParamSpec *pspec,
CurveEditor *editor)
{
GskStroke *stroke;
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_line_join (stroke, (GskLineJoin)gtk_drop_down_get_selected (combo));
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
}
static void
color_changed (GtkColorDialogButton *button,
GParamSpec *pspec,
CurveEditor *editor)
{
curve_editor_set_color (editor, gtk_color_dialog_button_get_rgba (button));
}
static void
stroke_toggled (GtkCheckButton *button,
CurveEditor *editor)
{
curve_editor_set_show_outline (editor, gtk_check_button_get_active (button));
gtk_widget_queue_draw (GTK_WIDGET (editor));
}
static void
limit_changed (GtkSpinButton *spin,
CurveEditor *editor)
{
GskStroke *stroke;
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_miter_limit (stroke, gtk_spin_button_get_value (spin));
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
}
static void
dashes_changed (GtkEntry *entry,
GParamSpec *spec,
CurveEditor *editor)
{
const char *text;
char **split;
GArray *dash;
GskStroke *stroke;
text = gtk_editable_get_text (GTK_EDITABLE (entry));
split = g_strsplit (text, " ", 0);
dash = g_array_new (FALSE, FALSE, sizeof (float));
for (int i = 0; split[i] != NULL; i++)
{
double d;
char *endp = 0;
d = g_strtod (split[i], &endp);
if (*endp == '\0')
g_array_append_vals (dash, (float[1]) { d }, 1);
}
g_strfreev (split);
stroke = gsk_stroke_copy (curve_editor_get_stroke (editor));
gsk_stroke_set_dash (stroke, (const float *)dash->data, dash->len);
curve_editor_set_stroke (editor, stroke);
gsk_stroke_free (stroke);
g_array_free (dash, TRUE);
}
GtkWidget *
do_curve (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
GtkWidget *demo;
GtkWidget *edit_toggle;
GtkWidget *reset_button;
GtkWidget *titlebar;
GtkWidget *stroke_toggle;
GtkWidget *line_width_spin;
GtkWidget *stroke_button;
GtkWidget *popover;
GtkWidget *grid;
GtkWidget *cap_combo;
GtkWidget *join_combo;
GtkWidget *color_button;
GtkWidget *limit_spin;
GtkWidget *dash_entry;
if (!window)
{
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Curve Editor");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
gtk_window_set_default_size (GTK_WINDOW (window), 315, 350);
edit_toggle = gtk_toggle_button_new ();
gtk_button_set_icon_name (GTK_BUTTON (edit_toggle), "document-edit-symbolic");
reset_button = gtk_button_new_from_icon_name ("edit-undo-symbolic");
stroke_button = gtk_menu_button_new ();
gtk_menu_button_set_icon_name (GTK_MENU_BUTTON (stroke_button), "open-menu-symbolic");
popover = gtk_popover_new ();
gtk_menu_button_set_popover (GTK_MENU_BUTTON (stroke_button), popover);
grid = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
gtk_popover_set_child (GTK_POPOVER (popover), grid);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Color:"), 0, 0, 1, 1);
color_button = gtk_color_dialog_button_new (gtk_color_dialog_new ());
gtk_grid_attach (GTK_GRID (grid), color_button, 1, 0, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Line width:"), 0, 1, 1, 1);
line_width_spin = gtk_spin_button_new_with_range (1, 20, 1);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (line_width_spin), 1);
gtk_grid_attach (GTK_GRID (grid), line_width_spin, 1, 1, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Line cap:"), 0, 2, 1, 1);
cap_combo = gtk_drop_down_new_from_strings ((const char *[]){"Butt", "Round", "Square", NULL});
gtk_grid_attach (GTK_GRID (grid), cap_combo, 1, 2, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Line join:"), 0, 3, 1, 1);
join_combo = gtk_drop_down_new_from_strings ((const char *[]){"Miter", "Miter-clip", "Round", "Bevel", "Arcs", NULL});
gtk_grid_attach (GTK_GRID (grid), join_combo, 1, 3, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Miter limit:"), 0, 4, 1, 1);
limit_spin = gtk_spin_button_new_with_range (0, 10, 1);
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (limit_spin), 1);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (limit_spin), 4);
gtk_grid_attach (GTK_GRID (grid), limit_spin, 1, 4, 1, 1);
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Dashes:"), 0, 5, 1, 1);
dash_entry = gtk_entry_new ();
gtk_grid_attach (GTK_GRID (grid), dash_entry, 1, 5, 1, 1);
stroke_toggle = gtk_check_button_new_with_label ("Show outline");
gtk_grid_attach (GTK_GRID (grid), stroke_toggle, 1, 6, 1, 1);
titlebar = gtk_header_bar_new ();
gtk_header_bar_pack_start (GTK_HEADER_BAR (titlebar), edit_toggle);
gtk_header_bar_pack_start (GTK_HEADER_BAR (titlebar), reset_button);
gtk_header_bar_pack_start (GTK_HEADER_BAR (titlebar), stroke_button);
gtk_window_set_titlebar (GTK_WINDOW (window), titlebar);
demo = curve_editor_new ();
g_signal_connect (stroke_toggle, "toggled", G_CALLBACK (stroke_toggled), demo);
g_signal_connect (edit_toggle, "notify::active", G_CALLBACK (edit_changed), demo);
g_signal_connect (reset_button, "clicked", G_CALLBACK (reset), demo);
g_signal_connect (cap_combo, "notify::selected", G_CALLBACK (cap_changed), demo);
g_signal_connect (join_combo, "notify::selected", G_CALLBACK (join_changed), demo);
g_signal_connect (color_button, "notify::rgba", G_CALLBACK (color_changed), demo);
g_signal_connect (line_width_spin, "value-changed", G_CALLBACK (line_width_changed), demo);
g_signal_connect (limit_spin, "value-changed", G_CALLBACK (limit_changed), demo);
g_signal_connect (dash_entry, "notify::text", G_CALLBACK (dashes_changed), demo);
reset (NULL, CURVE_EDITOR (demo));
gtk_spin_button_set_value (GTK_SPIN_BUTTON (line_width_spin), 6);
gtk_color_dialog_button_set_rgba (GTK_COLOR_DIALOG_BUTTON (color_button), &(GdkRGBA) { 1, 0, 0, 1 });
gtk_drop_down_set_selected (GTK_DROP_DOWN (cap_combo), GSK_LINE_CAP_ROUND);
gtk_editable_set_text (GTK_EDITABLE (dash_entry), "0 8");
gtk_window_set_child (GTK_WINDOW (window), demo);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -259,6 +259,10 @@
<gresource prefix="/video-player">
<file>bbb.png</file>
</gresource>
<gresource prefix="/curve">
<file>curve-editor.c</file>
<file>curve-editor.h</file>
</gresource>
<gresource prefix="/sources">
<file>application_demo.c</file>
<file>assistant.c</file>
@@ -276,6 +280,7 @@
<file>css_pixbufs.c</file>
<file>css_shadows.c</file>
<file>cursors.c</file>
<file>curve.c</file>
<file>dialog.c</file>
<file>drawingarea.c</file>
<file>dnd.c</file>
@@ -295,6 +300,7 @@
<file>gears.c</file>
<file>gestures.c</file>
<file>glarea.c</file>
<file>glyphs.c</file>
<file>gltransition.c</file>
<file>headerbar.c</file>
<file>hypertext.c</file>
@@ -338,8 +344,6 @@
<file>password_entry.c</file>
<file>path_fill.c</file>
<file>path_maze.c</file>
<file>path_spinner.c</file>
<file>path_walk.c</file>
<file>path_text.c</file>
<file>peg_solitaire.c</file>
<file>pickers.c</file>
@@ -426,10 +430,6 @@
<gresource prefix="/fontrendering">
<file>fontrendering.ui</file>
</gresource>
<gresource prefix="/path_walk">
<file>path_walk.ui</file>
<file compressed="true">path_world.txt</file>
</gresource>
<gresource prefix="/path_text">
<file>path_text.ui</file>
</gresource>

View File

@@ -208,13 +208,7 @@
</object>
</child>
<child>
<object class="GtkLabel" id="statusbar1">
<property name="xalign">0</property>
<property name="margin-start">2</property>
<property name="margin-end">2</property>
<property name="margin-top">2</property>
<property name="margin-bottom">2</property>
</object>
<object class="GtkStatusbar" id="statusbar1"/>
</child>
</object>
</child>

View File

@@ -34,7 +34,7 @@ transition (GtkWidget *widget,
{
DemoWidget *self = DEMO_WIDGET (widget);
DemoLayout *demo_layout = DEMO_LAYOUT (gtk_widget_get_layout_manager (widget));
gint64 now = gdk_frame_clock_get_frame_time (frame_clock);
gint64 now = g_get_monotonic_time ();
gtk_widget_queue_allocate (widget);
@@ -66,13 +66,11 @@ clicked (GtkGestureClick *gesture,
gpointer data)
{
DemoWidget *self = data;
GdkFrameClock *frame_clock;
if (self->tick_id != 0)
return;
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
self->start_time = gdk_frame_clock_get_frame_time (frame_clock);
self->start_time = g_get_monotonic_time ();
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self), transition, NULL, NULL);
}

View File

@@ -162,39 +162,27 @@ click_done (GtkGesture *gesture)
gtk_widget_insert_after (item, canvas, last_child);
}
/* GtkSettings treats `GTK_THEME=foo:dark` as theme name `foo`, variant `dark`,
* and our embedded CSS files let `foo-dark` work as an alias for `foo:dark`. */
static gboolean
has_dark_suffix (const char *theme)
{
return g_str_has_suffix (theme, ":dark") ||
g_str_has_suffix (theme, "-dark");
}
/* So we can make a good guess whether the current theme is dark by checking for
* either: it is suffixed `[:-]dark`, or Settings:…prefer-dark-theme is TRUE. */
static gboolean
theme_is_dark (void)
{
const char *env_theme;
GtkSettings *settings;
char *theme;
gboolean prefer_dark;
gboolean dark;
/* Like GtkSettings, 1st see if theme is overridden by environment variable */
env_theme = g_getenv ("GTK_THEME");
if (env_theme != NULL)
return has_dark_suffix (env_theme);
/* If not, test Settings:…theme-name in the same way OR :…prefer-dark-theme */
settings = gtk_settings_get_default ();
g_object_get (settings,
"gtk-theme-name", &theme,
"gtk-application-prefer-dark-theme", &prefer_dark,
NULL);
dark = prefer_dark || has_dark_suffix (theme);
if ((strcmp (theme, "Adwaita") == 0 && prefer_dark) || strcmp (theme, "HighContrastInverse") == 0)
dark = TRUE;
else
dark = FALSE;
g_free (theme);
return dark;
}
@@ -760,7 +748,9 @@ do_dnd (GtkWidget *do_widget)
GtkCssProvider *provider;
GString *css;
button = gtk_color_dialog_button_new (gtk_color_dialog_new ());
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
button = gtk_color_button_new ();
G_GNUC_END_IGNORE_DEPRECATIONS
g_object_unref (g_object_ref_sink (button));
provider = gtk_css_provider_new ();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -10,6 +10,8 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static GtkWidget *window = NULL;
static void
@@ -43,22 +45,21 @@ do_expander (GtkWidget *do_widget)
if (!window)
{
toplevel = GTK_WIDGET (gtk_widget_get_root (do_widget));
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Expander");
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (toplevel));
area = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
gtk_widget_set_margin_start (area, 10);
gtk_widget_set_margin_end (area, 10);
gtk_widget_set_margin_top (area, 10);
gtk_widget_set_margin_bottom (area, 10);
gtk_window_set_child (GTK_WINDOW (window), area);
label = gtk_label_new ("<big><b>Something went wrong</b></big>");
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
gtk_box_append (GTK_BOX (area), label);
label = gtk_label_new ("Here are some more details but not the full story");
window = gtk_message_dialog_new_with_markup (GTK_WINDOW (toplevel),
0,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"<big><b>%s</b></big>",
"Something went wrong");
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (window),
"Here are some more details "
"but not the full story.");
area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (window));
label = gtk_widget_get_last_child (area);
gtk_label_set_wrap (GTK_LABEL (label), FALSE);
gtk_widget_set_vexpand (label, FALSE);
gtk_box_append (GTK_BOX (area), label);
expander = gtk_expander_new ("Details:");
gtk_widget_set_vexpand (expander, TRUE);
@@ -121,7 +122,7 @@ do_expander (GtkWidget *do_widget)
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
gtk_widget_set_visible (window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (window));

View File

@@ -71,11 +71,13 @@ create_blurred_button (void)
return w;
}
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static GtkWidget *
create_font_button (void)
{
return gtk_font_dialog_button_new (gtk_font_dialog_new ());
return gtk_font_button_new ();
}
G_GNUC_END_IGNORE_DEPRECATIONS
static GtkWidget *
create_level_bar (void)
@@ -325,20 +327,11 @@ do_fishbowl (GtkWidget *do_widget)
if (!window)
{
GtkBuilder *builder;
GtkBuilderScope *scope;
GtkWidget *bowl;
g_type_ensure (GTK_TYPE_FISHBOWL);
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), fishbowl_prev_button_clicked_cb);
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), fishbowl_next_button_clicked_cb);
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), fishbowl_changes_toggled_cb);
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), format_header_cb);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
gtk_builder_add_from_resource (builder, "/fishbowl/fishbowl.ui", NULL);
builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
@@ -350,7 +343,6 @@ do_fishbowl (GtkWidget *do_widget)
gtk_widget_realize (window);
g_object_unref (builder);
g_object_unref (scope);
}
if (!gtk_widget_get_visible (window))

1182
demos/gtk-demo/glyphs.c Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -7,6 +7,7 @@ struct _GraphWidget
GskPath *path;
GskStroke *stroke;
GdkRGBA color;
GskPath *stroke_path;
guint tick_cb;
guint64 start_time;
@@ -30,6 +31,7 @@ update_path (GraphWidget *self,
GskPathBuilder *builder;
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->stroke_path, gsk_path_unref);
for (int i = 0; i < 20; i++)
{
@@ -55,6 +57,7 @@ update_path (GraphWidget *self,
p[i+3].x, p[i+3].y);
self->path = gsk_path_builder_free_to_path (builder);
self->stroke_path = gsk_path_stroke (self->path, self->stroke);
}
static gboolean
@@ -103,7 +106,7 @@ graph_widget_dispose (GObject *object)
{
GraphWidget *self = GRAPH_WIDGET (object);
g_clear_pointer (&self->path, gsk_path_unref);
gsk_path_unref (self->path);
gsk_stroke_free (self->stroke);
G_OBJECT_CLASS (graph_widget_parent_class)->dispose (object);
@@ -114,8 +117,16 @@ graph_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GraphWidget *self = GRAPH_WIDGET (widget);
int width, height;
gtk_snapshot_append_stroke (snapshot, self->path, self->stroke, &self->color);
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
gtk_snapshot_push_fill (snapshot, self->stroke_path, GSK_FILL_RULE_WINDING);
gtk_snapshot_append_color (snapshot,
&self->color,
&GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
}
static void

View File

@@ -840,24 +840,24 @@ gtk_gears_unrealize (GtkWidget *widget)
GtkGearsPrivate *priv = gtk_gears_get_instance_private ((GtkGears *) widget);
gtk_gl_area_make_current (glarea);
if (gtk_gl_area_get_error (glarea) == NULL)
{
/* Release the resources associated with OpenGL */
if (priv->gear_vbo[0] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[0]));
if (gtk_gl_area_get_error (glarea) != NULL)
return;
if (priv->gear_vbo[1] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[1]));
/* Release the resources associated with OpenGL */
if (priv->gear_vbo[0] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[0]));
if (priv->gear_vbo[2] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[2]));
if (priv->gear_vbo[1] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[1]));
if (priv->vao != 0)
glDeleteVertexArrays (1, &priv->vao);
if (priv->gear_vbo[2] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[2]));
if (priv->program != 0)
glDeleteProgram (priv->program);
}
if (priv->vao != 0)
glDeleteVertexArrays (1, &priv->vao);
if (priv->program != 0)
glDeleteProgram (priv->program);
priv->ModelViewProjectionMatrix_location = 0;
priv->NormalMatrix_location = 0;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -354,18 +354,10 @@ do_iconscroll (GtkWidget *do_widget)
if (!window)
{
GtkBuilder *builder;
GtkBuilderScope *scope;
GtkWidget *label;
guint id;
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), iconscroll_prev_clicked_cb);
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), iconscroll_next_clicked_cb);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
gtk_builder_add_from_resource (builder, "/iconscroll/iconscroll.ui", NULL);
builder = gtk_builder_new_from_resource ("/iconscroll/iconscroll.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
gtk_window_set_display (GTK_WINDOW (window),
@@ -383,7 +375,6 @@ do_iconscroll (GtkWidget *do_widget)
GUINT_TO_POINTER (id), remove_timeout);
g_object_unref (builder);
g_object_unref (scope);
}
if (!gtk_widget_get_visible (window))

View File

@@ -52,10 +52,6 @@ setup_listitem_cb (GtkListItemFactory *factory,
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
image = gtk_image_new ();
gtk_accessible_update_property (GTK_ACCESSIBLE (image),
GTK_ACCESSIBLE_PROPERTY_LABEL,
"App icon",
-1);
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
gtk_box_append (GTK_BOX (box), image);
label = gtk_label_new ("");
@@ -83,7 +79,6 @@ bind_listitem_cb (GtkListItemFactory *factory,
gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (app_info));
gtk_label_set_label (GTK_LABEL (label), g_app_info_get_display_name (app_info));
gtk_list_item_set_accessible_label (list_item, g_app_info_get_display_name (app_info));
}
/* In more complex code, we would also need functions to unbind and teardown

View File

@@ -431,9 +431,6 @@ setup_listitem_cb (GtkListItemFactory *factory,
picture = gtk_picture_new ();
gtk_expression_bind (expression, picture, "paintable", picture);
gtk_box_append (GTK_BOX (box), picture);
gtk_accessible_update_relation (GTK_ACCESSIBLE (picture),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, location_label, NULL,
-1);
/* And finally, everything comes together.
@@ -490,9 +487,6 @@ do_listview_clocks (GtkWidget *do_widget)
model = GTK_SELECTION_MODEL (gtk_no_selection_new (create_clocks_model ()));
gridview = gtk_grid_view_new (model, factory);
gtk_accessible_update_property (GTK_ACCESSIBLE (gridview),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Clocks",
-1);
gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
gtk_scrollable_set_vscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);

View File

@@ -17,6 +17,7 @@ demos = files([
'css_pixbufs.c',
'css_shadows.c',
'cursors.c',
'curve.c',
'dialog.c',
'drawingarea.c',
'dnd.c',
@@ -34,6 +35,7 @@ demos = files([
'gestures.c',
'glarea.c',
'gltransition.c',
'glyphs.c',
'headerbar.c',
'hypertext.c',
'iconscroll.c',
@@ -74,8 +76,6 @@ demos = files([
'password_entry.c',
'path_fill.c',
'path_maze.c',
'path_spinner.c',
'path_walk.c',
'path_text.c',
'peg_solitaire.c',
'pickers.c',
@@ -143,6 +143,7 @@ extra_demo_sources = files([
'language-names.c',
'nodewidget.c',
'graphwidget.c',
'curve-editor.c',
])
if os_unix
@@ -157,13 +158,25 @@ if librsvg_dep.found()
gtkdemo_deps += [ librsvg_dep ]
endif
gtkdemo_args = [ '-DGDK_DISABLE_DEPRECATED', '-DGTK_DISABLE_DEPRECATED', ]
demos_h = custom_target('gtk4 demo header',
output: 'demos.h',
input: demos,
command: [ find_program('geninclude.py'), '@OUTPUT@', '@INPUT@' ],
)
if can_use_objcopy_for_resources
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol')
endif
ld = find_program('ld', required : false)
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
# Create the resource blob
gtkdemo_gresource = custom_target('gtkdemo.gresource',
input : 'demo.gresource.xml',
@@ -211,7 +224,6 @@ if can_use_objcopy_for_resources
output : 'gtkdemo_resources2.o',
command : [objcopy,
'--strip-all',
'--set-section-alignment', '.data=8',
'--add-symbol','_g_binary_gtkdemo_resource_data=.data:0',
'@INPUT@',
'@OUTPUT@'])
@@ -240,7 +252,7 @@ gtkdemo_deps += [ demo_conf_h ]
executable('gtk4-demo',
sources: [demos, demos_h, extra_demo_sources, gtkdemo_resources],
c_args: demo_cflags,
c_args: gtkdemo_args + demo_cflags,
dependencies: gtkdemo_deps,
include_directories: confinc,
win_subsystem: 'windows',
@@ -250,7 +262,7 @@ executable('gtk4-demo',
executable('gtk4-demo-application',
sources: ['application.c', gtkdemo_resources],
c_args: common_cflags,
c_args: gtkdemo_args + common_cflags,
dependencies: gtkdemo_deps,
include_directories: confinc,
win_subsystem: 'windows',

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -7,6 +7,8 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
enum {
COLOR_SET,
N_SIGNALS
@@ -122,16 +124,19 @@ drawing_area_unmap (GtkWidget *widget)
static void
drawing_area_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
GtkSnapshot *snapshot)
{
DrawingArea *area = (DrawingArea *) widget;
int width, height;
GtkAllocation allocation;
cairo_t *cr;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_widget_get_allocation (widget, &allocation);
cr = gtk_snapshot_append_cairo (snapshot,
&GRAPHENE_RECT_INIT (
0, 0,
allocation.width,
allocation.height
));
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
@@ -140,7 +145,7 @@ drawing_area_snapshot (GtkWidget *widget,
cairo_paint (cr);
cairo_set_source_rgb (cr, 0.6, 0.6, 0.6);
cairo_rectangle (cr, 0, 0, width, height);
cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
cairo_stroke (cr);
cairo_destroy (cr);

View File

@@ -1,254 +1,310 @@
/* Path/Fill and Stroke
/* Path/Fill
*
* This demo shows how to use GskPath to draw shapes that are (a bit)
* more complex than a rounded rectangle.
*
* It also demonstrates printing to a stream with GtkPrintDialog.
* This demo shows how to use PangoCairo to draw text with more than
* just a single color.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <cairo-pdf.h>
#include "paintable.h"
#define GTK_TYPE_LOGO_PAINTABLE (gtk_logo_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GtkLogoPaintable, gtk_logo_paintable, GTK, LOGO_PAINTABLE, GObject)
#define GTK_TYPE_PATH_PAINTABLE (gtk_path_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathPaintable, gtk_path_paintable, GTK, PATH_PAINTABLE, GObject)
struct _GtkLogoPaintable
struct _GtkPathPaintable
{
GObject parent_instance;
int width;
int height;
GskPath *path[3];
GdkRGBA color[3];
GskPath *stroke_path;
GskStroke *stroke1;
GskStroke *stroke2;
GdkRGBA stroke_color;
GskPath *path;
GdkPaintable *background;
};
struct _GtkLogoPaintableClass
struct _GtkPathPaintableClass
{
GObjectClass parent_class;
};
static int
gtk_logo_paintable_get_intrinsic_width (GdkPaintable *paintable)
gtk_path_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (paintable);
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
return self->width;
if (self->background)
return MAX (gdk_paintable_get_intrinsic_width (self->background), self->width);
else
return self->width;
}
static int
gtk_logo_paintable_get_intrinsic_height (GdkPaintable *paintable)
gtk_path_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (paintable);
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
return self->height;
if (self->background)
return MAX (gdk_paintable_get_intrinsic_height (self->background), self->height);
else
return self->height;
}
static void
gtk_logo_paintable_snapshot (GdkPaintable *paintable,
gtk_path_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (paintable);
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
for (unsigned int i = 0; i < 3; i++)
#if 0
gtk_snapshot_push_fill (snapshot, self->path, GSK_FILL_RULE_WINDING);
#else
GskStroke *stroke = gsk_stroke_new (2.0);
gtk_snapshot_push_stroke (snapshot, self->path, stroke);
gsk_stroke_free (stroke);
#endif
if (self->background)
{
gtk_snapshot_push_fill (snapshot, self->path[i], GSK_FILL_RULE_WINDING);
gtk_snapshot_append_color (snapshot,
&self->color[i],
&GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
gdk_paintable_snapshot (self->background, snapshot, width, height);
}
for (unsigned int i = 0; i < 3; i++)
else
{
gtk_snapshot_push_stroke (snapshot, self->stroke_path, self->stroke1);
gtk_snapshot_append_color (snapshot,
&self->stroke_color,
&GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
gtk_snapshot_append_linear_gradient (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
&GRAPHENE_POINT_INIT (0, 0),
&GRAPHENE_POINT_INIT (width, height),
(GskColorStop[8]) {
{ 0.0, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.2, { 1.0, 0.0, 0.0, 1.0 } },
{ 0.3, { 1.0, 1.0, 0.0, 1.0 } },
{ 0.4, { 0.0, 1.0, 0.0, 1.0 } },
{ 0.6, { 0.0, 1.0, 1.0, 1.0 } },
{ 0.7, { 0.0, 0.0, 1.0, 1.0 } },
{ 0.8, { 1.0, 0.0, 1.0, 1.0 } },
{ 1.0, { 1.0, 0.0, 1.0, 1.0 } }
},
8);
}
gtk_snapshot_push_stroke (snapshot, self->stroke_path, self->stroke2);
gtk_snapshot_append_color (snapshot,
&self->stroke_color,
&GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
}
static GdkPaintableFlags
gtk_logo_paintable_get_flags (GdkPaintable *paintable)
gtk_path_paintable_get_flags (GdkPaintable *paintable)
{
return GDK_PAINTABLE_STATIC_CONTENTS | GDK_PAINTABLE_STATIC_SIZE;
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
if (self->background)
return gdk_paintable_get_flags (self->background);
else
return GDK_PAINTABLE_STATIC_CONTENTS | GDK_PAINTABLE_STATIC_SIZE;
}
static void
gtk_logo_paintable_paintable_init (GdkPaintableInterface *iface)
gtk_path_paintable_paintable_init (GdkPaintableInterface *iface)
{
iface->get_intrinsic_width = gtk_logo_paintable_get_intrinsic_width;
iface->get_intrinsic_height = gtk_logo_paintable_get_intrinsic_height;
iface->snapshot = gtk_logo_paintable_snapshot;
iface->get_flags = gtk_logo_paintable_get_flags;
iface->get_intrinsic_width = gtk_path_paintable_get_intrinsic_width;
iface->get_intrinsic_height = gtk_path_paintable_get_intrinsic_height;
iface->snapshot = gtk_path_paintable_snapshot;
iface->get_flags = gtk_path_paintable_get_flags;
}
/* When defining the GType, we need to implement the GdkPaintable interface */
G_DEFINE_TYPE_WITH_CODE (GtkLogoPaintable, gtk_logo_paintable, G_TYPE_OBJECT,
G_DEFINE_TYPE_WITH_CODE (GtkPathPaintable, gtk_path_paintable, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_logo_paintable_paintable_init))
gtk_path_paintable_paintable_init))
static void
gtk_logo_paintable_dispose (GObject *object)
/* Here's the boilerplate for the GObject declaration.
* We need to disconnect the signals here that we set up elsewhere
*/
static void
gtk_path_paintable_dispose (GObject *object)
{
GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (object);
GtkPathPaintable *self = GTK_PATH_PAINTABLE (object);
for (unsigned int i = 0; i < 3; i++)
gsk_path_unref (self->path[i]);
if (self->background)
{
g_signal_handlers_disconnect_by_func (self->background, gdk_paintable_invalidate_contents, self);
g_signal_handlers_disconnect_by_func (self->background, gdk_paintable_invalidate_size, self);
g_clear_object (&self->background);
}
gsk_path_unref (self->stroke_path);
gsk_stroke_free (self->stroke1);
gsk_stroke_free (self->stroke2);
G_OBJECT_CLASS (gtk_logo_paintable_parent_class)->dispose (object);
G_OBJECT_CLASS (gtk_path_paintable_parent_class)->dispose (object);
}
static void
gtk_logo_paintable_class_init (GtkLogoPaintableClass *klass)
gtk_path_paintable_class_init (GtkPathPaintableClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_logo_paintable_dispose;
object_class->dispose = gtk_path_paintable_dispose;
}
static void
gtk_logo_paintable_init (GtkLogoPaintable *self)
gtk_path_paintable_init (GtkPathPaintable *self)
{
}
static GdkPaintable *
gtk_logo_paintable_new (void)
/* And finally, we add a simple constructor.
* It is declared in the header so that the other examples
* can use it.
*/
GdkPaintable *
gtk_path_paintable_new (GskPath *path,
GdkPaintable *background,
int width,
int height)
{
GtkLogoPaintable *self;
graphene_rect_t bounds, bounds2;
GtkPathPaintable *self;
self = g_object_new (GTK_TYPE_LOGO_PAINTABLE, NULL);
/* Paths and colors extracted from gtk-logo.svg */
self->path[0] = gsk_path_parse ("m3.12,66.17 -2.06,-51.46 32.93,24.7 v55.58 l-30.87,-28.82 z");
self->path[1] = gsk_path_parse ("m34,95 49.4,-20.58 4.12,-51.46 -53.52,16.47 v55.58 z");
self->path[2] = gsk_path_parse ("m1.06,14.71 32.93,24.7 53.52,-16.47 -36.75,-21.88 -49.7,13.65 z");
gdk_rgba_parse (&self->color[0], "#e40000");
gdk_rgba_parse (&self->color[1], "#7fe719");
gdk_rgba_parse (&self->color[2], "#729fcf");
self->stroke_path = gsk_path_parse ("m50.6,51.3 -47.3,14 z l33,23 z v-50");
self->stroke1 = gsk_stroke_new (2.12);
self->stroke2 = gsk_stroke_new (1.25);
gdk_rgba_parse (&self->stroke_color, "#ffffff");
gsk_path_get_stroke_bounds (self->path[0], self->stroke1, &bounds);
gsk_path_get_stroke_bounds (self->path[1], self->stroke1, &bounds2);
graphene_rect_union (&bounds, &bounds2, &bounds);
gsk_path_get_stroke_bounds (self->path[2], self->stroke1, &bounds2);
graphene_rect_union (&bounds, &bounds2, &bounds);
gsk_path_get_stroke_bounds (self->stroke_path, self->stroke2, &bounds2);
graphene_rect_union (&bounds, &bounds2, &bounds);
self->width = bounds.origin.x + bounds.size.width;
self->height = bounds.origin.y + bounds.size.height;
self = g_object_new (GTK_TYPE_PATH_PAINTABLE, NULL);
self->path = path;
self->background = background;
if (self->background)
{
g_object_ref (self->background);
g_signal_connect_swapped (self->background, "invalidate-contents", G_CALLBACK (gdk_paintable_invalidate_contents), self);
g_signal_connect_swapped (self->background, "invalidate-size", G_CALLBACK (gdk_paintable_invalidate_size), self);
}
self->width = width;
self->height = height;
return GDK_PAINTABLE (self);
}
static cairo_status_t
write_cairo (void *closure,
const unsigned char *data,
unsigned int length)
void
gtk_path_paintable_set_path (GtkPathPaintable *self,
GskPath *path)
{
GOutputStream *stream = closure;
gsize written;
GError *error = NULL;
g_clear_pointer (&self->path, gsk_path_unref);
self->path = gsk_path_ref (path);
if (!g_output_stream_write_all (stream, data, length, &written, NULL, &error))
{
g_print ("Error writing pdf stream: %s\n", error->message);
g_error_free (error);
return CAIRO_STATUS_WRITE_ERROR;
}
return CAIRO_STATUS_SUCCESS;
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
}
static void
print_ready (GObject *source,
GAsyncResult *result,
gpointer data)
static GskPath *
create_hexagon (GtkWidget *widget)
{
GtkPrintDialog *dialog = GTK_PRINT_DIALOG (source);
GError *error = NULL;
GOutputStream *stream;
GtkSnapshot *snapshot;
GdkPaintable *paintable;
GskRenderNode *node;
cairo_surface_t *surface;
cairo_t *cr;
GskPathBuilder *builder;
stream = gtk_print_dialog_print_finish (dialog, result, &error);
if (stream == NULL)
{
g_print ("Failed to get output stream: %s\n", error->message);
g_error_free (error);
return;
}
builder = gsk_path_builder_new ();
snapshot = gtk_snapshot_new ();
paintable = gtk_picture_get_paintable (GTK_PICTURE (data));
gdk_paintable_snapshot (paintable, snapshot, 100, 100);
node = gtk_snapshot_free_to_node (snapshot);
gsk_path_builder_move_to (builder, 120, 0);
gsk_path_builder_line_to (builder, 360, 0);
gsk_path_builder_line_to (builder, 480, 208);
gsk_path_builder_line_to (builder, 360, 416);
gsk_path_builder_line_to (builder, 120, 416);
gsk_path_builder_line_to (builder, 0, 208);
gsk_path_builder_close (builder);
surface = cairo_pdf_surface_create_for_stream (write_cairo, stream, 100, 100);
cr = cairo_create (surface);
gsk_render_node_draw (node, cr);
cairo_destroy (cr);
cairo_surface_destroy (surface);
gsk_render_node_unref (node);
if (!g_output_stream_close (stream, NULL, &error))
{
g_print ("Error from close: %s\n", error->message);
g_error_free (error);
}
g_object_unref (stream);
return gsk_path_builder_free_to_path (builder);
}
static void
print (GtkButton *button,
gpointer data)
static GskPath *
create_path_from_text (GtkWidget *widget)
{
GtkWidget *picture = data;
GtkPrintDialog *dialog;
PangoLayout *layout;
PangoFontDescription *desc;
GskPathBuilder *builder;
dialog = gtk_print_dialog_new ();
layout = gtk_widget_create_pango_layout (widget, "Pango power!\nPango power!\nPango power!");
desc = pango_font_description_from_string ("sans bold 36");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
gtk_print_dialog_print (dialog,
GTK_WINDOW (gtk_widget_get_root (picture)),
NULL,
NULL,
print_ready,
picture);
builder = gsk_path_builder_new ();
g_object_unref (dialog);
gsk_path_builder_add_layout (builder, layout);
return gsk_path_builder_free_to_path (builder);
}
static gboolean
build_path (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data)
{
GskPathBuilder *builder = user_data;
switch (op)
{
case GSK_PATH_MOVE:
gsk_path_builder_move_to (builder, pts[0].x, pts[0].y);
break;
case GSK_PATH_CLOSE:
gsk_path_builder_close (builder);
break;
case GSK_PATH_LINE:
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
break;
case GSK_PATH_QUAD:
gsk_path_builder_quad_to (builder, pts[1].x, pts[1].y, pts[2].x, pts[2].y);
break;
case GSK_PATH_CUBIC:
gsk_path_builder_cubic_to (builder, pts[1].x, pts[1].y, pts[2].x, pts[2].y, pts[3].x, pts[3].y);
break;
case GSK_PATH_CONIC:
gsk_path_builder_conic_to (builder, pts[1].x, pts[1].y, pts[2].x, pts[2].y, weight);
break;
default:
g_assert_not_reached ();
break;
}
return TRUE;
}
static gboolean
update_path (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer measure)
{
float progress = gdk_frame_clock_get_frame_time (frame_clock) % (60 * G_USEC_PER_SEC) / (float) (30 * G_USEC_PER_SEC);
GskPathBuilder *builder;
GskPath *path;
GskPathPoint *point;
graphene_point_t pos;
graphene_vec2_t tangent;
GskStroke *stroke;
path = gsk_path_measure_get_path (measure);
stroke = gsk_stroke_new (1);
gsk_stroke_set_dash (stroke, (float[2]) { 10, 5 }, 2);
gsk_stroke_set_dash_offset (stroke, - (gdk_frame_clock_get_frame_time (frame_clock) % G_USEC_PER_SEC) * 15. / G_USEC_PER_SEC);
builder = gsk_path_builder_new ();
gsk_path_dash (path, stroke, 0.2, build_path, builder);
point = gsk_path_measure_get_point (measure,
(progress > 1 ? (progress - 1) : progress) * gsk_path_measure_get_length (measure));
gsk_path_point_get_position (point, &pos);
gsk_path_point_get_tangent (point, GSK_PATH_END, &tangent);
gsk_path_point_unref (point);
gsk_path_builder_move_to (builder, pos.x + 5 * graphene_vec2_get_x (&tangent), pos.y + 5 * graphene_vec2_get_y (&tangent));
gsk_path_builder_line_to (builder, pos.x + 3 * graphene_vec2_get_y (&tangent), pos.y + 3 * graphene_vec2_get_x (&tangent));
gsk_path_builder_line_to (builder, pos.x - 3 * graphene_vec2_get_y (&tangent), pos.y - 3 * graphene_vec2_get_x (&tangent));
gsk_path_builder_close (builder);
path = gsk_path_builder_free_to_path (builder);
gtk_path_paintable_set_path (GTK_PATH_PAINTABLE (gtk_picture_get_paintable (GTK_PICTURE (widget))),
path);
gsk_path_unref (path);
return G_SOURCE_CONTINUE;
}
GtkWidget *
@@ -258,31 +314,41 @@ do_path_fill (GtkWidget *do_widget)
if (!window)
{
GtkWidget *header, *button, *label;
GtkWidget *picture;
GdkPaintable *paintable;
GtkMediaStream *stream;
GskPath *path;
graphene_rect_t bounds;
GskPathMeasure *measure;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
gtk_window_set_default_size (GTK_WINDOW (window), 100, 100);
gtk_window_set_title (GTK_WINDOW (window), "Fill and Stroke");
header = gtk_header_bar_new ();
button = gtk_button_new_from_icon_name ("printer-symbolic");
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
label = gtk_label_new ("Fill and Stroke");
gtk_widget_add_css_class (label, "title");
gtk_header_bar_set_title_widget (GTK_HEADER_BAR (header), label);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Path Fill");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
paintable = gtk_logo_paintable_new ();
#if 0
stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
#else
stream = gtk_nuclear_media_stream_new ();
#endif
gtk_media_stream_play (stream);
gtk_media_stream_set_loop (stream, TRUE);
path = create_hexagon (window);
path = create_path_from_text (window);
gsk_path_get_bounds (path, &bounds);
paintable = gtk_path_paintable_new (path,
GDK_PAINTABLE (stream),
bounds.origin.x + bounds.size.width,
bounds.origin.y + bounds.size.height);
picture = gtk_picture_new_for_paintable (paintable);
measure = gsk_path_measure_new (path);
gtk_widget_add_tick_callback (picture, update_path, measure, (GDestroyNotify) gsk_path_measure_unref);
gtk_picture_set_content_fit (GTK_PICTURE (picture), GTK_CONTENT_FIT_CONTAIN);
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
g_object_unref (paintable);
g_signal_connect (button, "clicked", G_CALLBACK (print), picture);
gtk_window_set_child (GTK_WINDOW (window), picture);
}

View File

@@ -1,14 +1,13 @@
/* Path/Maze
*
* This demo shows how to use a GskPath to create a maze and use
* gsk_path_get_closest_point() to check the mouse stays
* gsk_path_measure_get_closest_point() to check the mouse stays
* on the path.
*
* It also shows off the performance of GskPath (or not) as this
* is a rather complex path.
*/
#include "config.h"
#include <glib/gi18n.h>
#include <gtk/gtk.h>
@@ -132,47 +131,24 @@ gtk_maze_class_init (GtkMazeClass *klass)
widget_class->snapshot = gtk_maze_snapshot;
}
static void
celebrate (gboolean win)
{
char *path;
GtkMediaStream *stream;
if (win)
path = g_build_filename (GTK_DATADIR, "sounds", "freedesktop", "stereo", "complete.oga", NULL);
else
path = g_build_filename (GTK_DATADIR, "sounds", "freedesktop", "stereo", "suspend-error.oga", NULL);
stream = gtk_media_file_new_for_filename (path);
gtk_media_stream_set_volume (stream, 1.0);
gtk_media_stream_play (stream);
g_signal_connect (stream, "notify::ended", G_CALLBACK (g_object_unref), NULL);
g_free (path);
}
static void
pointer_motion (GtkEventControllerMotion *controller,
double x,
double y,
GtkMaze *self)
{
GskPathPoint point;
float distance;
GskPathPoint *point;
graphene_point_t pos;
if (!self->active)
return;
if (gsk_path_get_closest_point (self->path,
&GRAPHENE_POINT_INIT (x, y),
INFINITY,
&point,
&distance))
{
if (distance < MAZE_STROKE_SIZE_ACTIVE / 2.f)
return;
}
point = gsk_path_measure_get_closest_point (self->measure, &GRAPHENE_POINT_INIT (x, y), INFINITY);
gsk_path_point_get_position (point, &pos);
gsk_path_point_unref (point);
celebrate (FALSE);
if (graphene_point_distance (&pos, &GRAPHENE_POINT_INIT (x, y), NULL, NULL) <= MAZE_STROKE_SIZE_ACTIVE / 2.0f)
return;
self->active = FALSE;
gtk_widget_queue_draw (GTK_WIDGET (self));

View File

@@ -1,323 +0,0 @@
/* Path/Spinner
*
* This demo shows how to use GskPath to draw a simple animation
* that could be used as a spinner.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "paintable.h"
#undef SHOW_CONTROLS
#define GTK_TYPE_SPINNER_PAINTABLE (gtk_spinner_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GtkSpinnerPaintable, gtk_spinner_paintable, GTK, SPINNER_PAINTABLE, GObject)
struct _GtkSpinnerPaintable
{
GObject parent_instance;
gint64 start_time;
int width;
double angle;
double completion;
GskPath *circle;
GskPath *path;
GskStroke *stroke;
GdkRGBA color;
GdkRGBA circle_color;
#ifdef SHOW_CONTROLS
GskPath *controls;
GdkRGBA control_color;
#endif
};
struct _GtkSpinnerPaintableClass
{
GObjectClass parent_class;
};
static int
gtk_spinner_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (paintable);
return self->width;
}
static int
gtk_spinner_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (paintable);
return self->width;
}
static void
gtk_spinner_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (paintable);
gtk_snapshot_append_stroke (snapshot, self->circle, self->stroke, &self->circle_color);
gtk_snapshot_append_stroke (snapshot, self->path, self->stroke, &self->color);
#ifdef SHOW_CONTROLS
GskStroke *stroke = gsk_stroke_new (1);
gtk_snapshot_append_stroke (snapshot, self->controls, stroke, &self->control_color);
gsk_stroke_free (stroke);
#endif
}
static GdkPaintableFlags
gtk_spinner_paintable_get_flags (GdkPaintable *paintable)
{
return GDK_PAINTABLE_STATIC_SIZE;
}
static void
gtk_spinner_paintable_paintable_init (GdkPaintableInterface *iface)
{
iface->get_intrinsic_width = gtk_spinner_paintable_get_intrinsic_width;
iface->get_intrinsic_height = gtk_spinner_paintable_get_intrinsic_height;
iface->snapshot = gtk_spinner_paintable_snapshot;
iface->get_flags = gtk_spinner_paintable_get_flags;
}
/* When defining the GType, we need to implement the GdkPaintable interface */
G_DEFINE_TYPE_WITH_CODE (GtkSpinnerPaintable, gtk_spinner_paintable, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_spinner_paintable_paintable_init))
static void
gtk_spinner_paintable_dispose (GObject *object)
{
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (object);
gsk_path_unref (self->circle);
gsk_path_unref (self->path);
#ifdef SHOW_CONTROLS
gsk_path_unref (self->controls);
#endif
gsk_stroke_free (self->stroke);
G_OBJECT_CLASS (gtk_spinner_paintable_parent_class)->dispose (object);
}
static void
gtk_spinner_paintable_class_init (GtkSpinnerPaintableClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_spinner_paintable_dispose;
}
static void
gtk_spinner_paintable_init (GtkSpinnerPaintable *self)
{
}
static GdkPaintable *
gtk_spinner_paintable_new (void)
{
GtkSpinnerPaintable *self;
GskPathBuilder *builder;
self = g_object_new (GTK_TYPE_SPINNER_PAINTABLE, NULL);
builder = gsk_path_builder_new ();
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (50, 50), 40);
self->circle = gsk_path_builder_free_to_path (builder);
self->width = 100;
self->angle = 0;
self->completion = 1;
gdk_rgba_parse (&self->color, "green");
gdk_rgba_parse (&self->circle_color, "lightgray");
#ifdef SHOW_CONTROLS
gdk_rgba_parse (&self->control_color, "black");
#endif
self->stroke = gsk_stroke_new (5);
return GDK_PAINTABLE (self);
}
#ifdef SHOW_CONTROLS
static gboolean
add_controls (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer data)
{
GskPathBuilder *builder = data;
switch (op)
{
case GSK_PATH_MOVE:
gsk_path_builder_move_to (builder, pts[0].x, pts[0].y);
break;
case GSK_PATH_CLOSE:
case GSK_PATH_LINE:
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
break;
case GSK_PATH_QUAD:
case GSK_PATH_CONIC:
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
gsk_path_builder_line_to (builder, pts[2].x, pts[2].y);
break;
case GSK_PATH_CUBIC:
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
gsk_path_builder_line_to (builder, pts[2].x, pts[2].y);
gsk_path_builder_line_to (builder, pts[3].x, pts[3].y);
break;
default:
g_assert_not_reached ();
}
return TRUE;
}
#endif
static void
update_path (GtkSpinnerPaintable *self)
{
GskPathBuilder *builder;
GskPathPoint start, end;
graphene_point_t p0, p1;
float start_angle, end_angle;
start_angle = self->angle;
end_angle = fmod (self->angle + 360 * self->completion / 100, 360);
p0 = GRAPHENE_POINT_INIT (50 + 40 * cos (M_PI * start_angle / 180),
50 + 40 * sin (M_PI * start_angle / 180));
p1 = GRAPHENE_POINT_INIT (50 + 40 * cos (M_PI * end_angle / 180),
50 + 40 * sin (M_PI * end_angle / 180));
g_clear_pointer (&self->path, gsk_path_unref);
gsk_path_get_closest_point (self->circle, &p0, INFINITY, &start, NULL);
gsk_path_get_closest_point (self->circle, &p1, INFINITY, &end, NULL);
builder = gsk_path_builder_new ();
gsk_path_builder_add_segment (builder, self->circle, &start, &end);
self->path = gsk_path_builder_free_to_path (builder);
#ifdef SHOW_CONTROLS
g_clear_pointer (&self->controls, gsk_path_unref);
builder = gsk_path_builder_new ();
gsk_path_foreach (self->path, -1, add_controls, builder);
self->controls = gsk_path_builder_free_to_path (builder);
#endif
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
}
static void
gtk_spinner_paintable_set_completion (GtkSpinnerPaintable *self,
float completion)
{
self->completion = CLAMP (completion, 0, 100);
update_path (self);
}
static float
gtk_spinner_paintable_get_completion (GtkSpinnerPaintable *self)
{
return self->completion;
}
static void
gtk_spinner_paintable_set_frame_time (GtkSpinnerPaintable *self,
gint64 time)
{
double delta;
if (self->start_time == 0)
self->start_time = time;
delta = (time - self->start_time) / (double) G_TIME_SPAN_SECOND;
self->angle = fmod (60 * delta, 360);
update_path (self);
}
static gboolean
tick_cb (GtkWidget *widget,
GdkFrameClock *clock,
gpointer data)
{
GtkSpinnerPaintable *self = data;
gtk_spinner_paintable_set_frame_time (self, gdk_frame_clock_get_frame_time (clock));
return G_SOURCE_CONTINUE;
}
static gboolean
progress_timeout (gpointer data)
{
GtkSpinnerPaintable *self = data;
static float progress_delta = 0.5;
float progress;
progress = gtk_spinner_paintable_get_completion (self);
if (progress >= 100 || progress <= 0)
progress_delta = -progress_delta;
gtk_spinner_paintable_set_completion (self, progress + progress_delta);
return G_SOURCE_CONTINUE;
}
static void
unset_timeout (gpointer data)
{
g_source_remove (GPOINTER_TO_UINT (data));
}
GtkWidget *
do_path_spinner (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *picture;
GdkPaintable *paintable;
guint timeout_id;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Spinner");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
paintable = gtk_spinner_paintable_new ();
picture = gtk_picture_new_for_paintable (paintable);
gtk_picture_set_content_fit (GTK_PICTURE (picture), GTK_CONTENT_FIT_CONTAIN);
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
g_object_unref (paintable);
gtk_widget_add_tick_callback (picture, tick_cb, paintable, NULL);
timeout_id = g_timeout_add (100, progress_timeout, paintable);
g_object_set_data_full (G_OBJECT (picture), "timeout", GUINT_TO_POINTER (timeout_id), unset_timeout);
gtk_window_set_child (GTK_WINDOW (window), picture);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,9 +1,6 @@
/* Path/Text
*
* This demo shows how to use GskPath to transform a path along another path.
*
* It also demonstrates that paths can be filled with more interesting
* content than just plain colors.
* This demo shows how to use GskPath to animate a path along another path.
*/
#include <glib/gi18n.h>
@@ -31,8 +28,10 @@ struct _GtkPathWidget
graphene_point_t points[4];
guint active_point;
float line_closest;
GskPath *line_path;
GskPathMeasure *line_measure;
GskPath *text_path;
GdkPaintable *background;
@@ -89,18 +88,15 @@ gtk_path_transform_point (GskPathMeasure *measure,
graphene_point_t *res)
{
graphene_vec2_t tangent;
GskPathPoint point;
GskPathPoint *point;
if (gsk_path_measure_get_point (measure, (pt->x + offset->x) * scale, &point))
{
GskPath *path = gsk_path_measure_get_path (measure);
point = gsk_path_measure_get_point (measure, (pt->x + offset->x) * scale);
gsk_path_point_get_position (point, res);
gsk_path_point_get_tangent (point, GSK_PATH_END, &tangent);
gsk_path_point_unref (point);
gsk_path_point_get_position (&point, path, res);
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_END, &tangent);
res->x -= (pt->y + offset->y) * scale * graphene_vec2_get_y (&tangent);
res->y += (pt->y + offset->y) * scale * graphene_vec2_get_x (&tangent);
}
res->x -= (pt->y + offset->y) * scale * graphene_vec2_get_y (&tangent);
res->y += (pt->y + offset->y) * scale * graphene_vec2_get_x (&tangent);
}
static gboolean
@@ -153,7 +149,7 @@ gtk_path_transform_op (GskPathOperation op,
{
graphene_point_t res[2];
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[3], &transform->offset, transform->scale, &res[1]);
gtk_path_transform_point (transform->measure, &pts[2], &transform->offset, transform->scale, &res[1]);
gsk_path_builder_conic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, weight);
}
break;
@@ -171,11 +167,10 @@ gtk_path_transform_op (GskPathOperation op,
}
static GskPath *
gtk_path_transform (GskPath *line_path,
gtk_path_transform (GskPathMeasure *measure,
GskPath *path,
const graphene_point_t *offset)
{
GskPathMeasure *measure = gsk_path_measure_new (line_path);
GtkPathTransform transform = { measure, gsk_path_builder_new (), *offset };
graphene_rect_t bounds;
@@ -187,8 +182,6 @@ gtk_path_transform (GskPath *line_path,
gsk_path_foreach (path, -1, gtk_path_transform_op, &transform);
gsk_path_measure_unref (measure);
return gsk_path_builder_free_to_path (transform.builder);
}
@@ -204,6 +197,7 @@ gtk_path_widget_clear_paths (GtkPathWidget *self)
gtk_path_widget_clear_text_path (self);
g_clear_pointer (&self->line_path, gsk_path_unref);
g_clear_pointer (&self->line_measure, gsk_path_measure_unref);
}
static void
@@ -214,8 +208,11 @@ gtk_path_widget_create_text_path (GtkPathWidget *self)
gtk_path_widget_clear_text_path (self);
if (self->line_measure == NULL)
return;
path = create_path_from_text (GTK_WIDGET (self), self->text, &offset);
self->text_path = gtk_path_transform (self->line_path, path, &offset);
self->text_path = gtk_path_transform (self->line_measure, path, &offset);
gsk_path_unref (path);
}
@@ -241,6 +238,8 @@ gtk_path_widget_create_paths (GtkPathWidget *self)
self->points[3].x * width, self->points[3].y * height);
self->line_path = gsk_path_builder_free_to_path (builder);
self->line_measure = gsk_path_measure_new (self->line_path);
gtk_path_widget_create_text_path (self);
}
@@ -320,6 +319,26 @@ gtk_path_widget_snapshot (GtkWidget *widget,
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
gsk_path_unref (path);
}
if (self->line_closest >= 0)
{
GskPathBuilder *builder;
GskPathPoint *point;
graphene_point_t closest;
builder = gsk_path_builder_new ();
point = gsk_path_measure_get_point (self->line_measure, self->line_closest);
gsk_path_point_get_position (point, &closest);
gsk_path_point_unref (point);
gsk_path_builder_add_circle (builder, &closest, POINT_SIZE);
path = gsk_path_builder_free_to_path (builder);
gtk_snapshot_push_fill (snapshot, path, GSK_FILL_RULE_WINDING);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 1, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
gsk_path_unref (path);
}
}
@@ -500,22 +519,25 @@ pointer_motion (GtkEventControllerMotion *controller,
double y,
GtkPathWidget *self)
{
GskPathPoint point;
GskPathPoint *point;
graphene_point_t pos;
if (gsk_path_get_closest_point (self->line_path,
&GRAPHENE_POINT_INIT (x, y),
INFINITY,
&point,
NULL))
{
gtk_widget_queue_draw (GTK_WIDGET (self));
}
point = gsk_path_measure_get_closest_point (self->line_measure,
&GRAPHENE_POINT_INIT (x, y),
INFINITY);
gsk_path_point_get_position (point, &pos);
self->line_closest = graphene_point_distance (&pos, &GRAPHENE_POINT_INIT (x, y), NULL, NULL);
gsk_path_point_unref (point);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_leave (GtkEventControllerMotion *controller,
GtkPathWidget *self)
{
self->line_closest = -1;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
@@ -536,6 +558,8 @@ gtk_path_widget_init (GtkPathWidget *self)
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
self->line_closest = -1;
self->points[0] = GRAPHENE_POINT_INIT (0.1, 0.9);
self->points[1] = GRAPHENE_POINT_INIT (0.3, 0.1);
self->points[2] = GRAPHENE_POINT_INIT (0.7, 0.1);

View File

@@ -1,373 +0,0 @@
/* Path/Walk
*
* This demo draws a world map and shows how to animate objects along a GskPath.
*
* The world map that is used here is a path with 211 lines and 1569 cubic
* Bėzier segments in 121 contours.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#define GTK_TYPE_PATH_WALK (gtk_path_walk_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathWalk, gtk_path_walk, GTK, PATH_WALK, GtkWidget)
#define POINT_SIZE 8
enum {
PROP_0,
PROP_N_POINTS,
PROP_PATH,
N_PROPS
};
struct _GtkPathWalk
{
GtkWidget parent_instance;
GskPath *path;
GskPathMeasure *measure;
graphene_rect_t bounds;
GskPath *arrow_path;
guint n_points;
};
struct _GtkPathWalkClass
{
GtkWidgetClass parent_class;
};
static GParamSpec *properties[N_PROPS] = { NULL, };
G_DEFINE_TYPE (GtkPathWalk, gtk_path_walk, GTK_TYPE_WIDGET)
static void
rgba_init_from_hsla (GdkRGBA *rgba,
float hue,
float saturation,
float lightness,
float alpha)
{
float m1, m2;
if (lightness <= 0.5)
m2 = lightness * (1 + saturation);
else
m2 = lightness + saturation - lightness * saturation;
m1 = 2 * lightness - m2;
rgba->alpha = alpha;
if (saturation == 0)
{
rgba->red = lightness;
rgba->green = lightness;
rgba->blue = lightness;
}
else
{
hue = hue + 120;
while (hue > 360)
hue -= 360;
while (hue < 0)
hue += 360;
if (hue < 60)
rgba->red = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
rgba->red = m2;
else if (hue < 240)
rgba->red = m1 + (m2 - m1) * (240 - hue) / 60;
else
rgba->red = m1;
hue -= 120;
if (hue < 0)
hue += 360;
if (hue < 60)
rgba->green = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
rgba->green = m2;
else if (hue < 240)
rgba->green = m1 + (m2 - m1) * (240 - hue) / 60;
else
rgba->green = m1;
hue -= 120;
if (hue < 0)
hue += 360;
if (hue < 60)
rgba->blue = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
rgba->blue = m2;
else if (hue < 240)
rgba->blue = m1 + (m2 - m1) * (240 - hue) / 60;
else
rgba->blue = m1;
}
}
static void
gtk_path_walk_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkPathWalk *self = GTK_PATH_WALK (widget);
double width = gtk_widget_get_width (widget);
double height = gtk_widget_get_height (widget);
float length, progress;
GskStroke *stroke;
guint i;
if (self->path == NULL)
return;
gtk_snapshot_save (snapshot);
stroke = gsk_stroke_new (2.0);
gtk_snapshot_push_stroke (snapshot, self->path, stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
gsk_stroke_free (stroke);
length = gsk_path_measure_get_length (self->measure);
progress = 25.f * gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget)) / G_USEC_PER_SEC;
stroke = gsk_stroke_new (1.0);
for (i = 0; i < self->n_points; i++)
{
GskPathPoint point;
graphene_point_t position;
float angle;
GdkRGBA color;
float distance;
distance = i * length / self->n_points;
distance = fmod (distance + progress, length);
gsk_path_measure_get_point (self->measure, distance, &point);
gsk_path_point_get_position (&point, self->path, &position);
angle = gsk_path_point_get_rotation (&point, self->path, GSK_PATH_FROM_START);
rgba_init_from_hsla (&color, 360.f * i / self->n_points, 1, 0.5, 1);
gtk_snapshot_save (snapshot);
gtk_snapshot_translate (snapshot, &position);
gtk_snapshot_rotate (snapshot, angle);
gtk_snapshot_append_fill (snapshot, self->arrow_path, GSK_FILL_RULE_EVEN_ODD, &color);
gtk_snapshot_append_stroke (snapshot, self->arrow_path, stroke, &(GdkRGBA) { 0, 0, 0, 1 });
gtk_snapshot_restore (snapshot);
}
gsk_stroke_free (stroke);
gtk_snapshot_restore (snapshot);
}
static void
gtk_path_walk_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkPathWalk *self = GTK_PATH_WALK (widget);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = (int) ceilf (self->bounds.size.width);
else
*minimum = *natural = (int) ceilf (self->bounds.size.height);
}
static void
gtk_path_walk_set_n_points (GtkPathWalk *self,
gsize n_points)
{
if (self->n_points == n_points)
return;
self->n_points = n_points;
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_POINTS]);
}
static void
gtk_path_walk_set_path (GtkPathWalk *self,
GskPath *path)
{
if (self->path == path)
return;
g_clear_pointer (&self->path, gsk_path_unref);
graphene_rect_init (&self->bounds, 0, 0, 0, 0);
if (path)
{
GskStroke *stroke;
self->path = gsk_path_ref (path);
stroke = gsk_stroke_new (2.0);
gsk_path_get_stroke_bounds (path, stroke, &self->bounds);
gsk_stroke_free (stroke);
self->measure = gsk_path_measure_new (self->path);
}
gtk_widget_queue_resize (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PATH]);
}
static void
gtk_path_walk_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkPathWalk *self = GTK_PATH_WALK (object);
switch (prop_id)
{
case PROP_N_POINTS:
gtk_path_walk_set_n_points (self, g_value_get_uint (value));
break;
case PROP_PATH:
gtk_path_walk_set_path (self, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_walk_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPathWalk *self = GTK_PATH_WALK (object);
switch (prop_id)
{
case PROP_N_POINTS:
g_value_set_uint (value, self->n_points);
break;
case PROP_PATH:
g_value_set_boxed (value, self->path);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_walk_dispose (GObject *object)
{
GtkPathWalk *self = GTK_PATH_WALK (object);
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->measure, gsk_path_measure_unref);
g_clear_pointer (&self->arrow_path, gsk_path_unref);
G_OBJECT_CLASS (gtk_path_walk_parent_class)->dispose (object);
}
static void
gtk_path_walk_class_init (GtkPathWalkClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_path_walk_dispose;
object_class->set_property = gtk_path_walk_set_property;
object_class->get_property = gtk_path_walk_get_property;
widget_class->snapshot = gtk_path_walk_snapshot;
widget_class->measure = gtk_path_walk_measure;
properties[PROP_N_POINTS] =
g_param_spec_uint ("n-points",
NULL, NULL,
1, G_MAXUINT,
500,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_PATH] =
g_param_spec_boxed ("path",
NULL, NULL,
GSK_TYPE_PATH,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static gboolean
tick_tick_tick (GtkWidget *self,
GdkFrameClock *frame_clock,
gpointer unused)
{
gtk_widget_queue_draw (GTK_WIDGET (self));
return G_SOURCE_CONTINUE;
}
static void
gtk_path_walk_init (GtkPathWalk *self)
{
/* Data taken from
* https://commons.wikimedia.org/wiki/Maps_of_the_world#/media/File:Simplified_blank_world_map_without_Antartica_(no_borders).svg
*/
GBytes *data = g_resources_lookup_data ("/path_walk/path_world.txt", 0, NULL);
GskPath *path = gsk_path_parse (g_bytes_get_data (data, NULL));
g_bytes_unref (data);
gtk_path_walk_set_path (self, path);
gsk_path_unref (path);
self->arrow_path = gsk_path_parse ("M 5 0 L 0 -5. 0 -2, -5 -2, -5 2, 0 2, 0 5 Z");
self->n_points = 500;
gtk_widget_add_tick_callback (GTK_WIDGET (self), tick_tick_tick, NULL, NULL);
}
GtkWidget *
gtk_path_walk_new (void)
{
GtkPathWalk *self;
self = g_object_new (GTK_TYPE_PATH_WALK, NULL);
return GTK_WIDGET (self);
}
GtkWidget *
do_path_walk (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkBuilder *builder;
g_type_ensure (GTK_TYPE_PATH_WALK);
builder = gtk_builder_new_from_resource ("/path_walk/path_walk.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">World Map</property>
<property name="titlebar">
<object class="GtkHeaderBar">
<child type="end">
<object class="GtkSpinButton">
<property name="adjustment">
<object class="GtkAdjustment" id="adjustment">
<property name="lower">0</property>
<property name="upper">5000</property>
<property name="value">500</property>
<property name="step-increment">1</property>
<property name="page-increment">10</property>
</object>
</property>
</object>
</child>
</object>
</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkPathWalk" id="view">
<property name="n-points" bind-source="adjustment" bind-property="value"/>
<property name="hexpand">true</property>
<property name="vexpand">true</property>
</object>
</child>
</object>
</property>
</object>
</interface>

File diff suppressed because one or more lines are too long

View File

@@ -1,9 +1,8 @@
/* Pickers and Launchers
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog, GtkPrintDialog, GtkFileLauncher, GtkUriLauncher
* #Keywords: GtkColorDialog, GtkFontDialog, GtkFileDialog, GtkFileLauncher, GtkUriLauncher
*
* The dialogs are mainly intended for use in preference dialogs.
* They allow to select colors, fonts and files. There is also a
* print dialog.
* They allow to select colors, fonts and applications.
*
* The launchers let you open files or URIs in applications that
* can handle them.
@@ -12,13 +11,11 @@
#include <gtk/gtk.h>
static GtkWidget *app_picker;
static GtkWidget *print_button;
static void
set_file (GFile *file,
gpointer data)
{
GFileInfo *info;
char *name;
if (!file)
@@ -34,13 +31,6 @@ set_file (GFile *file,
gtk_widget_set_sensitive (app_picker, TRUE);
g_object_set_data_full (G_OBJECT (app_picker), "file", g_object_ref (file), g_object_unref);
info = g_file_query_info (file, "standard::content-type", 0, NULL, NULL);
if (strcmp (g_file_info_get_content_type (info), "application/pdf") == 0)
{
gtk_widget_set_sensitive (print_button, TRUE);
g_object_set_data_full (G_OBJECT (print_button), "file", g_object_ref (file), g_object_unref);
}
}
static void
@@ -57,10 +47,6 @@ file_opened (GObject *source,
{
g_print ("%s\n", error->message);
g_error_free (error);
gtk_widget_set_sensitive (app_picker, FALSE);
g_object_set_data (G_OBJECT (app_picker), "file", NULL);
gtk_widget_set_sensitive (print_button, FALSE);
g_object_set_data (G_OBJECT (print_button), "file", NULL);
}
set_file (file, data);
@@ -128,53 +114,6 @@ open_app (GtkButton *picker)
g_object_unref (launcher);
}
static void
print_file_done (GObject *source,
GAsyncResult *result,
gpointer data)
{
GtkPrintDialog *dialog = GTK_PRINT_DIALOG (source);
GError *error = NULL;
GCancellable *cancellable;
unsigned int id;
cancellable = g_task_get_cancellable (G_TASK (result));
id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (cancellable), "timeout"));
if (id)
g_source_remove (id);
if (!gtk_print_dialog_print_file_finish (dialog, result, &error))
{
g_print ("%s\n", error->message);
g_error_free (error);
}
}
static void
print_file (GtkButton *picker)
{
GtkWindow *parent = GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (picker)));
GtkPrintDialog *dialog;
GCancellable *cancellable;
GFile *file;
unsigned int id;
file = G_FILE (g_object_get_data (G_OBJECT (picker), "file"));
dialog = gtk_print_dialog_new ();
cancellable = g_cancellable_new ();
id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
20,
abort_mission, g_object_ref (cancellable), g_object_unref);
g_object_set_data (G_OBJECT (cancellable), "timeout", GUINT_TO_POINTER (id));
gtk_print_dialog_print_file (dialog, parent, NULL, file, cancellable, print_file_done, NULL);
g_object_unref (cancellable);
g_object_unref (dialog);
}
static void
open_uri_done (GObject *source,
GAsyncResult *result,
@@ -295,15 +234,9 @@ do_pickers (GtkWidget *do_widget)
gtk_widget_set_sensitive (app_picker, FALSE);
g_signal_connect (app_picker, "clicked", G_CALLBACK (open_app), NULL);
gtk_box_append (GTK_BOX (picker), app_picker);
print_button = gtk_button_new_from_icon_name ("printer-symbolic");
gtk_widget_set_tooltip_text (print_button, "Print file");
gtk_widget_set_sensitive (print_button, FALSE);
g_signal_connect (print_button, "clicked", G_CALLBACK (print_file), NULL);
gtk_box_append (GTK_BOX (picker), print_button);
gtk_grid_attach (GTK_GRID (table), picker, 1, 2, 1, 1);
label = gtk_label_new ("URI:");
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -6,6 +6,6 @@
* Also, when adding new style properties, please add them here.
*/
window.demo * {
* {
all: unset;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -188,20 +188,10 @@ do_spinbutton (GtkWidget *do_widget)
if (!window)
{
GtkBuilder *builder;
GtkBuilderScope *scope;
GtkAdjustment *adj;
GtkWidget *label;
scope = gtk_builder_cscope_new ();
builder = gtk_builder_new ();
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), spinbutton_hex_spin_input);
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), spinbutton_hex_spin_output);
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), spinbutton_time_spin_input);
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), spinbutton_time_spin_output);
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), spinbutton_month_spin_input);
gtk_builder_cscope_add_callback (GTK_BUILDER_CSCOPE (scope), spinbutton_month_spin_output);
gtk_builder_set_scope (builder, scope);
gtk_builder_add_from_resource (builder, "/spinbutton/spinbutton.ui", NULL);
builder = gtk_builder_new_from_resource ("/spinbutton/spinbutton.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
@@ -243,7 +233,6 @@ do_spinbutton (GtkWidget *do_widget)
NULL, NULL);
g_object_unref (builder);
g_object_unref (scope);
}
if (!gtk_widget_get_visible (window))

View File

@@ -27,6 +27,7 @@ GtkWidget *
do_spinner (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
GtkWidget *content_area;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *button;
@@ -34,19 +35,28 @@ do_spinner (GtkWidget *do_widget)
if (!window)
{
window = gtk_window_new ();
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Spinner");
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
window = gtk_dialog_new_with_buttons ("Spinner",
GTK_WINDOW (do_widget),
0,
_("_Close"),
GTK_RESPONSE_NONE,
NULL);
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
g_signal_connect (window, "response",
G_CALLBACK (gtk_window_destroy), NULL);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
gtk_widget_set_margin_top (vbox, 5);
gtk_widget_set_margin_bottom (vbox, 5);
content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
G_GNUC_END_IGNORE_DEPRECATIONS
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
gtk_widget_set_margin_start (vbox, 5);
gtk_widget_set_margin_end (vbox, 5);
gtk_window_set_child (GTK_WINDOW (window), vbox);
gtk_widget_set_margin_top (vbox, 5);
gtk_widget_set_margin_bottom (vbox, 5);
gtk_box_append (GTK_BOX (content_area), vbox);
/* Sensitive */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);

View File

@@ -801,7 +801,7 @@ suggestion_entry_key_pressed (GtkEventControllerKey *controller,
selected = matches - 1;
}
gtk_list_view_scroll_to (GTK_LIST_VIEW (self->list), selected, GTK_LIST_SCROLL_SELECT, NULL);
gtk_single_selection_set_selected (self->selection, selected);
return TRUE;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 823 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -147,19 +147,6 @@ Creates a node like `gsk_cross_fade_node_new()` with the given properties.
Creates a node like `gsk_debug_node_new()` with the given properties.
### fill
| property | syntax | default | printed |
| --------- | --------------- | ---------------------- | ----------- |
| child | `<node>` | *see below* | always |
| path | `<string>` | "" | always |
| fill-rule | `<fill-rule>` | winding | always |
Creates a node like `gsk_fill_node_new()` with the given properties.
The default child node is the default color node, but created with the
bounds of the path.
### glshader
| property | syntax | default | printed |
@@ -302,24 +289,6 @@ Creates a node like `gsk_rounded_clip_node_new()` with the given properties.
Creates a node like `gsk_shadow_node_new()` with the given properties.
### stroke
| property | syntax | default | printed |
| ----------- | ------------------ | ----------------- | ----------- |
| child | `<node>` | *see below* | always |
| path | `<string>` | "" | always |
| line-width | `<number>` | 0 | non-default |
| line-cap | `<line-cap>` | butt | always |
| line-join | `<line-join>` | miter | always |
| miter-limit | `<number>` | 4 | non-default |
| dash | `<number>{+}|none` | none | non-default |
| dash-offset | `<number>` | 0 | non-default |
Creates a node like `gsk_stroke_node_new()` with the given properties.
The default child node is the default color node, but created with the
stroke bounds of the path.
### text
| property | syntax | default | printed |

View File

@@ -6,6 +6,8 @@
#include "demo_conf.h"
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static GtkWidget *main_window;
static GFile *filename = NULL;
static GtkPageSetup *page_setup = NULL;
@@ -41,7 +43,7 @@ update_statusbar (void)
GtkTextIter iter;
const char *print_str;
gtk_label_set_label (GTK_LABEL (statusbar), "");
gtk_statusbar_pop (GTK_STATUSBAR (statusbar), 0);
gtk_text_buffer_get_iter_at_mark (buffer,
&iter,
@@ -59,10 +61,10 @@ update_statusbar (void)
msg = g_strdup_printf ("%d, %d%s %s",
row, col,
file_changed?" - Modified":"",
print_str);
file_changed?" - Modified":"",
print_str);
gtk_label_set_label (GTK_LABEL (statusbar), msg);
gtk_statusbar_push (GTK_STATUSBAR (statusbar), 0, msg);
g_free (msg);
}
@@ -825,12 +827,7 @@ activate (GApplication *app)
contents);
/* Create statusbar */
statusbar = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (statusbar), 0);
gtk_widget_set_margin_start (statusbar, 2);
gtk_widget_set_margin_end (statusbar, 2);
gtk_widget_set_margin_top (statusbar, 2);
gtk_widget_set_margin_bottom (statusbar, 2);
statusbar = gtk_statusbar_new ();
gtk_box_append (GTK_BOX (box), statusbar);
/* Show text widget info in the statusbar */

View File

@@ -1,6 +1,16 @@
# demos/widget-factory
if can_use_objcopy_for_resources
objcopy_supports_add_symbol = false
objcopy = find_program('objcopy', required : false)
if objcopy.found()
objcopy_supports_add_symbol = run_command(objcopy, '--help', check: false).stdout().contains('--add-symbol')
endif
ld = find_program('ld', required : false)
if not meson.is_cross_build() and build_machine.cpu_family() != 'arm' and build_machine.system() == 'linux' and objcopy.found() and objcopy_supports_add_symbol and ld.found()
glib_compile_resources = find_program('glib-compile-resources')
# Create the resource blob
widgetfactory_gresource = custom_target('widgetfactory.gresource',
input : 'widget-factory.gresource.xml',

View File

@@ -1572,9 +1572,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="valign">3</property>
<child>
<object class="GtkVolumeButton">
<accessibility>
<property name="label" translatable="1">Volume</property>
</accessibility>
<property name="orientation">1</property>
<property name="valign">3</property>
<property name="value">.5</property>
@@ -1587,9 +1584,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
</child>
<child>
<object class="GtkScaleButton" id="mic-button">
<accessibility>
<property name="label" translatable="1">Microphone gain</property>
</accessibility>
<property name="has-tooltip">1</property>
<property name="icons">microphone-sensitivity-muted-symbolic
microphone-sensitivity-high-symbolic

View File

@@ -5,6 +5,16 @@ How to do a GTK release?
Make sure you have suitable versions of Meson and Ninja.
Also make sure you have the following packages installed with all their
dependencies:
* gtk-doc
* docbook-utils
Without those packages make distcheck will *not* pass.
Make sure that gtk-doc is the latest released version.
## Release check list
0. Save all your work, then move to the branch from which you want
@@ -18,8 +28,8 @@ $ git clean -dfx
1. Build using the common sequence:
```sh
$ meson setup _build
$ meson compile -C _build
$ meson _build .
$ ninja -C _build
```
2. Update NEWS based on the content of git log; follow the format of prior
@@ -30,10 +40,11 @@ $ meson compile -C _build
writers, committers, etc. Anybody who is mentioned in the commit log
gets a credit, but only real names, not email addresses or nicknames.
3. Update the pot file and commit the changes:
3. Update the pot files and commit the changes:
```sh
$ ninja -C _build gtk40-pot
$ ninja -C _build gtk40-properties-pot
```
4. If this is a major, stable, release, verify that the release notes
@@ -61,7 +72,7 @@ $ ninja -C _build gtk40-pot
Make sure that all new symbols have proper Since: tags, and that there
is an index in the main `-docs.xml` for the next stable version.
8. Run `meson dist -C_build` to generate the tarball.
8. Run `ninja dist` to generate the tarball.
9. Fix broken stuff found by 8), commit changes, repeat.
@@ -83,8 +94,7 @@ $ ninja -C _build gtk40-pot
$ git tag -m "GTK 4.2.0" 4.2.0
```
13. Bump the version number in `meson.build`, and add a section for the next
release in NEWS and commit the change.
13. Bump the version number in `meson.build` and commit the change.
14. Push the changes upstream, and push the tag as well. The git command for
doing that is:
@@ -101,8 +111,7 @@ $ git push origin 4.2.0
```sh
$ scp gtk-4.2.0.tar.xz matthiasc@master.gnome.org:
$ ssh matthiasc@master.gnome.org
$ ftpadmin install gtk-4.2.0.tar.xz
$ ssh matthiasc@master.gnome.org ftpadmin install gtk-4.2.0.tar.xz
```
16. Go to the gnome-announce list archives, find the last announce message,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

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