Compare commits

..

3 Commits

Author SHA1 Message Date
Nelson Benítez León
bab2bf2596 widget-factory: add example on styling tooltip window
by using new api:
  gtk_tooltip_set_css_class()
  GtkWidget signals 'tooltip-show' and 'tooltip-hide'

Part of #5925
2023-07-09 17:07:09 -04:00
Nelson Benítez León
11b4e4a467 GtkWidget: add new signals 'tooltip-show' and 'tooltip-hide'
which are emitted when a tooltip window is about to be shown
on a widget, and when a tooltip window stopped being shown
on a widget.

These signals provide two convenient moments for where to style
our tooltip window in case we want to do so by adding a css
class to it.

The existant signal 'query-tooltip' could not be used for that
as it's triggered on motion events and we cannot distinguish
from that when the tooltip window gets shown or hidden.

Part of issue #5925
2023-07-09 17:07:09 -04:00
Nelson Benítez León
1cae0cd54c GtkToolTip: new API to add css classes to GtkTooltipWindow
we add a simple API to allow styling GtkTooltip's window
by setting a css class on it:

void gtk_tooltip_set_css_class (GtkTooltip *tooltip,
                                const char *css_class);

By passing NULL it will remove any previously set css class
by this function.

Issue #5925
2023-07-09 17:07:09 -04:00
542 changed files with 29061 additions and 94159 deletions

View File

@@ -26,20 +26,12 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Dbuild-testsuite=true -Dintrospection=enabled"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v48"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v46"
workflow:
rules:
# run merge request pipelines
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# do not run branch pipelines if corresponding merge requests exist...
# (this avoids duplicate pipelines)
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
# ...but otherwise run branch pipelines
- if: $CI_COMMIT_BRANCH
# run tag pipelines
- if: $CI_COMMIT_TAG
- if: $CI_COMMIT_BRANCH
default:
retry:
@@ -205,32 +197,21 @@ msys2-mingw64:
paths:
- "${CI_PROJECT_DIR}/_build/gtkdll.tar.gz"
macos-x86_64:
macos:
# Sadly, this fails regularly, and its failure is never enlightening
allow_failure: true
rules:
# run merge request pipelines
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# do not run in forks
- if: $CI_PROJECT_NAMESPACE == "GNOME"
stage: build
tags:
- macosintel
- macos
needs: []
variables:
MESON_FORCE_BACKTRACKE: 1
TMPDIR: /Users/Shared/work/tmp
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
CCACHE_DIR: /Users/Shared/work/ccache
PIP_CACHE_DIR: /Users/Shared/build/cache
PIPENV_CACHE_DIR: $PIP_CACHE_DIR
PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR
before_script:
- bash .gitlab-ci/show-info-osx.sh
- python3 -m venv .venv
- ln -s /opt/cmake/CMake.app/Contents/bin/cmake .venv/bin
- ln -s /opt/ccache/ccache .venv/bin
- source .venv/bin/activate
- pip3 install meson==1.2.0
- pip3 install ninja==1.11.1
- pip3 install --user meson~=1.0
- pip3 install --user ninja
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
- export MESON_FORCE_BACKTRACE=1
script:
- meson setup ${COMMON_MESON_FLAGS}
-Dx11-backend=false
@@ -437,11 +418,10 @@ reference:
--buildtype=release
--force-fallback-for=gdk-pixbuf,pango
-Dintrospection=enabled
-Ddocumentation=true
-Dgtk_doc=true
-Dgdk-pixbuf:gtk_doc=true
-Dpango:gtk_doc=true
-Dbuild-demos=false
-Ddemos=false
-Dbuild-examples=false
-Dbuild-tests=false
-Dbuild-testsuite=false

View File

@@ -32,7 +32,6 @@ RUN dnf -y install \
glib2-static \
glibc-devel \
glibc-headers \
glslc \
gnupg2 \
gobject-introspection-devel \
graphene-devel \

View File

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

View File

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

View File

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

45
AUTHORS
View File

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

209
NEWS
View File

@@ -1,213 +1,6 @@
Overview of Changes in 4.13.1, xx-xx-xxxx
Overview of Changes in 4.11.5, xx-xx-xxxx
=========================================
Overview of Changes in 4.13.0, 25-08-2023
=========================================
* GskPath, GskPathBuilder, GskPathMeasure:
Data types and APIs for path rendering. These APIs are still
considered experimental, and may change until 4.14. Please try
them out and give us feedback. Documentation can be found
here: https://docs.gtk.org/gsk4/paths.html
* GtkGridView:
- Fix a crash when scrolling
* GtkColumnView:
- Fix a refcounting issue in the new scroll_to api
* GtkTreeView
- Fix style classes for sort arrows
* GtkEntry:
- Improve tracking of user changes (for undo)
* GtkNotebook:
- Fix a critical when switching pages
* GtkColor/FontDialogButton:
- Make these widgets activatable
* GtkMenuButton:
- Fix problems with focus handling
- Fix problems with DND
- Make flags a settable property
* GtkShortcutsWindow:
- Add API to build shortcuts windows programmatically
* Printing
- Fix the cpdb backend build
* MacOS:
- Make file filters work again
* GSK:
- Fix issues with color matrix nodes
* Wayland:
- Fix a crash with compositors other than gnome-shell
* Deprecations:
- Remaining GtkTreeModel-related types
* Demos:
- Add a few path demos to gtk4-demo
* Tools:
- gtk4-path-tool provides a commandline interface for paths
* Translation updates:
Basque
Catalan
Finnish
Galician
Georgian
German
Greek
Indonesian
Kazakh
Persian
Polish
Romanian
Spanish
Swedish
Turkish
Ukrainian
Overview of Changes in 4.12.0, 05-08-2023
=========================================
* List widgets:
- Add scroll_to APIs
* GtkFileLauncher:
- Add an always-ask property
* GtkTextView:
- Make backspace behavior match GtkEntry
* gsk:
- Fix handling of luminance in mask nodes
* Text rendering:
- Automate the setting of gtk-hint-font-metrics from the
scale factor. This improves font rendering in flatpaks
* Wayland:
- Fix behavior of stylus buttons
- Support suspended window state
* Vulkan:
- Many improvements
* Tools:
- Add gtk4-rendernode-tool
* Debugging:
- Drop the GTK_DEBUG_TOUCHSCREEN flag
* Build:
- Some build options have been renamed:
gtk_doc -> documentation
update_screenshots -> screenshots
The old names still work
* Translation updates:
Georgian
Greek
Hebrew
Persian
Vietnamese
* Contributors:
Aleksandr Melman
Alexander Mikhaylenko
Alexander Shopov
Alexandre Franke
Alice Mikhaylenko
António Fernandes
Arjan Molenaar
Asier Sarasua Garmendia
Balázs Meskó
Balázs Úr
Barnabás Pőcze
Bart Jacobs
Benjamin Otte
Bilal Elmoussaoui
Boyuan Yang
Bruce Cowan
Calvin Walton
Cam Cook
Chris Mayo
Christian Hergert
Christopher Davis
Chun-wei Fan
Corey Berla
Danial Behzadi
Daniel Boles
Daniel Rusek
Efstathios Iosifidis
Ekaterine Papava
Emin Tufan Çetin
Emmanuele Bassi
Erik Schilling
Fabio Tomat
FeRD (Frank Dana)
Fina Wilke
FineFindus
Fran Dieguez
G.Willems
Georges Basile Stavracas Neto
Guillaume Bernard
Hugo Carvalho
Ivan Molodetskikh
Jason Francis
Jonas Ådahl
Jordan Petridis
Jordi Mas
José Expósito
José Roberto de Souza
Khalid Abu Shawarib
Kévin Commaille
Leônidas Araújo
Luca Bacci
Ludovico de Nittis
Lukáš Tyrychtr
Marc-André Lureau
Marco Trevisan (Treviño)
Matt Turner
Matthias Clasen
Maximiliano Sandoval R
Michael Catanzaro
Michel Dänzer
Mohammed Sadiq
Nathan Follens
Nelson Benítez León
Ngọc Quân Trần
Niels De Graef
Olivier Crête
Patrick Griffis
Piotr Drąg
Sabri Ünal
Sebastian Keller
Sophie Herold
Sébastien Le Roux
Takao Fujiwara
Thomas Lange
Yiğit Burak
Yosef Or Boczko
Yuri Chornoivan
Zander Brown
al_SeveR
dgsasha
sumibi-yakitori
tszymanski
velsinki
Алексей Шилин
Арсений Засыпкин
Overview of Changes in 4.11.4, 03-07-2023
=========================================

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -335,10 +335,6 @@
<file>paintable_symbolic.c</file>
<file>panes.c</file>
<file>password_entry.c</file>
<file>path_fill.c</file>
<file>path_spinner.c</file>
<file>path_walk.c</file>
<file>path_text.c</file>
<file>peg_solitaire.c</file>
<file>pickers.c</file>
<file>printing.c</file>
@@ -424,13 +420,6 @@
<gresource prefix="/fontrendering">
<file>fontrendering.ui</file>
</gresource>
<gresource prefix="/path_walk">
<file>path_walk.ui</file>
<file compressed="true">path_world.txt</file>
</gresource>
<gresource prefix="/path_text">
<file>path_text.ui</file>
</gresource>
<gresource prefix="/org/gtk/Demo4">
<file>icons/16x16/actions/application-exit.png</file>
<file>icons/16x16/actions/document-new.png</file>

View File

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

View File

@@ -760,7 +760,9 @@ do_dnd (GtkWidget *do_widget)
GtkCssProvider *provider;
GString *css;
button = gtk_color_dialog_button_new (gtk_color_dialog_new ());
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
button = gtk_color_button_new ();
G_GNUC_END_IGNORE_DEPRECATIONS
g_object_unref (g_object_ref_sink (button));
provider = gtk_css_provider_new ();

View File

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

View File

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

View File

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

View File

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

View File

@@ -72,10 +72,6 @@ demos = files([
'paintable_symbolic.c',
'panes.c',
'password_entry.c',
'path_fill.c',
'path_spinner.c',
'path_walk.c',
'path_text.c',
'peg_solitaire.c',
'pickers.c',
'printing.c',
@@ -154,6 +150,8 @@ if librsvg_dep.found()
gtkdemo_deps += [ librsvg_dep ]
endif
gtkdemo_args = [ '-DGDK_DISABLE_DEPRECATED', '-DGTK_DISABLE_DEPRECATED', ]
demos_h = custom_target('gtk4 demo header',
output: 'demos.h',
input: demos,
@@ -208,7 +206,6 @@ if can_use_objcopy_for_resources
output : 'gtkdemo_resources2.o',
command : [objcopy,
'--strip-all',
'--set-section-alignment', '.data=8',
'--add-symbol','_g_binary_gtkdemo_resource_data=.data:0',
'@INPUT@',
'@OUTPUT@'])
@@ -237,7 +234,7 @@ gtkdemo_deps += [ demo_conf_h ]
executable('gtk4-demo',
sources: [demos, demos_h, extra_demo_sources, gtkdemo_resources],
c_args: demo_cflags,
c_args: gtkdemo_args + demo_cflags,
dependencies: gtkdemo_deps,
include_directories: confinc,
win_subsystem: 'windows',
@@ -247,7 +244,7 @@ executable('gtk4-demo',
executable('gtk4-demo-application',
sources: ['application.c', gtkdemo_resources],
c_args: common_cflags,
c_args: gtkdemo_args + common_cflags,
dependencies: gtkdemo_deps,
include_directories: confinc,
win_subsystem: 'windows',

View File

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

View File

@@ -1,198 +0,0 @@
/* Path/Fill and Stroke
*
* This demo shows how to use GskPath to draw shapes that are (a bit)
* more complex than a rounded rectangle.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "paintable.h"
#define GTK_TYPE_LOGO_PAINTABLE (gtk_logo_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GtkLogoPaintable, gtk_logo_paintable, GTK, LOGO_PAINTABLE, GObject)
struct _GtkLogoPaintable
{
GObject parent_instance;
int width;
int height;
GskPath *path[3];
GdkRGBA color[3];
GskPath *stroke_path;
GskStroke *stroke1;
GskStroke *stroke2;
GdkRGBA stroke_color;
};
struct _GtkLogoPaintableClass
{
GObjectClass parent_class;
};
static int
gtk_logo_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (paintable);
return self->width;
}
static int
gtk_logo_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (paintable);
return self->height;
}
static void
gtk_logo_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (paintable);
for (unsigned int i = 0; i < 3; i++)
{
gtk_snapshot_push_fill (snapshot, self->path[i], GSK_FILL_RULE_WINDING);
gtk_snapshot_append_color (snapshot,
&self->color[i],
&GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
}
for (unsigned int i = 0; i < 3; i++)
{
gtk_snapshot_push_stroke (snapshot, self->stroke_path, self->stroke1);
gtk_snapshot_append_color (snapshot,
&self->stroke_color,
&GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
}
gtk_snapshot_push_stroke (snapshot, self->stroke_path, self->stroke2);
gtk_snapshot_append_color (snapshot,
&self->stroke_color,
&GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
}
static GdkPaintableFlags
gtk_logo_paintable_get_flags (GdkPaintable *paintable)
{
return GDK_PAINTABLE_STATIC_CONTENTS | GDK_PAINTABLE_STATIC_SIZE;
}
static void
gtk_logo_paintable_paintable_init (GdkPaintableInterface *iface)
{
iface->get_intrinsic_width = gtk_logo_paintable_get_intrinsic_width;
iface->get_intrinsic_height = gtk_logo_paintable_get_intrinsic_height;
iface->snapshot = gtk_logo_paintable_snapshot;
iface->get_flags = gtk_logo_paintable_get_flags;
}
/* When defining the GType, we need to implement the GdkPaintable interface */
G_DEFINE_TYPE_WITH_CODE (GtkLogoPaintable, gtk_logo_paintable, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_logo_paintable_paintable_init))
static void
gtk_logo_paintable_dispose (GObject *object)
{
GtkLogoPaintable *self = GTK_LOGO_PAINTABLE (object);
for (unsigned int i = 0; i < 3; i++)
gsk_path_unref (self->path[i]);
gsk_path_unref (self->stroke_path);
gsk_stroke_free (self->stroke1);
gsk_stroke_free (self->stroke2);
G_OBJECT_CLASS (gtk_logo_paintable_parent_class)->dispose (object);
}
static void
gtk_logo_paintable_class_init (GtkLogoPaintableClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_logo_paintable_dispose;
}
static void
gtk_logo_paintable_init (GtkLogoPaintable *self)
{
}
static GdkPaintable *
gtk_logo_paintable_new (void)
{
GtkLogoPaintable *self;
graphene_rect_t bounds, bounds2;
self = g_object_new (GTK_TYPE_LOGO_PAINTABLE, NULL);
/* Paths and colors extracted from gtk-logo.svg */
self->path[0] = gsk_path_parse ("m3.12,66.17 -2.06,-51.46 32.93,24.7 v55.58 l-30.87,-28.82 z");
self->path[1] = gsk_path_parse ("m34,95 49.4,-20.58 4.12,-51.46 -53.52,16.47 v55.58 z");
self->path[2] = gsk_path_parse ("m1.06,14.71 32.93,24.7 53.52,-16.47 -36.75,-21.88 -49.7,13.65 z");
gdk_rgba_parse (&self->color[0], "#e40000");
gdk_rgba_parse (&self->color[1], "#7fe719");
gdk_rgba_parse (&self->color[2], "#729fcf");
self->stroke_path = gsk_path_parse ("m50.6,51.3 -47.3,14 z l33,23 z v-50");
self->stroke1 = gsk_stroke_new (2.12);
self->stroke2 = gsk_stroke_new (1.25);
gdk_rgba_parse (&self->stroke_color, "#ffffff");
gsk_path_get_stroke_bounds (self->path[0], self->stroke1, &bounds);
gsk_path_get_stroke_bounds (self->path[1], self->stroke1, &bounds2);
graphene_rect_union (&bounds, &bounds2, &bounds);
gsk_path_get_stroke_bounds (self->path[2], self->stroke1, &bounds2);
graphene_rect_union (&bounds, &bounds2, &bounds);
gsk_path_get_stroke_bounds (self->stroke_path, self->stroke2, &bounds2);
graphene_rect_union (&bounds, &bounds2, &bounds);
self->width = bounds.origin.x + bounds.size.width;
self->height = bounds.origin.y + bounds.size.height;
return GDK_PAINTABLE (self);
}
GtkWidget *
do_path_fill (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *picture;
GdkPaintable *paintable;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Fill and Stroke");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
paintable = gtk_logo_paintable_new ();
picture = gtk_picture_new_for_paintable (paintable);
gtk_picture_set_content_fit (GTK_PICTURE (picture), GTK_CONTENT_FIT_CONTAIN);
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
g_object_unref (paintable);
gtk_window_set_child (GTK_WINDOW (window), picture);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

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

View File

@@ -1,586 +0,0 @@
/* Path/Text
*
* This demo shows how to use GskPath to transform a path along another path.
*
* It also demonstrates that paths can be filled with more interesting
* content than just plain colors.
*/
#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;
GskPath *line_path;
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,
graphene_point_t *out_offset)
{
PangoLayout *layout;
PangoFontDescription *desc;
GskPathBuilder *builder;
GskPath *result;
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);
builder = gsk_path_builder_new ();
gsk_path_builder_add_layout (builder, layout);
result = gsk_path_builder_free_to_path (builder);
if (out_offset)
graphene_point_init (out_offset, 0, - pango_layout_get_baseline (layout) / (double) PANGO_SCALE);
g_object_unref (layout);
return result;
}
typedef struct
{
GskPathMeasure *measure;
GskPathBuilder *builder;
graphene_point_t offset;
double scale;
} GtkPathTransform;
static void
gtk_path_transform_point (GskPathMeasure *measure,
const graphene_point_t *pt,
const graphene_point_t *offset,
float scale,
graphene_point_t *res)
{
graphene_vec2_t tangent;
GskPathPoint point;
if (gsk_path_measure_get_point (measure, (pt->x + offset->x) * scale, &point))
{
GskPath *path = gsk_path_measure_get_path (measure);
gsk_path_point_get_position (&point, path, res);
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_END, &tangent);
res->x -= (pt->y + offset->y) * scale * graphene_vec2_get_y (&tangent);
res->y += (pt->y + offset->y) * scale * graphene_vec2_get_x (&tangent);
}
}
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->offset, 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->offset, transform->scale, &res);
gsk_path_builder_line_to (transform->builder, res.x, res.y);
}
break;
case GSK_PATH_QUAD:
{
graphene_point_t res[2];
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[2], &transform->offset, transform->scale, &res[1]);
gsk_path_builder_quad_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y);
}
break;
case GSK_PATH_CUBIC:
{
graphene_point_t res[3];
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[2], &transform->offset, transform->scale, &res[1]);
gtk_path_transform_point (transform->measure, &pts[3], &transform->offset, transform->scale, &res[2]);
gsk_path_builder_cubic_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->offset, transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[3], &transform->offset, transform->scale, &res[1]);
gsk_path_builder_conic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, weight);
}
break;
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 (GskPath *line_path,
GskPath *path,
const graphene_point_t *offset)
{
GskPathMeasure *measure = gsk_path_measure_new (line_path);
GtkPathTransform transform = { measure, gsk_path_builder_new (), *offset };
graphene_rect_t bounds;
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, -1, gtk_path_transform_op, &transform);
gsk_path_measure_unref (measure);
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);
}
static void
gtk_path_widget_create_text_path (GtkPathWidget *self)
{
GskPath *path;
graphene_point_t offset;
gtk_path_widget_clear_text_path (self);
path = create_path_from_text (GTK_WIDGET (self), self->text, &offset);
self->text_path = gtk_path_transform (self->line_path, path, &offset);
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_cubic_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);
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.6 }, &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)
{
GskPathBuilder *builder;
/* 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);
/* 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)
{
GskPathPoint point;
graphene_point_t pos;
if (gsk_path_get_closest_point (self->line_path,
&GRAPHENE_POINT_INIT (x, y),
INFINITY,
&point))
{
gsk_path_point_get_position (&point, self->line_path, &pos);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
}
static void
pointer_leave (GtkEventControllerMotion *controller,
GtkPathWidget *self)
{
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->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_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,38 +0,0 @@
<?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>

View File

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

View File

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

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -153,6 +153,35 @@ get_busy (GSimpleAction *action,
gtk_widget_set_sensitive (window, FALSE);
}
static void
search_button_tooltip_show (GtkWidget *self,
GtkTooltip *tooltip)
{
static int style = 0;
if (style == 0)
{
gtk_tooltip_set_css_class (tooltip, "red-tooltip");
style++;
}
else if (style == 1)
{
gtk_tooltip_set_css_class (tooltip, "yellow-tooltip");
style++;
}
else
{
style = 0;
}
}
static void
search_button_tooltip_hide (GtkWidget *self,
GtkTooltip *tooltip)
{
gtk_tooltip_set_css_class (tooltip, NULL);
}
static int current_page = 0;
static gboolean
on_page (int i)
@@ -2221,6 +2250,8 @@ activate (GApplication *app)
gtk_builder_cscope_add_callback (scope, level_scale_value_changed);
gtk_builder_cscope_add_callback (scope, transition_speed_changed);
gtk_builder_cscope_add_callback (scope, reset_icon_size);
gtk_builder_cscope_add_callback (scope, search_button_tooltip_show);
gtk_builder_cscope_add_callback (scope, search_button_tooltip_hide);
gtk_builder_set_scope (builder, scope);
g_object_unref (scope);
if (!gtk_builder_add_from_resource (builder, "/org/gtk/WidgetFactory4/widget-factory.ui", &error))

View File

@@ -6,3 +6,12 @@
.toolbar {
-gtk-icon-style: symbolic;
}
.red-tooltip {
background-color: red;
}
.yellow-tooltip {
background-color: yellow;
color: black;
}

View File

@@ -257,7 +257,9 @@
</object>
<object class="GtkTextBuffer" id="textbuffer1">
<property name="tag-table">tags</property>
<property name="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<property name="text">Search button above will display its tooltip in an alternating red, yellow and default style.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nullam fringilla, est ut feugiat ultrices, elit lacus ultricies nibh, id commodo tortor nisi id elit.
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
Morbi vel elit erat. Maecenas dignissim, dui et pharetra rutrum, tellus lectus rutrum mi, a convallis libero nisi quis tellus.
@@ -1921,6 +1923,8 @@ microphone-sensitivity-medium-symbolic</property>
<property name="icon-name">edit-find</property>
<property name="action-name">win.search</property>
<property name="tooltip-text" translatable="1">Search for it</property>
<signal name="tooltip-show" handler="search_button_tooltip_show"/>
<signal name="tooltip-hide" handler="search_button_tooltip_hide"/>
</object>
</child>
<child>

View File

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

View File

@@ -1,7 +1,7 @@
expand_content_md_files = [
]
if get_option('documentation')
if get_option('gtk_doc')
gdk4_toml = configure_file(
input: 'gdk4.toml.in',
output: 'gdk4.toml',

View File

@@ -32,34 +32,7 @@ show_class_hierarchy = true
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
[extra]
content_files = [
"paths.md",
]
content_images = [
"gtk-logo.svg",
"images/arc-dark.png",
"images/arc-light.png",
"images/caps-dark.png",
"images/caps-light.png",
"images/conic-light.png",
"images/conic-dark.png",
"images/cubic-dark.png",
"images/cubic-light.png",
"images/curvature-dark.png",
"images/curvature-light.png",
"images/directions-dark.png",
"images/directions-light.png",
"images/fill-even-odd.png",
"images/fill-winding.png",
"images/join-dark.png",
"images/join-light.png",
"images/line-dark.png",
"images/line-light.png",
"images/path-dark.png",
"images/path-light.png",
"images/quad-dark.png",
"images/quad-light.png",
"images/stroke-miter.png",
"images/stroke-round.png",
]
urlmap_file = "urlmap.js"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -1,92 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="arcto.svg"
inkscape:export-filename="cubic-light.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.75989759"
inkscape:cx="399.39592"
inkscape:cy="466.51023"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
d="M 58.033485,123.96862 C 75.231194,113.95411 92.489919,103.26728 107.81401,113.89786"
id="path3"
sodipodi:nodetypes="cc" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:0.20061772;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2"
cx="-16.837238"
cy="154.55043"
rx="35.832706"
ry="17.920988"
transform="matrix(0.86643544,-0.49928912,0.59215321,0.8058254,0,0)" />
<path
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
d="M 57.432798,124.38759 86.59638,102.1496 107.25717,113.71009"
id="path1"
sodipodi:nodetypes="ccc" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-9"
cx="86.580566"
cy="102.81618"
r="1.5" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 45.061871,134.70541 12.60825,-10.20893"
id="path4-4"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:1, 3;stroke-dashoffset:0;stroke-opacity:1"
d="m 35.405008,142.35717 8.95641,-7.26298"
id="path4-8-8"
sodipodi:nodetypes="cc" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-61-1"
cx="57.597607"
cy="124.23325"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-6-5"
cx="108.01463"
cy="114.17829"
r="1.5" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,81 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="caps.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="2.1493149"
inkscape:cx="438.74445"
inkscape:cy="288.69664"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1">
<linearGradient
id="swatch1"
inkscape:swatch="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop1" />
</linearGradient>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#000064;stroke-width:1;stroke-miterlimit:0;stroke-dasharray:none"
d="m 73.096455,77.084329 c 0,0 6.439436,18.711677 18.172676,26.635721"
id="path1"
sodipodi:nodetypes="cc" />
<path
style="color:#000000;fill:none;stroke:#000064;stroke-width:0.2;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 94.214979,99.722163 c -4.705477,-3.177832 -9.013472,-9.233699 -11.888672,-14.531169 -2.8752,-5.29748 -4.353516,-9.587833 -4.353516,-9.587833 L 68.51576,78.85704 c 0,0 1.743663,5.064163 5.021484,11.103457 3.277822,6.039297 8.05428,13.302573 15.082031,18.048773"
id="path1-1"
sodipodi:nodetypes="csccsc" />
<path
style="fill:none;stroke:#000064;stroke-width:1;stroke-miterlimit:0;stroke-dasharray:none"
d="m 112.14213,75.736452 c 0,0 6.43944,18.711675 18.17268,26.635728"
id="path1-4"
sodipodi:nodetypes="cc" />
<path
style="color:#000000;fill:none;stroke:#000064;stroke-width:0.2;stroke-linecap:round;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1"
d="m 132.83284,98.590758 c -4.70551,-3.177807 -9.01347,-9.233742 -11.88867,-14.53125 -2.8752,-5.297508 -4.35351,-9.587891 -4.35351,-9.587891 -0.89828,-2.611719 -3.74396,-4.000453 -6.35547,-3.101562 -2.61172,0.898277 -4.00046,3.743958 -3.10157,6.355468 0,0 1.74367,5.064185 5.02149,11.103516 3.27782,6.039331 8.05428,13.302641 15.08203,18.048851"
id="path1-4-5"
sodipodi:nodetypes="cscccsc" />
<path
style="fill:none;stroke:#000064;stroke-width:1;stroke-miterlimit:0;stroke-dasharray:none"
d="m 154.10911,73.84561 c 0,0 6.43943,18.711677 18.17267,26.63572"
id="path1-0"
sodipodi:nodetypes="cc" />
<path
style="color:#000000;fill:none;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="M 175.16683,96.47344 C 170.46135,93.295592 166.1514,87.239699 163.2762,81.94219 160.401,76.644682 158.92269,72.3543 158.92269,72.3543 l -1.62696,-4.728516 -9.45508,3.253906 1.62696,4.728516 c 0,0 1.74171,5.066138 5.01953,11.105469 3.27782,6.039331 8.05428,13.300675 15.08203,18.046895"
id="path1-4-1"
sodipodi:nodetypes="csccccsc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,93 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="conic.svg"
inkscape:export-filename="path-dark.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.5197952"
inkscape:cx="397.75096"
inkscape:cy="525.39974"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#8b8b8b;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 66.52304,196.79607 c 27.88945,-10.42358 28.400227,-11.25919 57.24918,-4.59693"
id="path5-7-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#848484;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 66.150275,196.9925 c 28.059619,-18.89157 28.355331,-21.42218 57.249175,-4.59693"
id="path5"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 65.439496,197.17632 30.328009,-21.33704 28.506125,16.61621"
id="path6" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 66.25585,197.17683 c 29.459015,-15.97487 29.941733,-16.52508 57.24918,-4.59693"
id="path5-7"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 52.936092,207.66575 12.60825,-10.20893"
id="path4"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:1, 3;stroke-dashoffset:0;stroke-opacity:1"
d="m 43.279229,215.31751 8.95641,-7.26298"
id="path4-8"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7"
cx="95.69075"
cy="175.70657"
r="1.5" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-61"
cx="65.471832"
cy="197.19359"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-6"
cx="123.73506"
cy="192.49165"
r="1.5" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

View File

@@ -1,90 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="cubic.svg"
inkscape:export-filename="path-dark.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.75989759"
inkscape:cx="398.73794"
inkscape:cy="466.51023"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 65.680232,196.81045 31.85267,-27.20583 3.379138,46.6055 23.3915,-31.31401"
id="path6"
sodipodi:nodetypes="cccc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 52.936092,207.66575 12.60825,-10.20893"
id="path4"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:1, 3;stroke-dashoffset:0;stroke-opacity:1"
d="m 43.279229,215.31751 8.95641,-7.26298"
id="path4-8"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 65.857856,197.15027 c 31.390863,-27.80022 35.053874,18.93262 59.490604,-13.30694"
id="path5"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7"
cx="97.246689"
cy="169.65689"
r="1.5" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-61"
cx="65.471832"
cy="197.19359"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-6"
cx="101.05927"
cy="215.75879"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-6-3"
cx="124.97194"
cy="184.30319"
r="1.5" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

View File

@@ -1,65 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="curvature.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.0746575"
inkscape:cx="396.87064"
inkscape:cy="561.57428"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
d="m 61.499887,117.85302 0.05055,-14.89554"
id="path3"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
d="m 47.704374,176.11887 c 0,0 -17.048386,-67.06278 9.674156,-72.76426 29.478854,-6.289566 30.433539,55.72526 58.46942,50.81836"
id="path1"
sodipodi:nodetypes="csc" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2"
cy="117.87344"
cx="61.445835"
rx="14.692688"
ry="14.525347" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2-8-9"
cx="61.42588"
cy="117.79034"
r="1.5" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -1,328 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="directions.svg"
inkscape:export-filename="directions-light.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.0746575"
inkscape:cx="371.28108"
inkscape:cy="266.59657"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false" />
<defs
id="defs1">
<marker
style="overflow:visible"
id="marker5"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="0.5"
markerHeight="0.5"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path5" />
</marker>
<marker
style="overflow:visible"
id="marker3"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="2"
markerHeight="2"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path3" />
</marker>
<marker
style="overflow:visible"
id="Triangle"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="2"
markerHeight="2"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path135" />
</marker>
<marker
style="overflow:visible"
id="marker3-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="2"
markerHeight="2"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path3-5" />
</marker>
<marker
style="overflow:visible"
id="Triangle-0"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="2"
markerHeight="2"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path135-9" />
</marker>
<marker
style="overflow:visible"
id="marker5-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="0.5"
markerHeight="0.5"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path5-8" />
</marker>
<marker
style="overflow:visible"
id="marker3-8-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="2"
markerHeight="2"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path3-5-4" />
</marker>
<marker
style="overflow:visible"
id="Triangle-0-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="2"
markerHeight="2"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path135-9-6" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;marker-end:url(#marker5)"
d="m 27.834229,78.180655 c 21.653076,9.584156 38.648414,3.28592 57.704513,-16.91815 26.702288,3.84691 38.178308,6.290079 51.837088,35.267113"
id="path1"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;marker-end:url(#marker5-9)"
d="m 91.839025,170.91959 c -22.098283,1.18425 -24.17615,-37.34309 2.699778,-37.47998 20.898567,-0.10644 38.726427,9.19795 51.837087,35.26711"
id="path1-8"
sodipodi:nodetypes="csc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;marker-start:url(#marker3);marker-end:url(#Triangle)"
d="M 52.087008,92.522138 119.92974,29.398044"
id="path2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;marker-start:url(#marker3-8);marker-end:url(#Triangle-0)"
d="M 39.037646,53.839137 130.44855,69.048774"
id="path2-3"
sodipodi:nodetypes="cc"
inkscape:transform-center-x="-71.02355"
inkscape:transform-center-y="28.680447" />
<path
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;marker-start:url(#marker3-8-4);marker-end:url(#Triangle-0-7)"
d="M 48.764932,133.73955 141.43055,133.1318"
id="path2-3-1"
sodipodi:nodetypes="cc"
inkscape:transform-center-x="-74.875204"
inkscape:transform-center-y="16.143612" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88055556px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="99.90786"
y="24.737305"
id="text4"><tspan
sodipodi:role="line"
id="tspan4"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88055556px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke-width:0.2"
x="99.90786"
y="24.737305">GSK_PATH_FROM_START</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="142.84389"
y="128.82414"
id="text4-5"><tspan
sodipodi:role="line"
id="tspan4-7"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke-width:0.2"
x="142.84389"
y="128.82414">GSK_PATH_FROM_START</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88055556px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="29.309605"
y="100.65614"
id="text5"><tspan
sodipodi:role="line"
id="tspan5"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88055556px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.2"
x="29.309605"
y="100.65614">GSK_PATH_TO_START</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="14.843884"
y="141.82414"
id="text5-8"><tspan
sodipodi:role="line"
id="tspan5-8"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.2"
x="14.843884"
y="141.82414">GSK_PATH_TO_START</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="135.70834"
y="70.811882"
id="text6"><tspan
sodipodi:role="line"
id="tspan6"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.2"
x="135.70834"
y="70.811882">GSK_PATH_TO_END</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="142.84389"
y="141.82416"
id="text6-6"><tspan
sodipodi:role="line"
id="tspan6-2"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.2"
x="142.84389"
y="141.82416">GSK_PATH_TO_END</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="14.843884"
y="48.774254"
id="text7"><tspan
sodipodi:role="line"
id="tspan7"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.2"
x="14.843884"
y="48.774254">GSK_PATH_FROM_END</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="14.843884"
y="128.82414"
id="text7-5"><tspan
sodipodi:role="line"
id="tspan7-9"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.2"
x="14.843884"
y="128.82414">GSK_PATH_FROM_END</tspan></text>
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2-8-9-7"
cx="85.343727"
cy="61.691891"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2-8-9-7-0"
cx="93.787331"
cy="133.30902"
r="1.5" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1,72 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="join.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.75989759"
inkscape:cx="118.43701"
inkscape:cy="570.47161"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#000064;stroke-width:1;stroke-linecap:square;stroke-miterlimit:10;stroke-dasharray:none"
d="m 12.748727,122.15935 c 4.449842,-15.44496 4.175632,-15.92044 16.908788,-26.568585 0,0 8.478091,16.421195 35.150804,33.660325"
id="path1"
sodipodi:nodetypes="ccc" />
<path
style="color:#000000;fill:none;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 17.59375,123.72266 c 3.810222,-13.2249 3.591775,-14.13123 11.107422,-20.53516 1.289688,1.82186 2.604788,3.71164 4.800781,6.23242 5.743296,6.59272 14.891452,15.32766 28.632813,24.20899 M 67.5625,125.23047 C 54.631174,116.87268 46.204933,108.77726 41.041016,102.84961 35.877098,96.921954 34.140625,93.474609 34.140625,93.474609 l -2.861328,-5.544922 -4.789063,4.003907 C 13.673794,102.6514 12.411529,105.58692 7.984375,120.95313"
id="path1-3"
sodipodi:nodetypes="ccsccscccc" />
<path
style="fill:none;stroke:#000064;stroke-width:1;stroke-linecap:square;stroke-miterlimit:10;stroke-dasharray:none"
d="m 147.99215,122.60257 c 4.44988,-15.44499 4.17566,-15.92048 16.90889,-26.568657 0,0 8.47814,16.421267 35.15101,33.660397"
id="path1-5"
sodipodi:nodetypes="ccc" />
<path
style="color:#000000;fill:none;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 152.79687,123.98633 c 3.81053,-13.22586 3.59005,-14.12993 11.10743,-20.53516 1.28968,1.82184 2.6029,3.71173 4.79882,6.23242 5.74333,6.59274 14.89333,15.32961 28.63477,24.21094 m 5.42773,-8.40039 c -12.9314,-8.35778 -21.35753,-16.45123 -26.52148,-22.37891 -5.16395,-5.927668 -6.90039,-9.374996 -6.90039,-9.374996 l -7.65039,-1.541015 C 148.87685,102.91706 147.61469,105.85252 143.1875,121.21875"
id="path1-5-8"
sodipodi:nodetypes="ccsccsccc" />
<path
style="fill:none;stroke:#000064;stroke-width:1;stroke-linecap:square;stroke-miterlimit:10;stroke-dasharray:none"
d="m 79.729342,122.0734 c 4.449844,-15.44499 4.175634,-15.92048 16.908794,-26.568654 0,0 8.478114,16.421264 35.150984,33.660394"
id="path1-7"
sodipodi:nodetypes="ccc" />
<path
style="color:#000000;fill:none;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 84.533203,123.19336 c 3.810222,-13.22495 3.591776,-14.1312 11.107422,-20.53516 1.289696,1.82187 2.604775,3.71164 4.800785,6.23243 5.74333,6.59275 14.89136,15.32765 28.63281,24.20898 m 5.42969,-8.39844 c -12.93141,-8.35778 -21.35949,-16.45122 -26.52344,-22.3789 -5.16395,-5.927686 -6.90039,-9.375004 -6.90039,-9.375004 -0.69636,-1.348401 -1.967393,-2.307601 -3.45508,-2.607422 -1.487509,-0.300132 -3.03083,0.09145 -4.195313,1.064453 C 80.61325,102.12215 79.350982,105.05756 74.923828,120.42383"
id="path1-7-4"
sodipodi:nodetypes="ccsccscccc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -1,73 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="line.svg"
inkscape:export-filename="line-light.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.75989759"
inkscape:cx="398.73794"
inkscape:cy="466.51023"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 52.936092,207.66575 12.60825,-10.20893"
id="path4"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:1, 3;stroke-dashoffset:0;stroke-opacity:1"
d="m 43.279229,215.31751 8.95641,-7.26298"
id="path4-8"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 66.150275,196.9925 40.275255,-5.24977"
id="path5"
sodipodi:nodetypes="cc" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-61"
cx="65.471832"
cy="197.19359"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-6"
cx="106.42249"
cy="191.8156"
r="1.5" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -1,108 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="path.svg"
inkscape:export-filename="path-dark.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.75989759"
inkscape:cx="397.42198"
inkscape:cy="561.25984"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="M 128.28233,149.47912 154.23127,90.244656 86.340809,68.820468"
id="path3" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;fill-opacity:1;stroke-dasharray:none;stroke-opacity:1"
d="m 33.956804,113.31099 c -9.049189,-11.90893 5.40551,-40.570358 20.351208,-39.990271 26.687501,1.035822 4.06495,71.984581 30.695656,74.009711 19.642072,1.49368 41.962402,-34.42048 30.634382,-50.536241 C 99.663884,74.068616 50.763019,135.42833 33.956804,113.31099 Z"
id="path1"
sodipodi:nodetypes="sssss" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2"
cx="34.517788"
cy="113.66589"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8"
cx="55.045853"
cy="73.566689"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-5"
cx="55.045834"
cy="73.831245"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2-8-9"
cx="55.045834"
cy="73.831245"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2-8-9-7"
cx="86.398613"
cy="68.897667"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2-8-9-7-8"
cx="153.87553"
cy="90.112595"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7"
cx="84.803238"
cy="147.51736"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2-8-7-2"
cx="115.28235"
cy="96.705284"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2-8-9-7-9"
cx="127.92362"
cy="150.03427"
r="1.5" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

View File

@@ -1,83 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="path.svg"
inkscape:export-filename="path-dark.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.75989759"
inkscape:cx="398.07996"
inkscape:cy="466.51023"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 52.936092,207.66575 12.60825,-10.20893"
id="path4"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:1, 3;stroke-dashoffset:0;stroke-opacity:1"
d="m 43.279229,215.31751 8.95641,-7.26298"
id="path4-8"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="M 66.150275,196.9925 C 86.276878,182.17569 104.9512,180.54783 123.39945,192.39557"
id="path5"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7"
cx="95.69075"
cy="175.70657"
r="1.5" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-61"
cx="65.471832"
cy="197.19359"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-6"
cx="123.73506"
cy="192.49165"
r="1.5" />
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 65.439496,197.17632 30.328009,-21.33704 28.506125,16.61621"
id="path6" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -1,8 +1,4 @@
gsk_expand_content_md_files = [
'paths.md',
]
if get_option('documentation')
if get_option('gtk_doc')
gsk4_toml = configure_file(
input: 'gsk4.toml.in',
output: 'gsk4.toml',
@@ -25,7 +21,7 @@ if get_option('documentation')
'@INPUT1@',
],
depends: [ gdk_gir[0] ],
depend_files: [ gsk_expand_content_md_files ],
depend_files: [ expand_content_md_files ],
build_by_default: true,
install: true,
install_dir: docs_dir,

View File

@@ -1,174 +0,0 @@
Title: Paths
Slug: paths
GSK provides a path API that can be used to render more complex
shapes than lines or rounded rectangles. It is comparable to cairos
[path API](https://www.cairographics.org/manual/cairo-Paths.html),
with some notable differences.
In general, a path consists of one or more connected **_contours_**,
each of which may have multiple **_operations_**, and may or may not be closed.
Operations can be straight lines or curves of various kinds. At the points
where the operations connect, the path can have sharp turns.
<figure>
<picture>
<source srcset="path-dark.png" media="(prefers-color-scheme: dark)">
<img alt="A path with multiple contours" src="path-light.png">
</picture>
<figcaption>A path with one closed, and one open contour</figcaption>
</figure>
The central object of the GSK path API is the immutable [struct@Gsk.Path]
struct, which contains path data in compact form suitable for rendering.
## Creating Paths
Since `GskPath` is immutable, the auxiliary [struct@Gsk.PathBuilder] struct
can be used to construct a path piece by piece. The pieces are specified with
points, some of which will be on the path, while others are just **_control points_**
that are used to influence the shape of the resulting path.
<figure>
<picture>
<source srcset="cubic-dark.png" media="(prefers-color-scheme: dark)">
<img alt="An cubic Bézier" src="cubic-light.png">
</picture>
<figcaption>A cubic Bézier operation, with 2 control points</figcaption>
</figure>
The `GskPathBuilder` API has three distinct groups of functions:
- Functions for building contours from individual operations, like [method@Gsk.PathBuilder.move_to],
[method@Gsk.PathBuilder.line_to], [method@Gsk.PathBuilder.cubic_to], [method@Gsk.PathBuilder.close]. `GskPathBuilder` maintains a **_current point_**, so these methods all
take one less points than necessary for the operation (e.g. `gsk_path_builder_line_to`
only takes a single point and draws a line from the current point to the new point).
- Functions for adding complete contours, such as [method@Gsk.PathBuilder.add_rect],
[method@Gsk.PathBuilder.add_rounded_rect], [method@Gsk.PathBuilder.add_circle].
- Adding parts of a preexisting path. Functions in this group include
[method@Gsk.PathBuilder.add_path] and [method@Gsk.PathBuilder.add_segment].
When you are done with building a path, you can convert the accumulated path
data into a `GskPath` struct with [method@Gsk.PathBuilder.free_to_path].
A sometimes convenient alternative is to create a path from a serialized form,
with [func@Gsk.Path.parse]. This function interprets strings in SVG path syntax,
such as:
M 100 100 C 100 200 200 200 200 100 Z
## Rendering with Paths
There are two main ways to render with paths. The first is to **_fill_** the
interior of a path with a color or more complex content, such as a gradient.
GSK supports different ways of determining what part of the plane are interior
to the path, which can be selected with a [enum@Gsk.FillRule] value.
<figure>
<picture>
<img alt="A filled path" src="fill-winding.png">
</picture>
<figcaption>A path filled with GSK_FILL_RULE_WINDING</figcaption>
</figure>
<figure>
<picture>
<img alt="A filled path" src="fill-even-odd.png">
</picture>
<figcaption>The same path, filled with GSK_FILL_RULE_EVEN_ODD</figcaption>
</figure>
To fill a path, use [gtk_snapshot_append_fill()](../gtk4/method.Snapshot.append_fill.html)
or the more general [gtk_snapshot_push_fill()](../gtk4/method.Snapshot.push_fill.html).
Alternatively, a path can be **_stroked_**, which means to emulate drawing
with an idealized pen along the path. The result of stroking a path is another
path (the **_stroke path_**), which is then filled.
The stroke operation can be influenced with the [struct@Gsk.Stroke] struct
that collects various stroke parameters, such as the line width, the style
of line joins and line caps, and a dash pattern.
<figure>
<picture>
<img alt="A stroked path" src="stroke-miter.png">
</picture>
<figcaption>The same path, stroked with GSK_LINE_JOIN_MITER</figcaption>
</figure>
<figure>
<picture>
<img alt="A stroked path" src="stroke-round.png">
</picture>
<figcaption>The same path, stroked with GSK_LINE_JOIN_ROUND</figcaption>
</figure>
To stroke a path, use
[gtk_snapshot_append_stroke()](../gtk4/method.Snapshot.append_stroke.html)
or [gtk_snapshot_push_stroke()](../gtk4/method.Snapshot.push_stroke.html).
## Hit testing
When paths are rendered as part of an interactive interface, it is sometimes
necessary to determine whether the mouse points is over the path. GSK provides
[method@Gsk.Path.in_fill] for this purpose.
## Path length
An important property of paths is their **_length_**. Computing it efficiently
requires caching, therefore GSK provides a separate [struct@Gsk.PathMeasure] object
to deal with path lengths. After constructing a `GskPathMeasure` object for a path,
it can be used to determine the length of the path with [method@Gsk.PathMeasure.get_length]
and locate points at a given distance into the path with [method@Gsk.PathMeasure.get_point].
## Other Path APIs
Paths have uses beyond rendering, for example as trajectories in animations.
In such uses, it is often important to access properties of paths, such as
their tangents at certain points. GSK provides an abstract representation
for points on a path in the form of the [struct@Gsk.PathPoint] struct.
You can query properties of a path at certain point once you have a
`GskPathPoint` representing that point.
`GskPathPoint` structs can be compared for equality with [method@Gsk.PathPoint.equal]
and ordered wrt. to which one comes first, using [method@Gsk.PathPoint.compare].
To obtain a `GskPathPoint`, use [method@Gsk.Path.get_closest_point],
[method@Gsk.Path.get_start_point], [method@Gsk.Path.get_end_point] or
[method@Gsk.PathMeasure.get_point].
To query properties of the path at a point, use [method@Gsk.PathPoint.get_position],
[method@Gsk.PathPoint.get_tangent], [method@Gsk.PathPoint.get_rotation],
[method@Gsk.PathPoint.get_curvature] and [method@Gsk.PathPoint.get_distance].
Some of the properties can have different values for the path going into
the point and the path leaving the point, typically at points where the
path takes sharp turns. Examples for this are tangents (which can have up
to 4 different values) and curvatures (which can have two different values).
<figure>
<picture>
<source srcset="directions-dark.png" media="(prefers-color-scheme: dark)">
<img alt="Path Tangents" src="directions-light.png">
</picture>
<figcaption>Path Tangents</figcaption>
</figure>
## Going beyond GskPath
Lots of powerful functionality can be implemented for paths:
- Finding intersections
- Offsetting curves
- Turning stroke outlines into paths
- Molding curves (making them pass through a given point)
GSK does not provide API for all of these, but it does offer a way to get at
the underlying Bézier curves, so you can implement such functionality yourself.
You can use [method@Gsk.Path.foreach] to iterate over the operations of the
path, and get the points needed to reconstruct or modify the path piece by piece.
See e.g. the [Primer on Bézier curves](https://pomax.github.io/bezierinfo/)
for inspiration of useful things to explore.

View File

@@ -268,7 +268,7 @@ support in the file chooser.
This option controls whether GTK should use colord for color
calibration support in the cups print backend.
### `documentation`, `man-pages` and `screenshots`
### `gtk_doc`, `man-pages` and `update_screenshots`
The *gi-docgen* package is used to generate the reference documentation
included with GTK. By default support for *gi-docgen* is disabled

View File

@@ -89,11 +89,11 @@ using `gtk_application_new()`.
When creating a [class@Gtk.Application], you need to pick an application
identifier (a name) and pass it to [ctor@Gtk.Application.new] as parameter. For
this example `org.gtk.example` is used. For choosing an identifier for your
application, see [this guide](https://developer.gnome.org/documentation/tutorials/application-id.html).
application, see [this guide](https://wiki.gnome.org/HowDoI/ChooseApplicationID).
Lastly, [ctor@Gtk.Application.new] takes `GApplicationFlags` as input
for your application, if your application would have special needs.
Next the [activate signal](https://developer.gnome.org/documentation/tutorials/application.html) is
Next the [activate signal](https://wiki.gnome.org/HowDoI/GtkApplication) is
connected to the activate() function above the `main()` function. The `activate`
signal will be emitted when your application is launched with `g_application_run()`
on the line below. The `g_application_run()` call also takes as arguments the

View File

@@ -1,193 +0,0 @@
.. _gtk4-path-tool(1):
=================
gtk4-path-tool
=================
-----------------------
GskPath Utility
-----------------------
SYNOPSIS
--------
| **gtk4-path-tool** <COMMAND> [OPTIONS...] <PATH>
|
| **gtk4-path-tool** decompose [OPTIONS...] <PATH>
| **gtk4-path-tool** show [OPTIONS...] <PATH>
| **gtk4-path-tool** render [OPTIONS...] <PATH>
| **gtk4-path-tool** info [OPTIONS...] <PATH>
DESCRIPTION
-----------
``gtk4-path-tool`` can perform various tasks on paths. Paths are specified
in SVG syntax, as strings like "M 100 100 C 100 200 200 200 200 100 Z".
To read a path from a file, use a filename that starts with a '.' or a '/'.
To read a path from stdin, use '-'.
COMMANDS
--------
Decomposing
^^^^^^^^^^^
The ``decompose`` command approximates the path by one with simpler elements.
When used without options, the curves of the path are approximated by line
segments.
``--allow-quad``
Allow quadratic Bézier curves to be used in the generated path.
``--allow-cubic``
Allow cubic Bézier curves to be used in the generated path.
``--allow-conic``
Allow conic Bézier curves to be used in the generated path.
Showing
^^^^^^^
The ``show`` command displays the given path in a window. The interior
of the path is filled.
``--fill-rule=VALUE``
The fill rule that is used to determine what areas are inside the path.
The possible values are ``winding`` or ``even-odd``. The default is ``winding``.
``--fg-color=COLOR``
The color that is used to fill the interior of the path or stroke the path.
If not specified, black is used.
``--bg-color=COLOR``
The color that is used to render the background behind the path.
If not specified, white is used.
``--fill``
Fill the path (this is the default).
``--stroke``
Stroke the path instead of filling it.
``--line-width=VALUE``
The line width to use for the stroke. ``VALUE`` must be a positive number.
The default line width is 1.
``--line-cap=VALUE``
The cap style to use at line ends. The possible values are ``butt``, ``round``
or ``square``. See the SVG specification for details on these styles.
The default cap style is ``butt``.
``--line-join=VALUE``
The join style to use at line joins. The possible values are ``miter``,
``miter-clip``, ``round``, ``bevel`` or ``arcs``. See the SVG specification
for details on these styles.
The default join style is ``miter``.
``--miter-limit=VALUE``
The limit at which to clip miters at line joins. The default value is 4.
``--dashes=VALUE``
The dash pattern to use for this stroke. A dash pattern is specified by
a comma-separated list of alternating non-negative numbers. Each number
provides the length of alternate "on" and "off" portions of the stroke.
If the dash pattern is empty, dashing is disabled, which is the default.
See the SVG specification for details on dashing.
``--dash-offset=VALUE``
The offset into the dash pattern where dashing should begin.
The default value is 0.
Rendering
^^^^^^^^^
The ``render`` command renders the given path as a PNG image.
The interior of the path is filled.
``--fill-rule=VALUE``
The fill rule that is used to determine what areas are inside the path.
The possible values are ``winding`` or ``even-odd``. The default is ``winding``.
``--fg-color=COLOR``
The color that is used to fill the interior of the path or stroke the path.
If not specified, black is used.
``--bg-color=COLOR``
The color that is used to render the background behind the path.
If not specified, white is used.
``--output-file=FILE``
The file to save the PNG image to.
If not specified, "path.png" is used.
``--fill``
Fill the path (this is the default).
``--stroke``
Stroke the path instead of filling it.
``--line-width=VALUE``
The line width to use for the stroke. ``VALUE`` must be a positive number.
The default line width is 1.
``--line-cap=VALUE``
The cap style to use at line ends. The possible values are ``butt``, ``round``
or ``square``. See the SVG specification for details on these styles.
The default cap style is ``butt``.
``--line-join=VALUE``
The join style to use at line joins. The possible values are ``miter``,
``miter-clip``, ``round``, ``bevel`` or ``arcs``. See the SVG specification
for details on these styles.
The default join style is ``miter``.
``--miter-limit=VALUE``
The limit at which to clip miters at line joins. The default value is 4.
``--dashes=VALUE``
The dash pattern to use for this stroke. A dash pattern is specified by
a comma-separated list of alternating non-negative numbers. Each number
provides the length of alternate "on" and "off" portions of the stroke.
If the dash pattern is empty, dashing is disabled, which is the default.
See the SVG specification for details on dashing.
``--dash-offset=VALUE``
The offset into the dash pattern where dashing should begin.
The default value is 0.
Info
^^^^
The ``info`` command shows various information about the given path,
such as its bounding box.
REFERENCES
----------
- SVG Path Specification, https://www.w3.org/TR/SVG2/paths.html

View File

@@ -1,47 +0,0 @@
.. _gtk4-rendernode-tool(1):
====================
gtk4-rendernode-tool
====================
-----------------------
GskRenderNode Utility
-----------------------
SYNOPSIS
--------
| **gtk4-rendernode-tool** <COMMAND> [OPTIONS...] <FILE>
|
| **gtk4-rendernode-tool** info [OPTIONS...] <FILE>
| **gtk4-rendernode-tool** show [OPTIONS...] <FILE>
| **gtk4-rendernode-tool** render [OPTIONS...] <FILE> [<FILE>]
DESCRIPTION
-----------
``gtk4-rendernode-tool`` can perform various operations on serialized rendernodes.
COMMANDS
--------
Information
^^^^^^^^^^^
The ``info`` command shows general information about the rendernode, such
as the number of nodes, and the depth of the tree.
Showing
^^^^^^^
The ``show`` command displays the rendernode.
Rendering
^^^^^^^^^
The ``render`` command saves a rendering of the rendernode as a png or tiff image.
The name of the file to write can be specified as a second FILE argument.
``--renderer=RENDERER``
Use the given renderer. Use ``--renderer=help`` to get a information
about poassible values for the ``RENDERER``.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 147 B

View File

@@ -78,7 +78,7 @@ ui_files = [
gtk_builder_tool = find_program('gtk4-builder-tool')
if get_option('screenshots')
if get_option('update_screenshots')
foreach ui_file: ui_files
png_file = ui_file.replace('.ui', '.png')
gtk_images += custom_target('@0@ from @1@'.format(png_file, ui_file),

View File

@@ -32,7 +32,7 @@ gtk_images = []
subdir('images')
if get_option('documentation')
if get_option('gtk_doc')
gtk4_toml = configure_file(
input: 'gtk4.toml.in',
output: 'gtk4.toml',
@@ -75,9 +75,7 @@ if get_option('man-pages') and rst2man.found()
[ 'gtk4-encode-symbolic-svg', '1', ],
[ 'gtk4-launch', '1', ],
[ 'gtk4-query-settings', '1', ],
[ 'gtk4-rendernode-tool', '1' ],
[ 'gtk4-update-icon-cache', '1', ],
[ 'gtk4-path-tool', '1', ],
]
if get_option('demos')

View File

@@ -73,6 +73,9 @@ A number of keys are influencing behavior instead of just logging:
`no-css-cache`
: Bypass caching for CSS style properties
`touchscreen`
: Pretend the pointer is a touchscreen device
`snapshot`
: Include debug render nodes in the generated snapshots

View File

@@ -222,7 +222,7 @@ It is possible to set accessible attributes in UI files as well:
<accessibility>
<property name="label">Download</property>
<relation name="labelled-by">label1</relation>
</accessibility>
/accessibility>
</object>
```

View File

@@ -1,7 +1,7 @@
toml_conf = configuration_data()
toml_conf.set('version', meson.project_version())
gidocgen = find_program('gi-docgen', required: get_option('documentation'), native: true)
gidocgen = find_program('gi-docgen', required: get_option('gtk_doc'), native: true)
gidocgen_common_args = [
'--quiet',
@@ -14,7 +14,7 @@ endif
docs_dir = gtk_datadir / 'doc'
if get_option('documentation') and not build_gir
if get_option('gtk_doc') and not build_gir
error('API reference requires introspection.')
endif

View File

@@ -15,78 +15,18 @@ struct _ExampleAppPrefs
G_DEFINE_TYPE (ExampleAppPrefs, example_app_prefs, GTK_TYPE_DIALOG)
static gboolean
string_to_font_desc (GValue *value,
GVariant *variant,
gpointer user_data)
{
const char *s = g_variant_get_string (variant, NULL);
PangoFontDescription *desc;
desc = pango_font_description_from_string (s);
g_value_take_boxed (value, desc);
return TRUE;
}
static GVariant *
font_desc_to_string (const GValue *value,
const GVariantType *expected_type,
gpointer user_data)
{
PangoFontDescription *desc = g_value_get_boxed (value);
char *s = pango_font_description_to_string (desc);
return g_variant_new_take_string (s);
}
static gboolean
transition_to_pos (GValue *value,
GVariant *variant,
gpointer user_data)
{
const char *s = g_variant_get_string (variant, NULL);
if (strcmp (s, "none") == 0)
g_value_set_uint (value, 0);
else if (strcmp (s, "crossfade") == 0)
g_value_set_uint (value, 1);
else
g_value_set_uint (value, 2);
return TRUE;
}
static GVariant *
pos_to_transition (const GValue *value,
const GVariantType *expected_type,
gpointer user_data)
{
switch (g_value_get_uint (value))
{
case 0: return g_variant_new_string ("none");
case 1: return g_variant_new_string ("crossfade");
case 2: return g_variant_new_string ("slide-left-right");
default: g_assert_not_reached ();
}
}
static void
example_app_prefs_init (ExampleAppPrefs *prefs)
{
gtk_widget_init_template (GTK_WIDGET (prefs));
prefs->settings = g_settings_new ("org.gtk.exampleapp");
g_settings_bind_with_mapping (prefs->settings, "font",
prefs->font, "font-desc",
G_SETTINGS_BIND_DEFAULT,
string_to_font_desc,
font_desc_to_string,
NULL, NULL);
g_settings_bind_with_mapping (prefs->settings, "transition",
prefs->transition, "selected",
G_SETTINGS_BIND_DEFAULT,
transition_to_pos,
pos_to_transition,
NULL, NULL);
g_settings_bind (prefs->settings, "font",
prefs->font, "font",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (prefs->settings, "transition",
prefs->transition, "active-id",
G_SETTINGS_BIND_DEFAULT);
}
static void

View File

@@ -27,10 +27,7 @@
</object>
</child>
<child>
<object class="GtkFontDialogButton" id="font">
<property name="dialog">
<object class="GtkFontDialog"/>
</property>
<object class="GtkFontButton" id="font">
<layout>
<property name="column">1</property>
<property name="row">0</property>
@@ -50,16 +47,12 @@
</object>
</child>
<child>
<object class="GtkDropDown" id="transition">
<property name="model">
<object class="GtkStringList">
<items>
<item translatable="yes">None</item>
<item translatable="yes">Fade</item>
<item translatable="yes">Slide</item>
</items>
</object>
</property>
<object class="GtkComboBoxText" id="transition">
<items>
<item translatable="yes" id="none">None</item>
<item translatable="yes" id="crossfade">Fade</item>
<item translatable="yes" id="slide-left-right">Slide</item>
</items>
<layout>
<property name="column">1</property>
<property name="row">1</property>

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