Compare commits

..

127 Commits

Author SHA1 Message Date
Matthias Clasen 303dcc667b gtk-demo: Add a few path benchmarks
The Tiger and Graph examples in the fishbowl test
path handling.
2022-04-08 16:44:29 -04:00
Matthias Clasen a73b6b4392 Add gsk_stroke_node_get_stroke_path
We will implement stroking by filling the stroke path.
2022-04-08 16:44:29 -04:00
Matthias Clasen a88dbb820b Add GskRoundedRectContour
The main advantage here is that we can avoid
going through the stroker for the common case
of rounded rectangles.
2022-04-08 16:44:29 -04:00
Matthias Clasen b61058cd22 Add a demo for path ops 2022-04-08 16:44:29 -04:00
Matthias Clasen 8b1d7fd622 Add some tests for pathops 2022-04-08 16:44:29 -04:00
Matthias Clasen 4e24f88482 path: Implement path ops
Implement boolean operations on paths.
2022-04-08 16:44:29 -04:00
Matthias Clasen 98c40daa5f path: Add gsk_path_transform
This is an obvious operation to want for paths.
2022-04-08 16:44:29 -04:00
Matthias Clasen def04f5df3 path: Add gsk_path_is_convex
Add a function to compute whether a path is convex.
2022-04-08 16:44:29 -04:00
Matthias Clasen 9709f20c53 path: Add gsk_path_get_flags
The flags contain some useful information.
2022-04-08 16:44:29 -04:00
Matthias Clasen 3661086dcc path: Add gsk_path_reverse
This is a natural operation, and useful for debugging things.
2022-04-08 16:44:29 -04:00
Matthias Clasen d71183bbfe curve: Limit recursion depth 2022-04-08 16:44:29 -04:00
Matthias Clasen 2430c55228 gtk-demo: Use gsk_path_builder_add_layout
We have an api now to hide the cairo use.
2022-04-08 16:44:29 -04:00
Matthias Clasen a8aa460330 pathbuilder: Add gsk_path_builder_add_layout
This api makes it easy to turn text into a path that
can be further manipulated.

The implementation currently goes via cairo.
2022-04-08 16:44:29 -04:00
Matthias Clasen b148c792ca 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.
2022-04-08 16:44:29 -04:00
Matthias Clasen cc3b47cef6 pathmeasure: Add gsk_path_measure_get_curvature 2022-04-08 16:44:29 -04:00
Matthias Clasen 386a58f0f4 stroke: Make gsk_stroke_to_cairo public
It comes in handy, and does no harm.
2022-04-08 16:44:29 -04:00
Matthias Clasen 10cd4fc48c gtk-demo: Add a curve editor demo 2022-04-08 16:44:29 -04:00
Matthias Clasen 0debc3d891 path: Implement offsetting
Implement offsetting of paths by reusing the
infrastructure of the stroker.
2022-04-08 16:44:29 -04:00
Matthias Clasen f166ec5bc9 path: Add gsk_path_offset
Add a function that takes a path, and offsets it
by some distance, applying line-join parameters
as needed.

This commit just adds the api, the implementation
will be in the following commit.
2022-04-08 16:44:29 -04:00
Matthias Clasen 95c3a34cfb stroker: Implement arcs
Implement arced joins as specified in SVG2.
2022-04-08 16:44:29 -04:00
Matthias Clasen 3720429958 Add GSK_LINE_JOIN_ARCS
Implementation will follow.
2022-04-08 16:44:29 -04:00
Matthias Clasen 57904fcd6a Add another stroker test
Check that the outlines of random paths look as
expected. We currently have to exclude paths where
points get too close to each other.
2022-04-08 16:44:29 -04:00
Matthias Clasen 9620b5eb38 Add basic tests for strokes
Add tests to check that any point on a path is
always at most half the line-width away from the
stroke path with that line-width.
2022-04-08 16:44:29 -04:00
Matthias Clasen 9bb552d23c path: Implement stroking
Implement gsk_contour_default_add_stroke, which takes a contour
and stroke parameters, and adds contours to a path builder for
the outline that would be produced by stroking the path with these
parameters.

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.
2022-04-08 16:44:29 -04:00
Matthias Clasen 188f78478c curve: Add some curve utilities
These apis will be used in the stroker.
2022-04-08 16:44:29 -04:00
Matthias Clasen 2b8fe62b55 contour: Special-case circles for strokes
The outline of a circle is just two circles.
2022-04-08 16:44:29 -04:00
Matthias Clasen 31fe02e449 contour: Special-case rects for strokes
In many cases, the outline of a rectangle is just
two rectangles.
2022-04-08 16:44:29 -04:00
Matthias Clasen 068838eac4 path: Add gsk_path_stroke
Add the plumbing that will let us do special-case stroking
for rectangles, circles and other special contours.

There is no implementation yet.
2022-04-08 16:44:29 -04:00
Matthias Clasen 81dae3e15f curve: Add gsk_curve_print
Useful for debugging.
2022-04-08 16:44:28 -04:00
Matthias Clasen e9a010eb67 curve: Add gsk_curve_get_curvature
This will be used in the stroker.
2022-04-08 16:44:28 -04:00
Matthias Clasen 282be569f6 curve: Add gsk_curve_get_normal
Its easy but thats no reason not to have this api.
2022-04-08 16:44:28 -04:00
Matthias Clasen f2069508cf Add a test for gsk_curve_offset
The stroker relies on offsetting.
This only tests a few very simple cases.
2022-04-08 16:44:28 -04:00
Matthias Clasen 56f587a5a3 Add a test for gsk_curve_reverse
The stroker relies on this working.
2022-04-08 16:44:28 -04:00
Matthias Clasen 64807abc59 Add a test for tangents of degenerate curves
The stroker relies on these to work.
2022-04-08 16:44:28 -04:00
Matthias Clasen 2cace6bada curve: Handle degenerate cases
Nothing prevents control points from being identical,
and if that happens, some of our constructions involving
tangents and normals break down. Handle these cases in
get_{start,end}_tangent and offset, for the case of
cubics.
2022-04-08 16:44:28 -04:00
Matthias Clasen b1363aadeb curve: Add gsk_curve_reverse
This will be used in stroking.
2022-04-08 16:44:28 -04:00
Matthias Clasen e44be94835 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.
2022-04-08 16:44:28 -04:00
Matthias Clasen ffc663b5c5 Add conic decomposition tests
We don't have good error bounds here, unfortunately.
2022-04-08 16:44:28 -04:00
Matthias Clasen fcf43c4012 path: support conic->curve in foreach 2022-04-08 16:44:28 -04:00
Matthias Clasen a9c36f8ba9 curve: Add gsk_curve_decompose_curve
This is mainly useful for decomposing a conic into
cubics. The criterion here for terminating the
subdivision is very improvised.
2022-04-08 16:44:28 -04:00
Matthias Clasen 72835f321f Add a performance test for curve eval
All curve types are equally fast here.
2022-04-08 16:44:28 -04:00
Matthias Clasen 8069495f76 Add a performance test for curve intersection
This shows how much more expensive curve
intersections are.
2022-04-08 16:44:28 -04:00
Matthias Clasen 6a51dfc929 Add curve split tests 2022-04-08 16:44:28 -04:00
Matthias Clasen 1fba399296 testsuite: Add special-case curve tests 2022-04-08 16:44:28 -04:00
Matthias Clasen 4d6c2108ac Add curve intersection tests
These tests check that gsk_curve_intersect finds
the intersections we want.
2022-04-08 16:44:28 -04:00
Matthias Clasen ac5c742df6 curve: Add gsk_curve_intersect
Add a way to find the intersections of two curves.
This will be used in stroking.
2022-04-08 16:44:28 -04:00
Matthias Clasen ee799830ef curve: Add gsk_curve_get_bounds
Add getters for bounding boxes of curves.
2022-04-08 16:44:28 -04:00
Matthias Clasen 7e9c94e599 Add a bounding box type
graphene_rect_t does not quite work for this purpose.
2022-04-08 16:44:28 -04:00
Matthias Clasen 9e2c689745 Only test conic weights between 1/20 and 20
The rest just give us no end of numeric trouble.
2022-04-08 16:44:28 -04:00
Benjamin Otte 94f93dbd2d path: Add gsk_path_builder_add_ellipse() 2022-04-08 16:44:28 -04:00
Benjamin Otte 846ae95818 path: Change semantics of gtk_path_builder_add_segment()
Allow start >= end to mean that the path continues at the beginning
after reaching the end until it reaches the point at @end.
2022-04-08 16:44:28 -04:00
Benjamin Otte c28fd1dbe6 pathmeasure: Add gsk_path_measure_is_closed () 2022-04-08 16:44:28 -04:00
Benjamin Otte 6021b76a6b pathmeasure: Add gsk_path_measure_restrict_to_contour() 2022-04-08 16:44:28 -04:00
Matthias Clasen 15541842e4 pathmeasure: Add gsk_path_measure_get_{path,tolerance}
These are just nice apis to have and avoid having to carry
these around as extra arguments in many places.

This was showing up as inconvenience in writing tests
for the measure apis.
2022-04-08 16:44:28 -04:00
Benjamin Otte 1dbfff9f2b gtk-demo: Use dashes in path-fill demo 2022-04-08 16:44:28 -04:00
Matthias Clasen 2418d67e23 gsk: Use stroke bounds in the stroke node
We can use gsk_path_get_stroke_bounds to get a
better estimate for the bounds of the stroke node.
2022-04-08 16:44:28 -04:00
Matthias Clasen 91193e807f path: Add gsk_path_get_stroke_bounds
A relatively cheap way to get bounds for the area
that would be affected by stroking a path.
2022-04-08 16:44:28 -04:00
Benjamin Otte d537df1f62 testsuite: Add tests for the dasher 2022-04-08 16:44:28 -04:00
Benjamin Otte 4a596fe5bf path: Add a foreach function that dashes a path 2022-04-08 16:44:28 -04:00
Benjamin Otte 27e7b97d28 path: Deal with non-uniformness of progress parameter
The progress is non-uniform, so simple translation of progress doesn't work.
So check if larger and smaller values inch closer towards minimal distance.
2022-04-08 16:44:28 -04:00
Benjamin Otte 95a34803cb path: Always decompose conics into at least 2 segments
Conics are evil in that their parameter skews towards the center, and if
it's a very flat conic (weight almost equal to 0), then we'd approximate
it with a single segment and not subdivide, which would cause the
parameter to be wildly off around 0.25 or 0.75.

And that would cause offset calculations to fail.
2022-04-08 16:44:28 -04:00
Matthias Clasen c3571c104d testsuite Add curve tangent tests 2022-04-08 16:44:28 -04:00
Benjamin Otte 451a629de1 testsuite: Add a test for the conic that got us segment() 2022-04-08 16:44:28 -04:00
Benjamin Otte c0e332f677 path: Add gsk_curve_segment()
Using split() twice with scaled t values does not work with conics.
2022-04-08 16:44:28 -04:00
Benjamin Otte 66edb0b5cd testsuite: Add a test for gsk_curve_decompose() 2022-04-08 16:44:28 -04:00
Benjamin Otte a430099e35 testuite: Add tests for gsk_curve_get_tangent() 2022-04-08 16:44:28 -04:00
Matthias Clasen 26aef58709 testuite: Add tests for gsk_curve_get_point()
Add a few tests for gsk_curve_get_point().

Since GskCurve is not public api, we add gskcurve.c
as source to the test binary.
2022-04-08 16:44:28 -04:00
Benjamin Otte d15f558769 curve: Split eval() into get_point() and get_tangent()
That's more in line with the get_start/end_point/tangent() functions.

Plus, those calls are independent and we usually want one or the other.
2022-04-08 16:44:28 -04:00
Matthias Clasen 0c2f43d1bd curve: Add gsk_curve_get_{start,end}_tangent
Add a way to get the tangents at the start and end of the curve.
This will be used in stroking.
2022-04-08 16:44:28 -04:00
Benjamin Otte 77d6bc9158 testsuite: Add conics to the random paths 2022-04-08 16:44:28 -04:00
Benjamin Otte ef120ef1a0 path: Add GskCurve
GskCurve is an abstraction for path operations. It's essentially a
collection of vfuncs per GskPathOperation.

GskStandardContour has been ported to use it where appropriate.
2022-04-08 16:44:28 -04:00
Benjamin Otte dcf0ba6920 path: Introduce gskpathop
A gskpathop is a pointer to a graphene_point_t* with the low bits used
to encode the GskPathOperation. It's an easy way to introduce API for
operations.

So far it's just used to replace GskStandardOperation.
2022-04-08 08:06:02 -04:00
Benjamin Otte 159fb16494 css: Replace border rendering code with GskPath 2022-04-08 08:06:02 -04:00
Benjamin Otte 7965c420bc pathbuilder: Add gsk_path_builder_add_rounded_rect()
It works, but does not use a custom contour yet.
2022-04-08 08:06:02 -04:00
Benjamin Otte 7b83101ed7 path: Add conic curves
So far this just adds the API, if you use it, you'll get lots of
g_warnings().

This will be fixed in future commits.
2022-04-08 08:06:02 -04:00
Benjamin Otte dd2036ea01 path: Rename to gtk_path_builder_add_segment()
It's about bulding paths, not about measuring them.
2022-04-08 08:06:02 -04:00
Matthias Clasen c66d61a55c path: Split contours into their own file
I'm not sure I want to keep all contours in one file,
but for now that's how it is.
2022-04-08 08:06:02 -04:00
Benjamin Otte e2b5e83812 path: Make all private contour APIs take a GskContour
... instead of a path, index tuple.
2022-04-08 08:06:02 -04:00
Matthias Clasen d773a36623 Add a nodeparser tests for fill and stroke nodes 2022-04-08 08:06:02 -04:00
Benjamin Otte a4374f41db stroke: Add support for dashes
... and hook it up in the node parser and for Cairo rendering.
2022-04-08 08:06:02 -04:00
Matthias Clasen 822cfb022f gsk: Implement parsing fill and stroke nodes
Make serialization and deserialization work for stroke and
fill nodes.
2022-04-08 08:06:02 -04:00
Benjamin Otte 95c823a377 path: Add flags to gsk_path_foreach()
This way we can default to the siplest possible foreach() output - like
cairo_copy_path_flat() decomposing everything into lines - and add flags
to get more and more fancy.

This will be useful to have conics automatically decomposed for Cairo
drawing or if we want to add more line types in the future.
2022-04-08 08:06:02 -04:00
Benjamin Otte 6949cfa14b testsuite: Add tests for in_fill()
Add a test for measure_in_fill. Also test some
special cases involving horizontal edges.
2022-04-08 08:06:02 -04:00
Matthias Clasen ccd1d6a0be pathmeasure: Implement gsk_path_measure_in_fill
Implement this in the obvious way, using the decomposed form
of standard contours. Since the decomposed form is part of the
measure object, this api moves from gsk_path_in_fill to
gsk_path_measure_in_fill.
2022-04-08 08:06:02 -04:00
Benjamin Otte 45c0851577 testsuite: Add a parsing test
This test includes an implementation of a gsk_path_equal() func with
a tolerance that is necessary because parsing does not always work
100% exactly due to floating point rounding, so we can't just
compare the to_string() output.
2022-04-08 08:06:02 -04:00
Matthias Clasen 37c1461a60 path: Special-case rects and circles
Write out the commands for rects and circles in a special
way, and add code in the parser to recognize this, so we
can successfully round-trip these through the SVG path format.

The special way - for people who want to use it for debugging -
for now is that we use uppercase "Z" to close standard paths, but
lowercase "z" to close our special paths.

A test is included, but the random path serializations should take care
of it, too.
2022-04-08 08:06:02 -04:00
Matthias Clasen 84162d8550 path: Fix serialization for circles
The svg A can not do a full circle, since it is a two point
parametrization - if the start and end point are the same,
it draws nothing. So, use two arcs.
2022-04-08 08:06:02 -04:00
Benjamin Otte 3f77813ce2 testsuite: Add librsvg path tests 2022-04-08 08:06:02 -04:00
Matthias Clasen b539e21528 path: Implement gsk_path_parse
Implement the SVG path syntax to read back the strings
that we generate when serializing paths. The tests for
this code are taken from librsvg.

This includes an elliptical arc implementation according
to the SVG spec. The code is mostly taken from librsvg,
but pretty directly follows the SVG spec implementation
notes. We don't export this, since the parametrization
is inconvenient. We do want an arc_to API, but
these are not the arcs we are looking for.
2022-04-08 08:06:02 -04:00
Matthias Clasen 00f0225712 path: Implement SVG arcs
This is elliptical arc implementation according to the SVG spec.
The code is mostly taken from librsvg, but pretty directly
follows the SVG spec implementation notes.

We don't export this, since the parametrization is inconvenient.
We do want an arc_to API, but these are not the arcs we are
looking for.

It will be used in parsing SVG path syntax.
2022-04-08 08:06:02 -04:00
Matthias Clasen 7aad5998c6 stroke: Add miter limit
Add a miter limit to GskStroke. This will be needed to
fully implement line joins.

Also introduce the GSK_LINE_JOIN_MITER_CLIP value,
following SVG 2.0. cairo does not have it, so translate
it to plain miter when using cairo.
2022-04-08 08:06:02 -04:00
Benjamin Otte a5fa6fded0 testsuite: Add relative path functions
They're making the paths slightly weirder, but they test public API, so
woohoo!
2022-04-08 08:06:02 -04:00
Benjamin Otte 845102fc22 pathbuilder: Add relative path commands
And gsk_path_builder_get_current_point().

They will be needed by the string parser.
2022-04-08 08:06:02 -04:00
Benjamin Otte d570e96a15 path: Add GSK_CIRCLE_POINT_INIT() to initialize points on the circle
This is just splitting out a commonly done operation into a macro.
2022-04-08 08:06:02 -04:00
Benjamin Otte 924f036667 pathbuilder: Redo semantics for starting curves
We now always have a "current point" which is either the last point an
operation was made to, or (0, 0) if no drawing operation has
been made yet.

Adding a contour of any kind to the builder will always update the
current point to that contour's end point.
2022-04-08 08:06:02 -04:00
Benjamin Otte e8750af295 gtk-demo: Show closest point in text-on-path demo 2022-04-08 08:06:02 -04:00
Benjamin Otte 4bcc4529da path: Split GskPathBuilder into its own file
... and add missing API docs.
2022-04-08 08:06:02 -04:00
Benjamin Otte 25582c8b32 testsuite: Add a test using get_point() and get_closest_point() 2022-04-08 08:06:02 -04:00
Benjamin Otte 8007e378c3 testsuite: Add a test for get_point() 2022-04-08 08:06:02 -04:00
Benjamin Otte 3dac5d2217 testsuite: Update create_random_path()
1. Allow specifying the max number of contours
2. Be smarter about creating the paths:
   With 10% chance, create a "weird" path like the empty one or only
   points or things like that.
   Otherwise create a bunch of contours, with 2/3 a standard contour,
   with 1/3 a predetermined one.
2022-04-08 08:06:02 -04:00
Benjamin Otte bcd90a884c gtk-demo: Add cute maze demo 2022-04-08 08:06:02 -04:00
Benjamin Otte d77f8c6ab9 testsuite: Add tests for gsk_path_measure_get_closest_point() 2022-04-08 08:06:02 -04:00
Benjamin Otte 3b8cbd10f8 pathmeasure: Add gsk_path_measure_get_closest_point()
... and gsk_path_measure_get_closest_point_full().

Those 2 functions allow finding the closest point
on a path to a given point.
2022-04-08 08:06:02 -04:00
Benjamin Otte d5f378bd0a spline: Use Skia's tolerance checks
This avoids measuring being too far off (it's still off, but it's less
than a percent now.
2022-04-08 08:06:02 -04:00
Benjamin Otte 895205894e testsuite: Add tests for gsk_path_measure_add_segment() 2022-04-08 08:06:02 -04:00
Benjamin Otte f23af85cb2 gtk-demo: Add a text-on-path demo 2022-04-08 08:06:02 -04:00
Benjamin Otte cdb528e566 gtk-demo: Add a path-fill demo 2022-04-07 22:37:56 -04:00
Benjamin Otte 7465f57a57 pathmeasure: Add gsk_path_measure_get_point()
Allows querying the coordinates and direction
of any specific point on a path.
2022-04-07 22:37:56 -04:00
Matthias Clasen d9b3589164 path: Add gsk_path_add_circle()
Adds a circle contour, too.
2022-04-07 22:37:56 -04:00
Benjamin Otte f1d8b96fd3 pathmeasure: Implement support for beziers
Instead of treating bezier curves as lines, we properly decompose them
into line segments now so that we can treat those as lines.
2022-04-07 22:37:56 -04:00
Benjamin Otte 19111abcdd path: Implement gsk_path_to_cairo() using foreach() 2022-04-07 22:37:56 -04:00
Benjamin Otte 32fb2667ff path: Add gsk_path_foreach() 2022-04-07 22:37:56 -04:00
Benjamin Otte e69a774da9 path: Collect flags
We don't need them yet, but maybe later.
2022-04-07 22:37:56 -04:00
Benjamin Otte adb0877a6b testsuite: Add path tests 2022-04-07 22:37:56 -04:00
Benjamin Otte ffb2744408 pathmeasure: Add gsk_path_measure_add_segment()
This allows chunking paths, weeee.
2022-04-07 22:37:56 -04:00
Benjamin Otte 8e073912e4 path: Add gsk_path_builder_add_path() 2022-04-07 22:37:56 -04:00
Benjamin Otte be3e7bbeb0 gsk: Add GskPathMeasure
An object to do measuring operations on paths - determining their
length, cutting off subpaths, things like that.
2022-04-07 22:37:56 -04:00
Benjamin Otte 9dfac7204f path: Change data structure for standard path
Instead of the Cairo method and imitating cairo_path_data_t, use the
Skia method and keep points and operations separate.

That way we get a points array that includes the starting point -
because it's always the end point of the previous operation.
2022-04-07 22:37:56 -04:00
Benjamin Otte 93798a0877 popover: Use fill and stroke nodes instead of Cairo
... to render the arrow.

The arrow should really be turned into a real thing - maybe an icon?
2022-04-07 22:37:56 -04:00
Benjamin Otte a0676cff0e snapshot: Add gtk_snapshot_push_stroke() 2022-04-07 22:37:56 -04:00
Benjamin Otte e501c81621 gsk: Add GskStrokeNode 2022-04-07 22:37:56 -04:00
Benjamin Otte b349519629 gsk: Add GskStroke
It's unused in this commit. This just prepares the new object.
2022-04-07 22:37:56 -04:00
Benjamin Otte 93d8b46a64 demos: Add a simple demo filling a path 2022-04-07 22:37:56 -04:00
Benjamin Otte 92d5dcb37e snapshot: Add gtk_snapshot_push_fill() 2022-04-07 22:37:56 -04:00
Benjamin Otte 5b16d333a6 gsk: Add GskFillNode
Take a rendernode as source and a GskPath and fill the region in the
path just like cairo_fill() would.
2022-04-07 22:37:56 -04:00
Benjamin Otte b3424bad52 gsk: Add GskPath 2022-04-07 22:37:56 -04:00
Matthias Clasen fb7f87618a Add a debug key for paths
Not used yet.
2022-04-07 22:37:56 -04:00
770 changed files with 1056547 additions and 25478 deletions
+2 -3
View File
@@ -25,7 +25,7 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v38"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v36"
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
.only-default:
@@ -58,7 +58,6 @@ style-check-diff:
- "${CI_PROJECT_DIR}/_build/report*.xml"
- "${CI_PROJECT_DIR}/_build/report*.html"
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.png"
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.node"
- "${CI_PROJECT_DIR}/_build/testsuite/tools/output/*/*"
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
@@ -173,7 +172,7 @@ macos:
needs: []
before_script:
- bash .gitlab-ci/show-info-osx.sh
- pip3 install --user meson==0.60.3
- pip3 install --user meson==0.59
- pip3 install --user ninja
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
- export MESON_FORCE_BACKTRACE=1
-3
View File
@@ -14,9 +14,6 @@ Each Docker image has a tag composed of two parts:
See the [container registry][registry] for the available images for each
branch, as well as their available versions.
Note that using `latest` as version number will overwrite the most
recently uploaded image in the registry.
### Checklist for Updating a CI image
- [ ] Update the `${image}.Dockerfile` file with the dependencies
+2 -1
View File
@@ -1,4 +1,4 @@
FROM fedora:36
FROM fedora:34
RUN dnf -y install \
adwaita-icon-theme \
@@ -87,6 +87,7 @@ RUN dnf -y install \
python3-wheel \
redhat-rpm-config \
sassc \
systemtap-sdt-devel \
vulkan-devel \
wayland-devel \
wayland-protocols-devel \
-4
View File
@@ -185,8 +185,6 @@ ul.images li {
<li><img alt="ref" src="{{ failure.image_data.ref }}" /></li>
<li><img alt="out" src="{{ failure.image_data.out }}" /></li>
<li><img alt="diff" src="{{ failure.image_data.diff }}" /></li>
<li><a href="{{ failure.image_data.refnode }}">ref node</a></li>
<li><a href="{{ failure.image_data.outnode }}">out node</a></li>
</ul>
{% endif %}
</li>
@@ -313,8 +311,6 @@ for line in args.infile:
image_data = {
'ref': os.path.join(args.reftest_output_dir, '{}.ref.png'.format(basename)),
'out': os.path.join(args.reftest_output_dir, '{}.out.png'.format(basename)),
'refnode': os.path.join(args.reftest_output_dir, '{}.ref.node'.format(basename)),
'outnode': os.path.join(args.reftest_output_dir, '{}.out.node'.format(basename)),
'diff': os.path.join(args.reftest_output_dir, '{}.diff.png'.format(basename)),
}
+1 -1
View File
@@ -5,7 +5,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
@echo on
:: FIXME: make warnings fatal
pip3 install --upgrade --user meson==0.60.3 || goto :error
pip3 install --upgrade --user meson==0.59 || goto :error
meson -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error
ninja -C _build || goto :error
-150
View File
@@ -1,153 +1,3 @@
Overview of Changes in 4.7.0, 07-05-2022
========================================
* GtkTextView:
- Reduce overdraws
* GtkViewport:
- Default scroll-to-focus to TRUE
* GtkText:
- Stop blinking when we lose focus
* GtkSearchEntry:
- Make search delay configurable
* GtkPopoverMenu:
- Fix RTL positioning of buttons
* GtkLabel:
- Fix focus keynav with links
* GtkFileChooser:
- Prevent undesirable completion popups
- Fix a corner case in save mode
- Keep the portal filechooser alive long enough
* GtkCheckButton:
- Allow setting a custom child
* GtkEditableLabel:
- Make the :editing property writable
* GtkColumnView:
- Various optimizations to improve scrolling performance
* GtkTreeStore:
- Allow populating tree stores from ui files
* GtkBoxLayout:
- Avoid infinite loops
* CSS:
- Optimize reordering within the same parent
* Emoji:
- Update to CLDR v40 / Unicode 14
- Add more locales
* Input:
- Add scroll unit handling
- Handle display changes in GtkIMMultiContext
- Always populate GDK_AXIS_X/Y in event history
- Don't crash for large compose tables
* Accessibility:
- Fix a crash at start when orca is running
* Theme:
- Refresh icons
- Fix selection in vertical spin buttons
- Fix selection in editable labels
* gdk:
- Optimize pixel format conversions
- Use EGL_KHR_swap_buffers_with_damage for NVidia
* gsk:
- Handle large viewports
- Prepare texture libraries for glyphy rendering
- Don't leak big glyphs in the glyph cache
- Align offscreen rendering with th pixel grid
- Check for half-float support before using it
* Wayland:
- Use xdg-activation protocol
- Fix text caret coordinates
- Fix on-screen keyboard activation
* MacOS:
- Fix sluggish and reversed scrolling
- Improve monitor detection
- Event handling fixes
- Fix keyboard input on popovers
- Support OpenGL-based video playback
- Suport fullscreen
- Improve native filechoooser size allocation
- Use CALayer and IOSurface for rendering
- Use a per-monitor CVDisplayLink
- Fix kinetic scrolling
- Improve window placement
- Improve multi-monitor handling
- Start applications in the foreground
- Fix cursor blink time
* Windows:
- Fix preedit window placement on HiDPI
* Tools:
- gtk4-builder-tool: Don't require a display for all commands
- gtk4-builder-tool: Add a screenshot command
- gtk4-node-editor: Install this utility
* Debugging:
- inspector: Show more application data
- inspector: Allow viewing PangoAttrList properties
* Documentation:
- Use the gtk-builder-tool to generate screenshots
* Build:
- Fix cross-compilation
- Fix build on aarch64
- Fix build with gcc 12
* Translation updates
Basque
Brazilian Portuguese
British English
Catalan
Chinese (China)
Chinese (Taiwan)
Croatian
Czech
Danish
Finnish
Galician
Georgian
German
Hebrew
Hungarian
Indonesian
Italian
Kazakh
Korean
Latvian
Lithuanian
Norwegian Bokmål
Persian
Polish
Portuguese
Russian
Serbian
Slovak
Slovenian
Spanish
Swedish
Turkish
Ukrainian
Overview of Changes in 4.6.1, 11-02-2022
========================================
File diff suppressed because it is too large Load Diff
+36
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,
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
+272
View File
@@ -0,0 +1,272 @@
/* 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_curve_to (builder, cx + kr, pad,
w - pad, cy - kr,
w - pad, cy);
gsk_path_builder_curve_to (builder, w - pad, cy + kr,
cx + kr, h - pad,
cx, h - pad);
gsk_path_builder_curve_to (builder, cx - kr, h - pad,
pad, cy + kr,
pad, cy);
gsk_path_builder_curve_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 (GtkColorChooser *chooser,
GParamSpec *pspec,
CurveEditor *editor)
{
GdkRGBA color;
gtk_color_chooser_get_rgba (chooser, &color);
curve_editor_set_color (editor, &color);
}
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_button_new_with_rgba (&(GdkRGBA){ 0., 0., 0., 1.});
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_chooser_set_rgba (GTK_COLOR_CHOOSER (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_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}
+13
View File
@@ -128,6 +128,7 @@
<file>fishbowl.ui</file>
<file>gtkfishbowl.c</file>
<file>gtkfishbowl.h</file>
<file>tiger.node</file>
</gresource>
<gresource prefix="/frames">
<file>frames.ui</file>
@@ -250,6 +251,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>
@@ -267,6 +272,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>dropdown.c</file>
@@ -287,6 +293,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>
@@ -325,6 +332,9 @@
<file>paintable_symbolic.c</file>
<file>panes.c</file>
<file>password_entry.c</file>
<file>path_fill.c</file>
<file>path_maze.c</file>
<file>path_text.c</file>
<file>peg_solitaire.c</file>
<file>pickers.c</file>
<file>printing.c</file>
@@ -409,6 +419,9 @@
<gresource prefix="/fontrendering">
<file>fontrendering.ui</file>
</gresource>
<gresource prefix="/path_text">
<file>path_text.ui</file>
</gresource>
<gresource prefix="/org/gtk/Demo4">
<file>icons/16x16/actions/application-exit.png</file>
<file>icons/16x16/actions/document-new.png</file>
+17
View File
@@ -11,6 +11,9 @@
#include "gtkgears.h"
#include "gskshaderpaintable.h"
#include "nodewidget.h"
#include "graphwidget.h"
const char *const css =
".blurred-button {"
" box-shadow: 0px 0px 5px 10px rgba(0, 0, 0, 0.5);"
@@ -201,6 +204,18 @@ create_menu_button (void)
return w;
}
static GtkWidget *
create_tiger (void)
{
return node_widget_new ("/fishbowl/tiger.node");
}
static GtkWidget *
create_graph (void)
{
return graph_widget_new ();
}
static const struct {
const char *name;
GtkWidget * (*create_func) (void);
@@ -218,6 +233,8 @@ static const struct {
{ "Switch", create_switch },
{ "Menubutton", create_menu_button },
{ "Shader", create_cogs },
{ "Tiger", create_tiger },
{ "Graph", create_graph },
};
static int selected_widget_type = -1;
File diff suppressed because it is too large Load Diff
+164
View File
@@ -0,0 +1,164 @@
#include "graphwidget.h"
struct _GraphWidget
{
GtkWidget parent_instance;
GskPath *path;
GskStroke *stroke;
GdkRGBA color;
GskPath *stroke_path;
guint tick_cb;
guint64 start_time;
double period;
double amplitude;
};
struct _GraphWidgetClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (GraphWidget, graph_widget, GTK_TYPE_WIDGET)
static void
update_path (GraphWidget *self,
float amplitude)
{
graphene_point_t p[20];
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++)
{
p[i].x = 10 * i;
p[i].y = 50;
if (i % 4 == 1 || i % 4 == 2)
{
if (i % 8 < 4)
p[i].y += amplitude;
else
p[i].y -= amplitude;
}
}
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder, p[0].x, p[0].y);
for (int i = 0; i < 20; i += 4)
gsk_path_builder_curve_to (builder,
p[i+1].x, p[i+1].y,
p[i+2].x, p[i+2].y,
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
tick_cb (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
GraphWidget *self = GRAPH_WIDGET (widget);
guint64 now;
double angle;
now = gdk_frame_clock_get_frame_time (frame_clock);
if (self->start_time == 0)
self->start_time = now;
angle = 360 * (now - self->start_time) / (double)(self->period * G_TIME_SPAN_MINUTE);
update_path (self, sin (angle) * self->amplitude);
gtk_widget_queue_draw (widget);
return G_SOURCE_CONTINUE;
}
static void
graph_widget_init (GraphWidget *self)
{
self->color.red = g_random_double_range (0, 1);
self->color.green = g_random_double_range (0, 1);
self->color.blue = g_random_double_range (0, 1);
self->color.alpha = 1;
self->period = g_random_double_range (0.5, 1);
self->amplitude = g_random_double_range (10, 25);
self->stroke = gsk_stroke_new (2);
update_path (self, 0);
self->start_time = 0;
self->tick_cb = gtk_widget_add_tick_callback (GTK_WIDGET (self), tick_cb, NULL, NULL);
}
static void
graph_widget_dispose (GObject *object)
{
GraphWidget *self = GRAPH_WIDGET (object);
gsk_path_unref (self->path);
gsk_stroke_free (self->stroke);
G_OBJECT_CLASS (graph_widget_parent_class)->dispose (object);
}
static void
graph_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GraphWidget *self = GRAPH_WIDGET (widget);
int width, height;
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
graph_widget_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = 200;
else
*minimum = *natural = 100;
}
static void
graph_widget_class_init (GraphWidgetClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = graph_widget_dispose;
widget_class->snapshot = graph_widget_snapshot;
widget_class->measure = graph_widget_measure;
}
GtkWidget *
graph_widget_new (void)
{
return g_object_new (GRAPH_TYPE_WIDGET, NULL);
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include <gtk/gtk.h>
#define GRAPH_TYPE_WIDGET (graph_widget_get_type ())
G_DECLARE_FINAL_TYPE (GraphWidget, graph_widget, GRAPH, WIDGET, GtkWidget)
GtkWidget * graph_widget_new (void);
+1 -2
View File
@@ -23,7 +23,7 @@ do_headerbar (GtkWidget *do_widget)
{
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Welcome to the Hotel California");
gtk_window_set_title (GTK_WINDOW (window), "Welcome to Facebook - Log in, sign up or learn more");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
@@ -31,7 +31,6 @@ do_headerbar (GtkWidget *do_widget)
header = gtk_header_bar_new ();
button = gtk_button_new_from_icon_name ("mail-send-receive-symbolic");
gtk_widget_set_tooltip_text (button, "Check out");
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+1 -1
View File
@@ -100,7 +100,7 @@ show_page (GtkTextView *text_view,
theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (text_view)));
icon = gtk_icon_theme_lookup_icon (theme,
"view-conceal-symbolic",
"eye-not-looking-symbolic",
NULL,
16,
1,
+5 -3
View File
@@ -66,9 +66,11 @@ do_links (GtkWidget *do_widget)
"as hyperlinks, which can be clicked "
"or activated via <a href=\"keynav\">keynav</a> "
"and they work fine with other markup, like when "
"linking to <a href=\"http://www.flathub.org/\"><b>"
"<span letter_spacing=\"1024\" underline=\"none\" color=\"pink\" background=\"darkslategray\">Flathub</span>"
"</b></a>.");
"searching on <a href=\"http://www.google.com/\">"
"<span color=\"#0266C8\">G</span><span color=\"#F90101\">o</span>"
"<span color=\"#F2B50F\">o</span><span color=\"#0266C8\">g</span>"
"<span color=\"#00933B\">l</span><span color=\"#F90101\">e</span>"
"</a>.");
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
gtk_label_set_max_width_chars (GTK_LABEL (label), 40);
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
+8
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',
@@ -70,6 +72,9 @@ demos = files([
'paintable_symbolic.c',
'panes.c',
'password_entry.c',
'path_fill.c',
'path_maze.c',
'path_text.c',
'peg_solitaire.c',
'pickers.c',
'printing.c',
@@ -130,6 +135,9 @@ extra_demo_sources = files([
'unicode-names.c',
'suggestionentry.c',
'language-names.c',
'curve-editor.c',
'nodewidget.c',
'graphwidget.c',
])
if os_unix
+76
View File
@@ -0,0 +1,76 @@
#include "nodewidget.h"
struct _NodeWidget
{
GtkWidget parent_instance;
GskRenderNode *node;
};
struct _NodeWidgetClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (NodeWidget, node_widget, GTK_TYPE_WIDGET)
static void
node_widget_init (NodeWidget *self)
{
}
static void
node_widget_dispose (GObject *object)
{
NodeWidget *self = NODE_WIDGET (object);
gsk_render_node_unref (self->node);
G_OBJECT_CLASS (node_widget_parent_class)->dispose (object);
}
static void
node_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
NodeWidget *self = NODE_WIDGET (widget);
gtk_snapshot_append_node (snapshot, self->node);
}
static void
node_widget_class_init (NodeWidgetClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = node_widget_dispose;
widget_class->snapshot = node_widget_snapshot;
}
GtkWidget *
node_widget_new (const char *resource)
{
NodeWidget *self;
GBytes *bytes;
GskRenderNode *node;
graphene_rect_t bounds;
float scale;
GskTransform *transform;
self = g_object_new (NODE_TYPE_WIDGET, NULL);
bytes = g_resources_lookup_data (resource, 0, NULL);
node = gsk_render_node_deserialize (bytes, NULL, NULL);
g_bytes_unref (bytes);
gsk_render_node_get_bounds (node, &bounds);
scale = MIN (100.0/bounds.size.width, 100.0/bounds.size.height);
transform = gsk_transform_scale (NULL, scale, scale);
self->node = gsk_transform_node_new (node, transform);
gsk_transform_unref (transform);
gsk_render_node_unref (node);
return GTK_WIDGET (self);
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include <gtk/gtk.h>
#define NODE_TYPE_WIDGET (node_widget_get_type ())
G_DECLARE_FINAL_TYPE (NodeWidget, node_widget, NODE, WIDGET, GtkWidget)
GtkWidget * node_widget_new (const char *file);
+348
View File
@@ -0,0 +1,348 @@
/* Path/Text Fill
*
* 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 "paintable.h"
#include "gsk/gskpathdashprivate.h"
#define GTK_TYPE_PATH_PAINTABLE (gtk_path_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathPaintable, gtk_path_paintable, GTK, PATH_PAINTABLE, GObject)
struct _GtkPathPaintable
{
GObject parent_instance;
int width;
int height;
GskPath *path;
GdkPaintable *background;
};
struct _GtkPathPaintableClass
{
GObjectClass parent_class;
};
static int
gtk_path_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
if (self->background)
return MAX (gdk_paintable_get_intrinsic_width (self->background), self->width);
else
return self->width;
}
static int
gtk_path_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
if (self->background)
return MAX (gdk_paintable_get_intrinsic_height (self->background), self->height);
else
return self->height;
}
static void
gtk_path_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkPathPaintable *self = GTK_PATH_PAINTABLE (paintable);
#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)
{
gdk_paintable_snapshot (self->background, snapshot, width, height);
}
else
{
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_pop (snapshot);
}
static GdkPaintableFlags
gtk_path_paintable_get_flags (GdkPaintable *paintable)
{
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_path_paintable_paintable_init (GdkPaintableInterface *iface)
{
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 (GtkPathPaintable, gtk_path_paintable, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_path_paintable_paintable_init))
/* Here's the boilerplate for the GObject declaration.
* We don't need to do anything special here, because we keep no
* data of our own.
*/
static void
gtk_path_paintable_class_init (GtkPathPaintableClass *klass)
{
}
static void
gtk_path_paintable_init (GtkPathPaintable *self)
{
}
/* 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)
{
GtkPathPaintable *self;
self = g_object_new (GTK_TYPE_PATH_PAINTABLE, NULL);
self->path = path;
self->background = background;
if (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);
}
void
gtk_path_paintable_set_path (GtkPathPaintable *self,
GskPath *path)
{
g_clear_pointer (&self->path, gsk_path_unref);
self->path = gsk_path_ref (path);
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
}
static GskPath *
create_hexagon (GtkWidget *widget)
{
GskPathBuilder *builder;
builder = gsk_path_builder_new ();
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);
return gsk_path_builder_free_to_path (builder);
}
static GskPath *
create_path_from_text (GtkWidget *widget)
{
PangoLayout *layout;
PangoFontDescription *desc;
GskPathBuilder *builder;
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);
builder = gsk_path_builder_new ();
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_CURVE:
gsk_path_builder_curve_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;
graphene_point_t pos;
graphene_vec2_t tangent;
GskStroke *stroke;
builder = gsk_path_builder_new ();
gsk_path_builder_add_segment (builder,
measure,
#if 1
0.0, gsk_path_measure_get_length (measure));
#else
progress > 1 ? (progress - 1) * gsk_path_measure_get_length (measure) : 0.0,
(progress < 1 ? progress : 1.0) * gsk_path_measure_get_length (measure));
#endif
path = gsk_path_builder_free_to_path (builder);
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);
gsk_path_unref (path);
gsk_path_measure_get_point (measure,
(progress > 1 ? (progress - 1) : progress) * gsk_path_measure_get_length (measure),
&pos,
&tangent);
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 *
do_path_fill (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
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), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Path Fill");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
#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_keep_aspect_ratio (GTK_PICTURE (picture), FALSE);
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
g_object_unref (paintable);
gtk_window_set_child (GTK_WINDOW (window), picture);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}
+339
View File
@@ -0,0 +1,339 @@
/* Path/Maze
* #Keywords: game, mouse
*
* This demo shows how to use a GskPath to create a maze and use
* 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 <glib/gi18n.h>
#include <gtk/gtk.h>
#include "paintable.h"
#define MAZE_GRID_SIZE 20
#define MAZE_STROKE_SIZE_ACTIVE (MAZE_GRID_SIZE - 4)
#define MAZE_STROKE_SIZE_INACTIVE (MAZE_GRID_SIZE - 12)
#define MAZE_WIDTH 31
#define MAZE_HEIGHT 21
#define GTK_TYPE_MAZE (gtk_maze_get_type ())
G_DECLARE_FINAL_TYPE (GtkMaze, gtk_maze, GTK, MAZE, GtkWidget)
struct _GtkMaze
{
GtkWidget parent_instance;
int width;
int height;
GskPath *path;
GskPathMeasure *measure;
GdkPaintable *background;
gboolean active;
};
struct _GtkMazeClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (GtkMaze, gtk_maze, GTK_TYPE_WIDGET)
static void
gtk_maze_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkMaze *self = GTK_MAZE (widget);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = self->width;
else
*minimum = *natural = self->height;
}
static void
gtk_maze_snapshot (GtkWidget *widget,
GdkSnapshot *snapshot)
{
GtkMaze *self = GTK_MAZE (widget);
double width = gtk_widget_get_width (widget);
double height = gtk_widget_get_height (widget);
GskStroke *stroke;
stroke = gsk_stroke_new (MAZE_STROKE_SIZE_INACTIVE);
if (self->active)
gsk_stroke_set_line_width (stroke, MAZE_STROKE_SIZE_ACTIVE);
gsk_stroke_set_line_join (stroke, GSK_LINE_JOIN_ROUND);
gsk_stroke_set_line_cap (stroke, GSK_LINE_CAP_ROUND);
gtk_snapshot_push_stroke (snapshot, self->path, stroke);
gsk_stroke_free (stroke);
if (self->background)
{
gdk_paintable_snapshot (self->background, snapshot, width, height);
}
else
{
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_pop (snapshot);
}
static void
gtk_maze_dispose (GObject *object)
{
GtkMaze *self = GTK_MAZE (object);
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->measure, gsk_path_measure_unref);
if (self->background)
{
g_signal_handlers_disconnect_matched (self->background, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
g_clear_object (&self->background);
}
G_OBJECT_CLASS (gtk_maze_parent_class)->dispose (object);
}
static void
gtk_maze_class_init (GtkMazeClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_maze_dispose;
widget_class->measure = gtk_maze_measure;
widget_class->snapshot = gtk_maze_snapshot;
}
static void
pointer_motion (GtkEventControllerMotion *controller,
double x,
double y,
GtkMaze *self)
{
if (!self->active)
return;
if (gsk_path_measure_get_closest_point (self->measure, &GRAPHENE_POINT_INIT (x, y), NULL) <= MAZE_STROKE_SIZE_ACTIVE / 2.0f)
return;
self->active = FALSE;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_leave (GtkEventControllerMotion *controller,
GtkMaze *self)
{
if (!self->active)
{
self->active = TRUE;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
}
static void
gtk_maze_init (GtkMaze *self)
{
GtkEventController *controller;
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
self->active = TRUE;
}
static void
gtk_maze_set_path (GtkMaze *self,
GskPath *path)
{
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->measure, gsk_path_measure_unref);
self->path = gsk_path_ref (path);
self->measure = gsk_path_measure_new (path);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
GtkWidget *
gtk_maze_new (GskPath *path,
GdkPaintable *background,
int width,
int height)
{
GtkMaze *self;
self = g_object_new (GTK_TYPE_MAZE, NULL);
gtk_maze_set_path (self, path);
gsk_path_unref (path);
self->background = background;
if (self->background)
{
g_signal_connect_swapped (self->background, "invalidate-contents", G_CALLBACK (gtk_widget_queue_draw), self);
g_signal_connect_swapped (self->background, "invalidate-size", G_CALLBACK (gtk_widget_queue_resize), self);
}
self->width = width;
self->height = height;
return GTK_WIDGET (self);
}
static void
add_point_to_maze (GtkBitset *maze,
GskPathBuilder *builder,
guint x,
guint y)
{
gboolean set[4] = { };
guint dir;
gtk_bitset_add (maze, y * MAZE_WIDTH + x);
while (TRUE)
{
set[0] = set[0] || x == 0 || gtk_bitset_contains (maze, y * MAZE_WIDTH + x - 1);
set[1] = set[1] || y == 0 || gtk_bitset_contains (maze, (y - 1) * MAZE_WIDTH + x);
set[2] = set[2] || x + 1 == MAZE_WIDTH || gtk_bitset_contains (maze, y * MAZE_WIDTH + x + 1);
set[3] = set[3] || y + 1 == MAZE_HEIGHT || gtk_bitset_contains (maze, (y + 1) * MAZE_WIDTH + x);
if (set[0] && set[1] && set[2] && set[3])
return;
do
{
dir = g_random_int_range (0, 4);
}
while (set[dir]);
switch (dir)
{
case 0:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x - 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x - 1, y);
break;
case 1:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y - 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x, y - 1);
break;
case 2:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 1.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x + 1, y);
break;
case 3:
gsk_path_builder_move_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 0.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (x + 0.5) * MAZE_GRID_SIZE, (y + 1.5) * MAZE_GRID_SIZE);
add_point_to_maze (maze, builder, x, y + 1);
break;
default:
g_assert_not_reached ();
break;
}
}
}
static GskPath *
create_path_for_maze (GtkWidget *widget)
{
GskPathBuilder *builder;
GtkBitset *maze;
builder = gsk_path_builder_new ();
maze = gtk_bitset_new_empty ();
/* make sure the outer lines are unreachable:
* Set the full range, then remove the center again. */
gtk_bitset_add_range (maze, 0, MAZE_WIDTH * MAZE_HEIGHT);
gtk_bitset_remove_rectangle (maze, MAZE_WIDTH + 1, MAZE_WIDTH - 2, MAZE_HEIGHT - 2, MAZE_WIDTH);
/* Fill the maze */
add_point_to_maze (maze, builder, MAZE_WIDTH / 2, MAZE_HEIGHT / 2);
/* Add start and stop lines */
gsk_path_builder_move_to (builder, 1.5 * MAZE_GRID_SIZE, -0.5 * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, 1.5 * MAZE_GRID_SIZE, 1.5 * MAZE_GRID_SIZE);
gsk_path_builder_move_to (builder, (MAZE_WIDTH - 1.5) * MAZE_GRID_SIZE, (MAZE_HEIGHT - 1.5) * MAZE_GRID_SIZE);
gsk_path_builder_line_to (builder, (MAZE_WIDTH - 1.5) * MAZE_GRID_SIZE, (MAZE_HEIGHT + 0.5) * MAZE_GRID_SIZE);
gtk_bitset_unref (maze);
return gsk_path_builder_free_to_path (builder);
}
GtkWidget *
do_path_maze (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *maze;
GtkMediaStream *stream;
GskPath *path;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Follow the maze with the mouse");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
#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_path_for_maze (window);
maze = gtk_maze_new (path,
GDK_PAINTABLE (stream),
MAZE_WIDTH * MAZE_GRID_SIZE,
MAZE_HEIGHT * MAZE_GRID_SIZE);
gtk_window_set_child (GTK_WINDOW (window), maze);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}
+594
View File
@@ -0,0 +1,594 @@
/* Path/Curved Text
*
* This demo shows how to use GskPath to animate a path along another path.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#define GTK_TYPE_PATH_WIDGET (gtk_path_widget_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathWidget, gtk_path_widget, GTK, PATH_WIDGET, GtkWidget)
#define POINT_SIZE 8
enum {
PROP_0,
PROP_TEXT,
PROP_EDITABLE,
N_PROPS
};
struct _GtkPathWidget
{
GtkWidget parent_instance;
char *text;
gboolean editable;
graphene_point_t points[4];
guint active_point;
float line_closest;
GskPath *line_path;
GskPathMeasure *line_measure;
GskPath *text_path;
GdkPaintable *background;
};
struct _GtkPathWidgetClass
{
GtkWidgetClass parent_class;
};
static GParamSpec *properties[N_PROPS] = { NULL, };
G_DEFINE_TYPE (GtkPathWidget, gtk_path_widget, GTK_TYPE_WIDGET)
static GskPath *
create_path_from_text (GtkWidget *widget,
const char *text)
{
cairo_surface_t *surface;
cairo_t *cr;
cairo_path_t *path;
PangoLayout *layout;
PangoFontDescription *desc;
GskPath *result;
surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL);
cr = cairo_create (surface);
layout = gtk_widget_create_pango_layout (widget, text);
desc = pango_font_description_from_string ("sans bold 36");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
cairo_move_to (cr, 0, - pango_layout_get_baseline (layout) / (double) PANGO_SCALE);
pango_cairo_layout_path (cr, layout);
path = cairo_copy_path (cr);
result = gsk_path_new_from_cairo (path);
cairo_path_destroy (path);
g_object_unref (layout);
cairo_destroy (cr);
cairo_surface_destroy (surface);
return result;
}
typedef struct
{
GskPathMeasure *measure;
GskPathBuilder *builder;
double scale;
} GtkPathTransform;
static void
gtk_path_transform_point (GskPathMeasure *measure,
const graphene_point_t *pt,
float scale,
graphene_point_t *res)
{
graphene_vec2_t tangent;
gsk_path_measure_get_point (measure, pt->x * scale, res, &tangent);
res->x -= pt->y * scale * graphene_vec2_get_y (&tangent);
res->y += pt->y * scale * graphene_vec2_get_x (&tangent);
}
static gboolean
gtk_path_transform_op (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer data)
{
GtkPathTransform *transform = data;
switch (op)
{
case GSK_PATH_MOVE:
{
graphene_point_t res;
gtk_path_transform_point (transform->measure, &pts[0], transform->scale, &res);
gsk_path_builder_move_to (transform->builder, res.x, res.y);
}
break;
case GSK_PATH_LINE:
{
graphene_point_t res;
gtk_path_transform_point (transform->measure, &pts[1], transform->scale, &res);
gsk_path_builder_line_to (transform->builder, res.x, res.y);
}
break;
case GSK_PATH_CURVE:
{
graphene_point_t res[3];
gtk_path_transform_point (transform->measure, &pts[1], transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[2], transform->scale, &res[1]);
gtk_path_transform_point (transform->measure, &pts[3], transform->scale, &res[2]);
gsk_path_builder_curve_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, res[2].x, res[2].y);
}
break;
case GSK_PATH_CONIC:
{
graphene_point_t res[2];
gtk_path_transform_point (transform->measure, &pts[1], transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[2], 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;
case GSK_PATH_CLOSE:
gsk_path_builder_close (transform->builder);
break;
default:
g_assert_not_reached();
return FALSE;
}
return TRUE;
}
static GskPath *
gtk_path_transform (GskPathMeasure *measure,
GskPath *path)
{
GtkPathTransform transform = { measure, gsk_path_builder_new () };
graphene_rect_t bounds;
gsk_path_get_bounds (path, &bounds);
if (bounds.origin.x + bounds.size.width > 0)
transform.scale = gsk_path_measure_get_length (measure) / (bounds.origin.x + bounds.size.width);
else
transform.scale = 1.0f;
gsk_path_foreach (path, GSK_PATH_FOREACH_ALLOW_CURVE, gtk_path_transform_op, &transform);
return gsk_path_builder_free_to_path (transform.builder);
}
static void
gtk_path_widget_clear_text_path (GtkPathWidget *self)
{
g_clear_pointer (&self->text_path, gsk_path_unref);
}
static void
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
gtk_path_widget_create_text_path (GtkPathWidget *self)
{
GskPath *path;
gtk_path_widget_clear_text_path (self);
if (self->line_measure == NULL)
return;
path = create_path_from_text (GTK_WIDGET (self), self->text);
self->text_path = gtk_path_transform (self->line_measure, path);
gsk_path_unref (path);
}
static void
gtk_path_widget_create_paths (GtkPathWidget *self)
{
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
GskPathBuilder *builder;
gtk_path_widget_clear_paths (self);
if (width <= 0 || height <= 0)
return;
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder,
self->points[0].x * width, self->points[0].y * height);
gsk_path_builder_curve_to (builder,
self->points[1].x * width, self->points[1].y * height,
self->points[2].x * width, self->points[2].y * height,
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);
}
static void
gtk_path_widget_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
GTK_WIDGET_CLASS (gtk_path_widget_parent_class)->size_allocate (widget, width, height, baseline);
gtk_path_widget_create_paths (self);
}
static void
gtk_path_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
double width = gtk_widget_get_width (widget);
double height = gtk_widget_get_height (widget);
GskPath *path;
GskStroke *stroke;
gsize i;
/* frosted glass the background */
gtk_snapshot_push_blur (snapshot, 100);
gdk_paintable_snapshot (self->background, snapshot, width, height);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 0.5 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
/* draw the text */
if (self->text_path)
{
gtk_snapshot_push_fill (snapshot, self->text_path, GSK_FILL_RULE_WINDING);
gdk_paintable_snapshot (self->background, snapshot, width, height);
/* ... with an emboss effect */
stroke = gsk_stroke_new (2.0);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT(1, 1));
gtk_snapshot_push_stroke (snapshot, self->text_path, stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 0.2 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gsk_stroke_free (stroke);
gtk_snapshot_pop (snapshot);
gtk_snapshot_pop (snapshot);
}
if (self->editable && self->line_path)
{
/* draw the control line */
stroke = gsk_stroke_new (1.0);
gtk_snapshot_push_stroke (snapshot, self->line_path, stroke);
gsk_stroke_free (stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
}
if (self->line_closest >= 0)
{
GskPathBuilder *builder;
graphene_point_t closest;
builder = gsk_path_builder_new ();
gsk_path_measure_get_point (self->line_measure, self->line_closest, &closest, NULL);
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);
}
if (self->editable && self->line_path)
{
GskPathBuilder *builder;
/* draw the points */
builder = gsk_path_builder_new ();
for (i = 0; i < 4; i++)
{
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), 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) { 1, 1, 1, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
stroke = gsk_stroke_new (1.0);
gtk_snapshot_push_stroke (snapshot, path, stroke);
gsk_stroke_free (stroke);
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);
}
}
static void
gtk_path_widget_set_text (GtkPathWidget *self,
const char *text)
{
if (g_strcmp0 (self->text, text) == 0)
return;
g_free (self->text);
self->text = g_strdup (text);
gtk_path_widget_create_paths (self);
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TEXT]);
}
static void
gtk_path_widget_set_editable (GtkPathWidget *self,
gboolean editable)
{
if (self->editable == editable)
return;
self->editable = editable;
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_EDITABLE]);
}
static void
gtk_path_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
switch (prop_id)
{
case PROP_TEXT:
gtk_path_widget_set_text (self, g_value_get_string (value));
break;
case PROP_EDITABLE:
gtk_path_widget_set_editable (self, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
switch (prop_id)
{
case PROP_TEXT:
g_value_set_string (value, self->text);
break;
case PROP_EDITABLE:
g_value_set_boolean (value, self->editable);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_widget_dispose (GObject *object)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
gtk_path_widget_clear_paths (self);
G_OBJECT_CLASS (gtk_path_widget_parent_class)->dispose (object);
}
static void
gtk_path_widget_class_init (GtkPathWidgetClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_path_widget_dispose;
object_class->set_property = gtk_path_widget_set_property;
object_class->get_property = gtk_path_widget_get_property;
widget_class->size_allocate = gtk_path_widget_allocate;
widget_class->snapshot = gtk_path_widget_snapshot;
properties[PROP_TEXT] =
g_param_spec_string ("text",
"text",
"Text transformed along a path",
NULL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_EDITABLE] =
g_param_spec_boolean ("editable",
"editable",
"If the path can be edited by the user",
FALSE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
drag_begin (GtkGestureDrag *gesture,
double x,
double y,
GtkPathWidget *self)
{
graphene_point_t mouse = GRAPHENE_POINT_INIT (x, y);
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
gsize i;
for (i = 0; i < 4; i++)
{
if (graphene_point_distance (&GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), &mouse, NULL, NULL) <= POINT_SIZE)
{
self->active_point = i;
break;
}
}
if (i == 4)
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
return;
}
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
drag_update (GtkGestureDrag *drag,
double offset_x,
double offset_y,
GtkPathWidget *self)
{
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
double start_x, start_y;
gtk_gesture_drag_get_start_point (drag, &start_x, &start_y);
self->points[self->active_point] = GRAPHENE_POINT_INIT ((start_x + offset_x) / width,
(start_y + offset_y) / height);
self->points[self->active_point].x = CLAMP (self->points[self->active_point].x, 0, 1);
self->points[self->active_point].y = CLAMP (self->points[self->active_point].y, 0, 1);
gtk_path_widget_create_paths (self);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_motion (GtkEventControllerMotion *controller,
double x,
double y,
GtkPathWidget *self)
{
gsk_path_measure_get_closest_point_full (self->line_measure,
&GRAPHENE_POINT_INIT (x, y),
INFINITY,
NULL, NULL,
&self->line_closest,
NULL);
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));
}
static void
gtk_path_widget_init (GtkPathWidget *self)
{
GtkEventController *controller;
controller = GTK_EVENT_CONTROLLER (gtk_gesture_drag_new ());
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_update), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
g_signal_connect (controller, "enter", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), 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);
self->points[3] = GRAPHENE_POINT_INIT (0.9, 0.9);
self->background = GDK_PAINTABLE (gdk_texture_new_from_resource ("/sliding_puzzle/portland-rose.jpg"));
gtk_path_widget_set_text (self, "It's almost working");
}
GtkWidget *
gtk_path_widget_new (void)
{
GtkPathWidget *self;
self = g_object_new (GTK_TYPE_PATH_WIDGET, NULL);
return GTK_WIDGET (self);
}
GtkWidget *
do_path_text (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkBuilder *builder;
g_type_ensure (GTK_TYPE_PATH_WIDGET);
builder = gtk_builder_new_from_resource ("/path_text/path_text.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}
+38
View File
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">Text along a Path</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child type="end">
<object class="GtkToggleButton" id="edit-toggle">
<property name="icon-name">document-edit-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkRevealer">
<property name="reveal-child" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
<child>
<object class="GtkEntry" id="text">
<property name="text">Through the looking glass</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkPathWidget" id="view">
<property name="editable" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
<property name="text" bind-source="text" bind-property="text" bind-flags="sync-create"></property>
<property name="hexpand">true</property>
<property name="vexpand">true</property>
</object>
</child>
</object>
</child>
</object>
</interface>
File diff suppressed because it is too large Load Diff
+6 -18
View File
@@ -19,24 +19,12 @@ executable('gtk4-node-editor',
] + common_cflags,
win_subsystem: 'windows',
link_args: extra_demo_ldflags,
install: true,
install: false,
)
# icons
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
foreach size: ['scalable', 'symbolic']
install_subdir('data/' + size, install_dir: icontheme_dir)
endforeach
# desktop file
install_data('org.gtk.gtk4.NodeEditor.desktop', install_dir: gtk_applicationsdir)
# appdata
configure_file(
input: 'org.gtk.gtk4.NodeEditor.appdata.xml.in',
output: 'org.gtk.gtk4.NodeEditor.appdata.xml',
configuration: appdata_config,
install_dir: gtk_appdatadir
)
# icons, don't install them until we decide to install gtk4-node-editor
#icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
#foreach size: ['scalable', 'symbolic']
# install_subdir('data/' + size, install_dir: icontheme_dir)
#endforeach
-23
View File
@@ -57,7 +57,6 @@ struct _NodeEditorWindow
GtkWidget *testcase_cairo_checkbutton;
GtkWidget *testcase_name_entry;
GtkWidget *testcase_save_button;
GtkWidget *scale_scale;
GtkWidget *renderer_listbox;
GListStore *renderers;
@@ -172,7 +171,6 @@ text_changed (GtkTextBuffer *buffer,
GBytes *bytes;
GtkTextIter iter;
GtkTextIter start, end;
float scale;
g_array_remove_range (self->errors, 0, self->errors->len);
text = get_current_text (self->text_buffer);
@@ -183,17 +181,6 @@ text_changed (GtkTextBuffer *buffer,
/* If this is too slow, go fix the parser performance */
self->node = gsk_render_node_deserialize (bytes, deserialize_error_func, self);
scale = gtk_scale_button_get_value (GTK_SCALE_BUTTON (self->scale_scale));
if (self->node && scale != 1.0)
{
GskRenderNode *node;
node = gsk_transform_node_new (self->node, gsk_transform_scale (NULL, scale, scale));
gsk_render_node_unref (self->node);
self->node = node;
}
g_bytes_unref (bytes);
if (self->node)
{
@@ -290,14 +277,6 @@ text_changed (GtkTextBuffer *buffer,
&start, &end);
}
static void
scale_changed (GObject *object,
GParamSpec *pspec,
NodeEditorWindow *self)
{
text_changed (self->text_buffer, self);
}
static gboolean
text_view_query_tooltip_cb (GtkWidget *widget,
int x,
@@ -983,7 +962,6 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, testcase_cairo_checkbutton);
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, testcase_name_entry);
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, testcase_save_button);
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, scale_scale);
gtk_widget_class_bind_template_callback (widget_class, text_view_query_tooltip_cb);
gtk_widget_class_bind_template_callback (widget_class, open_cb);
@@ -1090,7 +1068,6 @@ node_editor_window_init (NodeEditorWindow *self)
self->text_buffer = gtk_text_buffer_new (self->tag_table);
g_signal_connect (self->text_buffer, "changed", G_CALLBACK (text_changed), self);
g_signal_connect (self->scale_scale, "notify::value", G_CALLBACK (scale_changed), self);
gtk_text_view_set_buffer (GTK_TEXT_VIEW (self->text_view), self->text_buffer);
/* Default */
-17
View File
@@ -157,23 +157,6 @@
<signal name="notify::active" handler="dark_mode_cb" swapped="0"/>
</object>
</child>
<child type="end">
<object class="GtkScaleButton" id="scale_scale">
<property name="focus-on-click">0</property>
<property name="valign">center</property>
<property name="adjustment">
<object class="GtkAdjustment">
<property name="lower">1</property>
<property name="value">1</property>
<property name="upper">10</property>
<property name="step-increment">0.1</property>
<property name="page-increment">0.5</property>
</object>
</property>
<property name="icons">zoom-in-symbolic</property>
<property name="tooltip-text" translatable="yes">Scale the image</property>
</object>
</child>
</object>
</child>
<child>
@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>org.gtk.gtk4.NodeEditor</id>
<launchable type="desktop-id">org.gtk.gtk4.NodeEditor.desktop</launchable>
<metadata_license>CC0-1.0</metadata_license>
<project_license>LGPL-2.1-or-later</project_license>
<name>GTK Node Editor</name>
<summary>Program to edit render node files</summary>
<description>
<p>
GTK Node Editor is a simple application to show and edit
render node files.
</p>
<p>
Render node files can e.g. be created by the GTK inspector.
</p>
</description>
<screenshots>
<screenshot>
<image>https://static.gnome.org/appdata/gtk4-node-editor/gtk4-node-editor.png</image>
<caption>Node Editor</caption>
</screenshot>
</screenshots>
<kudos>
<kudo>HiDpiIcon</kudo>
<kudo>ModernToolkit</kudo>
</kudos>
<url type="homepage">https://www.gtk.org</url>
<translation type="gettext">gtk-4.0</translation>
<update_contact>matthias.clasen_at_gmail.com</update_contact>
<developer_name>Matthias Clasen and others</developer_name>
<content_rating type="oars-1.1"/>
<releases>
<release version="@BUILD_VERSION@">
<description>
<p>A new build of GTK.</p>
</description>
</release>
</releases>
</component>
@@ -1,9 +0,0 @@
[Desktop Entry]
Name=Node Editor
Comment=An application that edits render nodes
Exec=gtk4-node-editor
Icon=org.gtk.gtk4.NodeEditor
Terminal=false
Type=Application
StartupNotify=true
Categories=Development;GTK;
+1 -1
View File
@@ -5,7 +5,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
website_url = "https://www.gtk.org"
authors = "GTK Development Team"
logo_url = "gtk-logo.svg"
license = "LGPL-2.1-or-later"
license = "GPL-2.1-or-later"
description = "The GTK toolkit"
devhelp = true
+1 -1
View File
@@ -5,7 +5,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
website_url = "https://www.gtk.org"
authors = "GTK Development Team"
logo_url = "gtk-logo.svg"
license = "LGPL-2.1-or-later"
license = "GPL-2.1-or-later"
description = "The GTK toolkit"
dependencies = ["Gdk-4.0"]
devhelp = true
+1 -29
View File
@@ -16,7 +16,6 @@ SYNOPSIS
| **gtk4-builder-tool** enumerate <FILE>
| **gtk4-builder-tool** simplify [OPTIONS...] <FILE>
| **gtk4-builder-tool** preview [OPTIONS...] <FILE>
| **gtk4-builder-tool** screenshot [OPTIONS...] <FILE>
DESCRIPTION
-----------
@@ -42,7 +41,7 @@ definition file.
Preview
^^^^^^^
The ``preview`` command displays the UI definition file.
The ``preview`` command displays the UI dfinition file.
This command accepts options to specify the ID of the toplevel object and a CSS
file to use.
@@ -56,33 +55,6 @@ file to use.
Load style information from the given CSS file.
Screenshot
^^^^^^^^^^
The ``screenshot`` command saves a rendering of the UI definition file
as a png image or node file. The name of the file to write can be specified as
a second FILE argument.
This command accepts options to specify the ID of the toplevel object and a CSS
file to use.
``--id=ID``
The ID of the object to preview. If not specified, gtk4-builder-tool will
choose a suitable object on its own.
``--css=FILE``
Load style information from the given CSS file.
``--node``
Write a serialized node file instead of a png image.
``--force``
Overwrite an existing file.
Simplification
^^^^^^^^^^^^^^
-27
View File
@@ -1,27 +0,0 @@
.. _gtk4-node-editor(1):
=================
gtk4-node-editor
=================
-----------------
Editor render nodes
-----------------
SYNOPSIS
--------
| **gtk4-node-editor** [OPTIONS...]
DESCRIPTION
-----------
``gtk4-node-editor`` is a utility to show and edit render node files.
Such render node files can be obtained e.g. from the GTK inspector.
OPTIONS
-------
``-h, --help``
Show the application help.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 20 KiB

-16
View File
@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkAboutDialog">
<property name="program-name">GTK Code Demos</property>
<property name="version">4.8.0</property>
<property name="copyright">© 1997-2022 The GTK Team</property>
<property name="comments">Program to demonstrate GTK functions</property>
<property name="logo">gtk-logo.png</property>
<property name="title">About GTK Code Demos</property>
<property name="authors">Peter Mattis
Spencer Kimball
Josh MacDonald
and many more…
</property>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

-47
View File
@@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<child>
<object class="GtkTextView">
<property name="vexpand">1</property>
</object>
</child>
<child>
<object class="GtkActionBar">
<child>
<object class="GtkButton">
<property name="icon-name">object-select-symbolic</property>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">call-start-symbolic</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

@@ -1,43 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkAppChooserButton">
<property name="content-type">text/plain</property>
<property name="halign">center</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Application Button</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 22 KiB

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkAppChooserDialog">
<property name="content-type">image/png</property>
<property name="default-width">200</property>
<property name="default-height">300</property>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

-30
View File
@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkAssistant">
<property name="resizable">0</property>
<property name="default-width">300</property>
<property name="default-height">140</property>
<property name="title">Assistant</property>
<child>
<object class="GtkAssistantPage">
<property name="title">Assistant page</property>
<property name="complete">1</property>
<property name="child">
<object class="GtkLabel">
<property name="label">Assistant</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkAssistantPage">
<property name="page-type">confirm</property>
<property name="child">
<object class="GtkLabel">
<property name="label">You sure?</property>
</object>
</property>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

-96
View File
@@ -1,96 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="homogeneous">1</property>
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="spacing">4</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkButton">
<style><class name="small-button"/></style>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkButton">
<style><class name="small-button"/></style>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">⋯</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">4</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkButton">
<style><class name="small-button"/></style>
<property name="halign">center</property>
</object>
</child>
<child>
<object class="GtkButton">
<style><class name="small-button"/></style>
<property name="halign">center</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">⋮</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="justify">center</property>
<property name="label">Horizontal and Vertical Boxes</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

-30
View File
@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkButton">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="label">Button</property>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 16 KiB

-44
View File
@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<child>
<object class="GtkCalendar">
<property name="halign">center</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Calendar</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

-63
View File
@@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<child>
<object class="GtkCenterBox">
<property name="orientation">horizontal</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">fill</property>
<child type="start">
<object class="GtkButton">
<style><class name="small-button"/></style>
<property name="valign">center</property>
</object>
</child>
<child type="center">
<object class="GtkButton">
<style><class name="small-button"/></style>
<property name="valign">center</property>
</object>
</child>
<child type="end">
<object class="GtkButton">
<style><class name="small-button"/></style>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="justify">center</property>
<property name="label">Center Box</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

-43
View File
@@ -1,43 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkCheckButton">
<property name="active">1</property>
<property name="label">Check Button</property>
</object>
</child>
<child>
<object class="GtkCheckButton">
<property name="active">0</property>
<property name="label">Check Button</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

-43
View File
@@ -1,43 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkColorButton">
<property name="rgba">#1e90ff</property>
<property name="halign">center</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Color Button</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkColorChooserDialog">
<property name="title">Color Chooser Dialog</property>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

@@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkComboBox">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="has-entry">1</property>
<child internal-child="entry">
<object class="GtkEntry">
<property name="text">Combo Box Entry</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkComboBoxText">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<items>
<item>Combo Box Text</item>
</items>
<property name="active">0</property>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

-49
View File
@@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkComboBox">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="model">
<object class="GtkListStore">
<columns>
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0">Combo Box</col>
</row>
</data>
</object>
</property>
<child>
<object class="GtkCellRendererText">
</object>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
<property name="active">0</property>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

-30
View File
@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkDialog">
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<property name="title">Dialog</property>
<child type="action">
<object class="GtkButton" id="button_cancel">
<property name="label">Cancel</property>
</object>
</child>
<child type="action">
<object class="GtkButton" id="button_ok">
<property name="label">Accept</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Content</property>
<property name="hexpand">1</property>
<property name="halign">center</property>
</object>
</child>
<action-widgets>
<action-widget response="ok" default="true">button_ok</action-widget>
<action-widget response="cancel" default="true">button_cancel</action-widget>
</action-widgets>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

-49
View File
@@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">fill</property>
<property name="valign">center</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<child>
<object class="GtkFrame">
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<child>
<object class="GtkPicture">
<property name="paintable">drawingarea-content.png</property>
<property name="halign">center</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Drawing Area</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

-37
View File
@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkDropDown">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="model">
<object class="GtkStringList">
<items>
<item>Drop Down</item>
<item>Almost a combo</item>
</items>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<property name="focus-widget">editable2</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkEditableLabel">
<property name="text">Editable Label</property>
</object>
</child>
<child>
<object class="GtkSeparator">
</object>
</child>
<child>
<object class="GtkEditableLabel" id="editable2">
<property name="text">Editable Label</property>
<property name="editing">1</property>
<style>
<class name="frame"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 54 KiB

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkEmojiChooser">
<property name="autohide">0</property>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

-34
View File
@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkEntry">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">fill</property>
<property name="valign">center</property>
<property name="text">Entry</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

-34
View File
@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkExpander">
<property name="label">Expander</property>
<property name="hexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkLabel">
<property name="label">Hidden Content</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

-66
View File
@@ -1,66 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="frame"/>
<class name="shadow"/>
<class name="background"/>
</style>
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<child>
<object class="GtkFlowBox">
<property name="min-children-per-line">2</property>
<property name="max-children-per-line">2</property>
<property name="selection-mode">browse</property>
<child>
<object class="GtkLabel">
<property name="label">Child One</property>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Child Two</property>
</object>
</child>
<child>
<object class="GtkFlowBoxChild">
<child>
<object class="GtkBox">
<property name="orientation">horizontal</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="label">Child Three</property>
</object>
</child>
<child>
<object class="GtkCheckButton">
<property name="active">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Flow Box</property>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

-43
View File
@@ -1,43 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkFontButton">
<property name="font-desc">Sans Serif 10</property>
<property name="halign">center</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Font Button</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 40 KiB

-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkFontChooserDialog">
<property name="default-width">200</property>
<property name="default-height">300</property>
<property name="title">Font Chooser Dialog</property>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

-34
View File
@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkFrame">
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">fill</property>
<property name="valign">fill</property>
<property name="label">Frame</property>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

-54
View File
@@ -1,54 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-width">150</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">fill</property>
<property name="valign">center</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<child>
<object class="GtkFrame">
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<style>
<class name="black"/>
</style>
<child>
<object class="GtkPicture">
<property name="paintable">glarea-content.png</property>
<property name="halign">center</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">GL Area</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

-101
View File
@@ -1,101 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<child>
<object class="GtkGrid">
<property name="row-spacing">4</property>
<property name="column-spacing">4</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkButton">
<style><class name="small-button"/></style>
<property name="valign">center</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<style><class name="small-button"/></style>
<property name="valign">center</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<style><class name="small-button"/></style>
<property name="valign">center</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<style><class name="small-button"/></style>
<property name="valign">center</property>
<layout>
<property name="column">1</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">⋯</property>
<layout>
<property name="column">2</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">⋮</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
</layout>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="justify">center</property>
<property name="label">Grid</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

-23
View File
@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="resizable">0</property>
<property name="default-width">220</property>
<property name="default-height">150</property>
<property name="title">Header Bar</property>
<child type='titlebar'>
<object class="GtkHeaderBar">
<child type='end'>
<object class="GtkButton">
<property name="icon-name">bookmark-new-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkTextView">
<property name="cursor-visible">0</property>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

-71
View File
@@ -1,71 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkListStore" id="store">
<columns>
<column type="gchararray"/>
<column type="GdkPixbuf"/>
</columns>
<data>
<row>
<col id="0">One</col>
<col id="1">folder.png</col>
</row>
<row>
<col id="0">Two</col>
<col id="1">gnome.png</col>
</row>
</data>
</object>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<child>
<object class="GtkScrolledWindow">
<style>
<class name="frame"/>
</style>
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">never</property>
<property name="propagate-natural-height">1</property>
<child>
<object class="GtkIconView">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="model">store</property>
<property name="text-column">0</property>
<property name="pixbuf-column">1</property>
<property name="item-orientation">horizontal</property>
<property name="row-spacing">0</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Icon View</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

-44
View File
@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkImage">
<property name="icon-name">applications-graphics</property>
<property name="icon-size">large</property>
<property name="halign">center</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Image</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

-40
View File
@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="resizable">0</property>
<property name="default-width">280</property>
<property name="default-height">120</property>
<style>
<class name="nobackground"/>
</style>
<child>
<object class="GtkBox">
<style>
<class name="shadow"/>
<class name="background"/>
<class name="frame"/>
</style>
<child>
<object class="GtkInfoBar">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">fill</property>
<property name="valign">center</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="show-close-button">1</property>
<property name="message-type">info</property>
<child>
<object class="GtkLabel">
<property name="label">Info Bar</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

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