Compare commits

...

392 Commits

Author SHA1 Message Date
Chun-wei Fan 24d25b0db5 build: Check HarfBuzz has GDI support built in on Windows
We are using APIs from there.  Also enable GDI and DirectWrite if we are
building HarfBuzz as a fallback, and remove an extraneous HarfBuzz dependency
declaration.
2022-07-08 17:14:04 +08:00
Chun-wei Fan 30147b1a99 gtkimcontextime.c: Port to Pango2 APIs
Update the code to use Pango2 APIs, by removing includes to pangowin32, which
is gone, and replacing relevant calls to Pango2 equivilants.

Replace the call to pango_win32_font_logfontw() by retrieving instead the
underlying hb_font_t, and calling hb_uniscribe_font_get_logfontw(), but preedit
fonts are currently not working until a resolution to HarfBuzz issue #3683 can
be found.  Since we are still using Windows IME APIs for input, we need the
HarfBuzz GDI/Uniscribe items to be included in the HarfBuzz builds.
2022-07-08 17:14:04 +08:00
Chun-wei Fan 3979def662 GSK Vulkan: WIP port to Pango2 2022-07-08 17:14:04 +08:00
Chun-wei Fan 71ea2e2ecb gdk/win32: WIP Port to Pango2 2022-07-08 17:13:54 +08:00
Chun-wei Fan c79b4e2e56 build: Don't try to use pangowin32 in deps
It's no longer there for Pango2.
2022-07-08 11:53:29 +08:00
Matthias Clasen f7c4b26c59 Make a standalone font explorer
This is the font features demo, broken out as
a standalone application and cleaned up.
2022-07-06 13:45:11 -04:00
Matthias Clasen a13cfde2a9 fixup clear_template 2022-07-05 20:43:53 -04:00
Emmanuele Bassi 3a5d161b8a Add gtk_widget_clear_template()
The dual of gtk_widget_init_template(), which should be used to clear
the template data associated with a specific GtkWidget type.
2022-07-05 20:43:53 -04:00
Matthias Clasen baabb57df3 font demo: Keep up with api churn 2022-07-05 14:22:04 -04:00
Matthias Clasen a69d39d945 fontchooser: Small fixes
Make initial property values match.
2022-07-05 14:22:04 -04:00
Matthias Clasen 646149bc72 Fontchooser: Add palette support
For fonts that have color palettes, optionally
allow the user to select one.

This is behind the new GTK_FONT_CHOOSER_LEVEL_PALETTE
flag. If it is enabled, you can use
gtk_font_chooser_get_palette() to get the
selected palette name.

The testfontchooserdialog test lets you play with
this. Fonts to try tihs with are Amiri Quran Colored
or the Bungee Color family.
2022-07-04 10:37:20 -04:00
Matthias Clasen b01eb0600c Font demo: Add color palettes 2022-07-04 10:36:52 -04:00
Matthias Clasen 5b92bf51a0 Font demo: Keep a single paragraph
This is currently required for line height to
take effect (we may want to make the leading-trim
changeable).
2022-07-04 10:36:52 -04:00
Matthias Clasen 8ab180b3a9 Port to pango2 api 2022-07-04 10:36:48 -04:00
Matthias Clasen 897195b2f5 Compare family names case-insensitively 2022-07-04 10:36:47 -04:00
Matthias Clasen d595cc1c55 Use modern C++
This is needed to build HarfBuzz as a subproject.
2022-07-04 10:36:47 -04:00
Matthias Clasen 2841256260 fontchooser: Make size level effective
We were not hiding the size controls on the tweaks
page, which is arguably what should happen when
the size level is disabled.
2022-07-04 10:36:47 -04:00
Matthias Clasen ff0fec0f7d Beef up testfontchooserdialog
Allow testing levels.
2022-07-04 10:36:47 -04:00
Matthias Clasen d0894b2786 fontchooser: Some OpenType improvements
Work harder to find examples for char variation
features, and pull the feature labels out of
the font if possible. This lets us show
meaningful names like "Localised @ and & symbols"
instead of "Stylistic Set 7" or even "ss07".
2022-07-03 07:38:24 -04:00
Matthias Clasen 5ba8fc8f10 Font features demo improvements
Use font-provided names for ssNN and cvNN features.

But good luck finding a font that has these!
2022-07-03 01:19:19 -04:00
Matthias Clasen 5d05daaed0 Font features demo improvements
Add buttons to cycle through samples.
2022-07-02 23:37:34 -04:00
Matthias Clasen 86dd72fad6 Fix up font features demo
The conversion to a textview was incomplete.
2022-07-02 22:46:27 -04:00
Мирослав Николић b0766a62ec Update Serbian translation
(cherry picked from commit 7c0cf9e0c9)
2022-07-03 02:18:58 +00:00
Emmanuele Bassi a664d06c2f Merge branch 'wip/exalm/actionbar' into 'main'
actionbar: Document GtkBuildable child types

See merge request GNOME/gtk!4848
2022-07-02 22:46:40 +00:00
Alexander Mikhaylenko d42c51e27d actionbar: Document GtkBuildable child types 2022-07-03 02:26:18 +04:00
Aleksandr Melman 63af01f7c9 Update Russian translation 2022-07-02 18:50:32 +00:00
Matthias Clasen 12f7929f44 Merge branch 'matthiasc/for-main' into 'main'
gtk4-demo: Add color to font features

See merge request GNOME/gtk!4847
2022-07-02 18:17:04 +00:00
Matthias Clasen 9c4490b7ad gtk4-demo: Add color to font features 2022-07-02 11:35:24 -04:00
Matthias Clasen f0d329cf5e Merge branch 'wip/chergert/fix-menutracker' into 'main'
menutrackeritem: protect against use-after-free

Closes #5009

See merge request GNOME/gtk!4832
2022-07-01 11:17:32 +00:00
Matthias Clasen 58d79e87ea Merge branch 'matthiasc/for-main' into 'main'
gtk4-demo: Cosmetics

See merge request GNOME/gtk!4846
2022-07-01 04:37:07 +00:00
Matthias Clasen cd40cd145f gtk4-demo: Cosmetics 2022-07-01 00:10:16 -04:00
Matthias Clasen 4f6b5b0fac Merge branch 'matthiasc/for-main' into 'main'
Matthiasc/for main

See merge request GNOME/gtk!4845
2022-07-01 04:08:03 +00:00
Matthias Clasen 88bbb933a1 gtk4-demo: Add a waterfall to font features 2022-06-30 23:52:37 -04:00
Matthias Clasen 4070e794d2 gtk4-demo: Fix font features animation 2022-06-30 21:11:49 -04:00
Matthias Clasen 3b6ec027d3 Merge branch 'matthiasc/for-main' into 'main'
demos: Use gtk_builder_cscope_add_callback

See merge request GNOME/gtk!4844
2022-07-01 01:03:04 +00:00
Matthias Clasen a284dc9f31 demos: Use gtk_builder_cscope_add_callback
This is C convenience API, lets use it for
our convenience.
2022-06-30 20:10:06 -04:00
Matthias Clasen 091daf4cff Merge branch 'matthiasc/for-main' into 'main'
Add gtk_builder_cscope_add_callback

See merge request GNOME/gtk!4843
2022-06-30 23:23:04 +00:00
Matthias Clasen 64f3ac6760 gtk3-demo: Add animation to font features 2022-06-30 19:02:02 -04:00
Matthias Clasen 508ceccb66 gtk4-demo: Polish the font features demo 2022-06-30 19:02:02 -04:00
Matthias Clasen d6dde63074 gtk4-demo: Restructure the font features demo 2022-06-30 19:02:02 -04:00
Matthias Clasen bdb1886fc9 gtk4-demo: Cosmetics
Rename the ui file to match the C source, to preserve sanity.
2022-06-30 19:02:02 -04:00
Matthias Clasen faa9ef2dc0 Add gtk_builder_cscope_add_callback
This is a convenience method for the common case
that symbols are used under their own name.
2022-06-30 19:02:02 -04:00
Matthias Clasen 21b9667f08 Merge branch 'matthiasc/for-main' into 'main'
gtk-demo: Beef up font features demo

See merge request GNOME/gtk!4841
2022-06-30 14:12:20 +00:00
Matthias Clasen e4781e393c gtk-demo: Beef up font features demo
Some work on making this demo better.
2022-06-30 09:42:32 -04:00
Matthias Clasen 7536513ef8 Merge branch 'wip/jimmac/selectable-labels' into 'main'
theme: selectable labels legibility

Closes #5017

See merge request GNOME/gtk!4840
2022-06-29 20:05:44 +00:00
Jakub Steiner 6776c21350 theme: selectable labels legibility
- don't set fg color for selections

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5017
2022-06-29 21:40:30 +02:00
Matthias Clasen 9f4ef77663 Merge branch 'matthiasc/for-main' into 'main'
gtk-demo: Cosmetics

See merge request GNOME/gtk!4839
2022-06-29 19:16:32 +00:00
Benjamin Otte a64bb67ef7 Merge branch 'testdatatable' into 'main'
tests: Add testdatatable

See merge request GNOME/gtk!4838
2022-06-29 13:00:53 +00:00
Ivan Molodetskikh 53f3b4b9d9 tests: Add testdatatable
Add a GtkColumnView scrolling performance test similar to the one used
previously in https://gitlab.gnome.org/GNOME/gtk/-/issues/3334.

The test creates a table with 20 columns and 10,000 rows and scrolls it
to a random position every frame, while measuring the frame times.

There is a commandline flag to pick the cell widget between none (for
benchmarking raw column view scrolling) and various label types. There
is also a commandline switch to disable automatic scrolling in case a
manual assessment is desired. Finally, there's an argument for
controlling the number of columns.
2022-06-28 21:52:49 -07:00
Emmanuele Bassi 5bb4d69720 Merge branch 'ebassi/ci-publish-doc-fix' into 'main'
ci: Force the fedora image for the publish-docs job

See merge request GNOME/gtk!4837
2022-06-28 21:02:46 +00:00
Emmanuele Bassi 35808a918d ci: Force the fedora image for the publish-docs job
Otherwise every CI runner might decide to use a different default
image, and we'll end up on one that doesn't have curl.
2022-06-28 21:32:08 +01:00
Benjamin Otte 672618e560 Merge branch 'wip/otte/for-main' into 'main'
Rework listitemfactory

See merge request GNOME/gtk!4835
2022-06-28 19:30:17 +00:00
Emmanuele Bassi e28516d189 Merge branch 'template-signals' into 'main'
Force quark creation for templates

See merge request GNOME/gtk!4836
2022-06-28 17:59:31 +00:00
Maximiliano Sandoval R dfe9460240 Force quark creation for templates 2022-06-28 18:48:38 +02:00
Sabri Ünal 01820d8524 Update Turkish translation 2022-06-28 15:52:12 +00:00
Benjamin Otte be1729b316 signallistitemfactory: Update signal prototype
I'm not sure this is API safe, but it is necessary if we want to support
section items and canvas items.

If it's deemed API-unstable, we have to copy this object and deprecate
this one.
2022-06-28 16:37:38 +02:00
Benjamin Otte 57f2b5d2e6 listitemfactory: Make this callback-based
This way, we no longer prescribe the use of either GtkListItem or
GtkListItemWidget.

This means we can use it in other places, such as for custom section
header objects or with my Canvas ideas.
2022-06-28 16:37:38 +02:00
Benjamin Otte c00b234440 picture: Clear the paintable properly
Add a clear() function and call it from dispose() instead of using
set_paintable().
2022-06-28 16:37:11 +02:00
Danial Behzadi 8d803e8615 Update Persian translation 2022-06-28 10:31:16 +00:00
Aleksandr Melman 9477ecbc92 Update Russian translation 2022-06-25 18:36:18 +00:00
Quentin PAGÈS 1e686ee535 Update Occitan translation 2022-06-25 08:56:48 +00:00
Christian Hergert 4d883861b1 menutrackeritem: protect against use-after-free
With recent updates to GLib, I now see cases where we can hit a state that
has finalized before notify (which will bump the ref count back up). This
is evident in GNOME Text Editor when showing a language submenu from a
popover, and then dismissing the popover and subsequently the tab.

With the previous commit, we at least get a warning like this, which helped
track down the issue.

 Gtk-CRITICAL **: gtk_action_observable_unregister_observer: assertion 'GTK_IS_ACTION_OBSERVABLE (observable)' failed
 GLib-GObject-CRITICAL **: g_object_ref: assertion '!object_already_finalized' failed

This patch fixes both of those criticals.

Fixes #5009
2022-06-24 14:30:45 -07:00
Christian Hergert f9c0fc4fdd menutrackeritem: be defensive during finalize
The menu/action system tends to be incredibly re-entrant, and while fixing
the misuse during finalization cycles should be a priority, this can help
protect just a bit more.

Related #5009
2022-06-24 14:30:31 -07:00
Benjamin Otte 354f1a783a Merge branch 'wip/otte/for-main' into 'main'
gdk: Replace GTK_USE_PORTAL env var with GDK_DEBUG flag

See merge request GNOME/gtk!4829
2022-06-24 03:39:16 +00:00
Benjamin Otte 813dd0a674 gdk: Replace GTK_USE_PORTAL env var with GDK_DEBUG flag
It's a debug flag, so make it clear that it is one.

Related: Clowns on the Arch wiki on
https://wiki.archlinux.org/title/Uniform_look_for_Qt_and_GTK_applications#Consistent_file_dialog
2022-06-24 03:14:50 +02:00
Matthias Clasen bbfacb4d22 Merge branch 'alatiera/doc-type' into 'main'
shortcutcontroller: fix typo in property docs

See merge request GNOME/gtk!4827
2022-06-23 21:46:45 +00:00
Hugo Carvalho 086f2324a3 Update Portuguese translation 2022-06-23 21:41:23 +00:00
Jordan Petridis c378eacb5d shortcutcontroller: fix typo in property docs
followup of d7dae84af2
2022-06-23 22:35:48 +03:00
Matthias Clasen 0660bb834e Merge branch 'bad-popup-extents' into 'main'
[x11] Fix coordinate space of rect in gdk_x11_surface_get_frame_extents when called on popups.

See merge request GNOME/gtk!4820
2022-06-23 11:59:55 +00:00
Matthias Clasen 092fe2f712 gtk-demo: Cosmetics
Tweak the complicated textview demo a bit.
2022-06-23 07:40:55 -04:00
Matthias Clasen 5be54fad82 Merge branch 'wip/jtojnar/demo-pickers-no-dirs' into 'main'
gtk-demo: Remove mention of directories in picker examples

See merge request GNOME/gtk!4825
2022-06-23 11:39:33 +00:00
Jan Tojnar d91e669d98 gtk-demo: Remove mention of directories in picker examples
Those were removed in https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/2909.
2022-06-22 23:07:28 +02:00
Asier Sarasua Garmendia 9a22577e34 Update Basque translation 2022-06-22 19:17:51 +00:00
Yuri Chornoivan 88366c5e13 Update Ukrainian translation 2022-06-22 19:06:56 +00:00
Matthias Clasen 287ed99130 Merge branch 'wip/otte/inspector-inspector' into 'main'
inspector: Inspect

See merge request GNOME/gtk!4822
2022-06-22 18:25:13 +00:00
Matthias Clasen 40e09cf2bb Merge branch 'wip/xdg-toplevel-bounds' into 'main'
wayland: Add supports for xdg_toplevel.bounds

See merge request GNOME/gtk!4261
2022-06-22 14:24:41 +00:00
Matthias Clasen 5a3ca064ea Merge branch 'gtk-window-export-handle-win32' into 'main'
Implement gtk_window_export_handle for other backends

See merge request GNOME/gtk!4824
2022-06-22 14:20:11 +00:00
Daniel Mustieles edc991dafd Updated Spanish translation 2022-06-22 10:45:59 +02:00
Luca Bacci a1d03e69a4 Add stub gtk_window_export_handle implementation for some backends 2022-06-21 22:56:33 +02:00
Benjamin Otte 18c2ba9b71 inspector: Add an "inspect inspector" button
And launch a new inspector.

The location of that button is rather random - I had no idea where to
put it.
2022-06-21 02:35:02 +02:00
Benjamin Otte 3da3cb35a6 object-tree: Allow inspecting inspectors
We filter by display, so the inspector window should show up only when
inspecting the inspector.
2022-06-21 02:35:02 +02:00
Benjamin Otte e54567611b inspector: Don't use global variable here
When inspecting the inspector, we want to create mutiple displays here.

If we need this to be global, we should store it per-inspected-display.
2022-06-21 02:35:02 +02:00
Aurimas Černius ce88d19015 Updated Lithuanian translation 2022-06-20 22:18:16 +03:00
Emilio Cobos Álvarez 5301a74bd3 [x11] Fix coordinate space of rect in gdk_x11_surface_get_frame_extents when called on popups.
If we take the early return we don't unscale this at the bottom of the
function, causing wrong coordinates in HiDPI screens.

This bug also affects GTK3 (I noticed this running Firefox tests on X).
2022-06-20 10:13:21 +02:00
Matthias Clasen 381c34783d Merge branch 'alatiera/inscription-since' into 'main'
inscription: Add missing Since annotations

See merge request GNOME/gtk!4815
2022-06-17 22:38:16 +00:00
Luca Bacci 3ea8dc02a3 Merge branch 'gdk-win32-gtk-overlay-scrolling' into 'main'
GdkWin32: Add code for gtk-overlay-scrolling setting

Closes #4899

See merge request GNOME/gtk!4816
2022-06-17 09:37:14 +00:00
Luca Bacci 83c780cfad GdkWin32: Add code for gtk-overlay-scrolling setting
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/4899
2022-06-17 11:06:43 +02:00
Jordan Petridis 4b5d218067 inscription: Add missing Since annotations 2022-06-17 00:15:46 +03:00
Matthias Clasen 8944493eca Merge branch 'wip/jimmac/hc-sidebar-borders' into 'main'
HC: make selected items better visible

Closes #4984

See merge request GNOME/gtk!4813
2022-06-15 13:40:17 +00:00
Jakub Steiner dd9f26c492 HC: make selected items better visible
- follow libadwaita's example and outline selected items for better visibility
  in high contrast variant

Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/4984
2022-06-15 14:47:47 +02:00
Jordi Mas 3c038dc239 Update Catalan translation 2022-06-14 19:41:12 +02:00
Matthias Clasen 9ee555719e Merge branch 'matthiasc/for-main' into 'main'
gtk-demo: Add some keywords

See merge request GNOME/gtk!4812
2022-06-14 12:25:02 +00:00
Benjamin Otte 7953092059 Merge branch 'wip/antoniof/dont-rubberband-on-drag-end' into 'main'
listbase: Don't start rubberband on ::drag-end

See merge request GNOME/gtk!4793
2022-06-14 03:45:55 +00:00
Jonas Ådahl de1a8c8d89 wayland: Add support for xdg_toplevel.bounds
The GdkToplevelSize struct already has the concept of "bounds", which
means the largest size a window should reasonably have. It's practically
the equivalent of the monitor the window is intended to be mapped on,
with the "struts" (e.g. panels) cut out. It's used by GTK to use this
information to calculate a default window size that is "lagom" (swedish;
not too large, not too small).
2022-06-13 22:12:55 +02:00
Jordi Mas 98e000beb7 Update Catalan translation 2022-06-13 20:01:17 +02:00
Matthias Clasen 8b3a38779b gtk-demo: Add some keywords
Make it so that the right demos show up when
you search for GtkInscription.
2022-06-13 11:16:51 -04:00
Aleksandr Melman 8d72c8ee5f Update Russian translation 2022-06-13 13:26:30 +00:00
Benjamin Otte f9b0866415 Merge branch 'wip/otte/inscription' into 'main'
Inscription: Derive row alignment from xalign

See merge request GNOME/gtk!4811
2022-06-13 12:08:16 +00:00
Danial Behzadi dbe06357ec Update Persian translation 2022-06-13 06:44:53 +00:00
Danial Behzadi 9e03c3f6cd Update Persian translation 2022-06-13 05:48:56 +00:00
Benjamin Otte 2d14372142 reftests: Add an inscription xalign RTL test
This checks mainly that we do the right thing wrt PangoAlignment
weirdness.

0.25 and 0.75 are set to 0.0 and 1.0 currently because of Pango
limitations (and no desire to manually move lines).
But if that were to be fixed, both the ref and the test should update in
the same way and things should just keep working.
2022-06-13 06:49:22 +02:00
Benjamin Otte 0a4c08a7be inscription: Multiparagraph text is always multiline
Wrap this text and clip towards the bottom, no matter how high the
inscription is.
2022-06-13 06:49:12 +02:00
Benjamin Otte 883011f252 inscription: Do not try to align layouts that have a proper width set
Pango knows where to put the text.
2022-06-13 06:49:12 +02:00
Benjamin Otte 4927b6e625 reftests: Add inscription reftest for xalign
Compare with labels again.
2022-06-13 06:49:11 +02:00
Georges Basile Stavracas Neto c93a01d627 Inscription: Derive row alignment from xalign
Texts usually want the alignment of each row to match the xalign of
the text itself.

Derive the alignment of the PangoLayout from the xalign property of
the inscription. Because Pango doesn't provide float row alignment,
map left, center and right from the xalign in 1 / 3 steps.
2022-06-13 05:35:47 +02:00
Piotr Drąg 221a18704b Update POTFILES.skip 2022-06-12 14:52:37 +02:00
Matthias Clasen 62984d091a Merge branch 'wip/otte/inscription' into 'main'
More inscription work

See merge request GNOME/gtk!4808
2022-06-12 01:38:40 +00:00
Benjamin Otte 6d15549f51 inscription: Add ::wrap-mode
We use a different wrap-mode than GtkLabel, because we cannot just
resize the widget to make long words fit, we have to fit the size we are
given.
2022-06-12 03:10:50 +02:00
Benjamin Otte 4c1fc4f5d7 reftests: Test inscription multiline overflow 2022-06-12 02:42:00 +02:00
Benjamin Otte 98e0ca7477 gtk-demo: Add a "Read More" label demo. 2022-06-11 22:19:17 +02:00
Benjamin Otte 4809efd630 reftests: Test overflowing inscription yalign
Overflowing inscriptions should always align to the top, even when half
an extra line is available.
2022-06-11 22:19:17 +02:00
Matthias Clasen d88e935398 Merge branch 'wip/otte/listmodels' into 'main'
19 listmodels: Add ::item-type and ::n-items

See merge request GNOME/gtk!4807
2022-06-11 15:15:53 +00:00
Benjamin Otte 393ef4d0a2 inscription: Fixate layout at top when it doesn't fit
Ellipsized and clipped layouts shouldn't reposition themselves according
to yalign when they don't fully fit.
2022-06-11 16:28:27 +02:00
Benjamin Otte efd9aac3fa assistant: Add ::item-type and ::n-items to the pages list 2022-06-11 16:08:37 +02:00
Matthias Clasen c7c8b37e4c Merge branch 'wip/otte/inscription' into 'main'
Add GtkInscription

See merge request GNOME/gtk!4800
2022-06-11 13:47:20 +00:00
Benjamin Otte 11aef91fa5 bookmarklist: Add ::item-type and ::n-items 2022-06-11 08:25:23 +02:00
Benjamin Otte f48c9b8388 directorylist: Add ::item-type and ::n-items 2022-06-11 08:25:22 +02:00
Benjamin Otte 62096ebd16 filterlistmodel: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:22 +02:00
Benjamin Otte f7b8184b00 fattenlistmodel: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:21 +02:00
Benjamin Otte b91f60b4f9 listlistmodel: Add ::item-type and ::n-items 2022-06-11 08:25:21 +02:00
Benjamin Otte b6ba8ecbd0 maplistmodel: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:20 +02:00
Benjamin Otte 02ee10639d multifilter: Add ::item-type and ::n-items 2022-06-11 08:25:20 +02:00
Benjamin Otte 0e42fa95b1 multiselection: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:19 +02:00
Benjamin Otte 7a36632afc multisorter: Add ::item-type and ::n-items 2022-06-11 08:25:19 +02:00
Benjamin Otte 301f1a577d noselection: Add ::item-type and ::n-items 2022-06-11 08:25:18 +02:00
Benjamin Otte 67e336992f propertylookuplistmodel: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:18 +02:00
Benjamin Otte e1845f5e90 selectionfiltermodel: Add ::item-type and ::n-items 2022-06-11 08:25:17 +02:00
Benjamin Otte d7dae84af2 shortcutcontroller: Add ::item-type and ::n-items 2022-06-11 08:25:17 +02:00
Benjamin Otte 0f829c4599 singleselection: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:16 +02:00
Benjamin Otte 3fca865625 slicelistmodel: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:16 +02:00
Benjamin Otte bf8b26aa27 sortlistmodel: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:15 +02:00
Benjamin Otte cbc3d3f3ec stack: Add ::item-type and ::n-items to the pages list 2022-06-11 08:25:15 +02:00
Benjamin Otte fd4562aac9 treelistmodel: Add ::item-type and ::n-items
With tests!
2022-06-11 08:25:14 +02:00
Benjamin Otte c26962c4b1 multifilter: Actually emit ::items-changed when items change 2022-06-11 08:25:14 +02:00
Benjamin Otte 46ce19d22a multisorter: Actually emit ::items-changed when items change 2022-06-11 08:25:14 +02:00
Benjamin Otte 303bc3bb1b inspector: Use inscriptions for the rendernodes list 2022-06-11 02:15:08 +02:00
Benjamin Otte bf5edc6b7c reftests: Add test for the overflow methods
Reference is using labels again
2022-06-11 02:15:08 +02:00
Benjamin Otte 7c034cc283 inscription: Set css name
We use "label" just like GtkLabel as the two widgets differ in the way
they are measured, but they should be styled the same.

If it turns out we change our opinion on this for specific cases, we
can add style classes later.
2022-06-11 02:15:08 +02:00
Benjamin Otte e437a9c348 inscription: Add a11y support for text interface
This is entirely untested.
2022-06-11 02:15:08 +02:00
Benjamin Otte 1517c1813c inscription: Add ::text-overflow
Can't name it ::overflow, because that's taken by GtkWidget already
2022-06-11 02:15:08 +02:00
Benjamin Otte 9973a7173f reftests: Add test for inscription markup parsing
Compare with label markup parsing as the reference.
2022-06-11 02:15:08 +02:00
Benjamin Otte 01fcfc5c2a inscription: Add ::markup
Utility property that sets both the ::text and ::attributes properties,
mainly intended for use in ui files to ease translation support and bindings.
2022-06-11 02:15:08 +02:00
Benjamin Otte 3f4c88aad1 inscription: Add ::attributes property 2022-06-11 02:15:08 +02:00
Emin Tufan Çetin 8a0d6da187 Update Turkish translation 2022-06-10 06:06:14 +00:00
Benjamin Otte b8199bcc1f gtkpango: Add G_GNUC_WARN_UNUSED_RESULT
Guess who just spent 10 minutes in gdb and doesn't want to do that
again.
2022-06-10 04:34:23 +02:00
Benjamin Otte abdbef1b5e inspector: Add inscription support
Allow searching for inscription text and show it in the label column.
2022-06-10 04:34:23 +02:00
Benjamin Otte 6ac7f0562b inspector: Use inscriptions in the object tree 2022-06-10 04:34:23 +02:00
Benjamin Otte c796b30136 testcolumnview: Use GtkInscription
This test is suddenly MASSIVELY faster.

I wonder why.
Could it be because inscription does exactly what it was made for?
2022-06-10 04:34:23 +02:00
Benjamin Otte 61bc38cd61 gtk-demo: Use GtkInscription in the wordlist demo 2022-06-10 04:34:23 +02:00
Benjamin Otte b56b5ed81b gtk-demo: Use GtkInscription in the main list 2022-06-10 04:34:23 +02:00
Benjamin Otte b6a8080b2f Add GtkInscription
A label alternative that renders itself into a given rectangle.

The main use case is cells in column view.

Related: #3334
2022-06-09 05:58:27 +02:00
Matthias Clasen 0400607102 Merge branch 'symbolic-hc' into 'main'
Wayland/display: Don't force HighContrast icon theme

See merge request GNOME/gtk!4802
2022-06-08 10:36:46 +00:00
Matthias Clasen 5089fa3ecc Merge branch 'node-editor-scale' into 'main'
node-editor: Add a zoom button

See merge request GNOME/gtk!4804
2022-06-07 18:57:53 +00:00
Benjamin Otte dec6a93510 Merge branch 'wip/otte/for-main' into 'main'
inspector: Allow searching for editable text

See merge request GNOME/gtk!4801
2022-06-07 18:20:43 +00:00
Matthias Clasen 27db4b5c2f node-editor: Add a zoom button
This is a bit more convenient than manually
adding a transform node in the text editor.
2022-06-07 13:39:22 -04:00
Florian Müllner c3706ea9ec wayland/display: Don't force HighContrast icon theme
The theme is considered deprecated in favor of symbolic icons from
the regular theme.
2022-06-07 19:34:50 +02:00
Benjamin Otte e4869938b7 listview: Fix clipping for horizontal listviews
Fixes a bug introduced with
commit 39645d3258
2022-06-07 19:21:46 +02:00
Benjamin Otte fa1dca29b6 inspector: Allow searching for editable text
... and display it in the label column.
2022-06-07 17:33:04 +02:00
Hugo Carvalho 5abaee4f02 Update Portuguese translation 2022-06-07 13:54:09 +00:00
Yuri Chornoivan d2b6fef1f8 Update Ukrainian translation 2022-06-07 06:15:52 +00:00
Benjamin Otte 9de027df65 video: Fix typo in docs 2022-06-07 05:56:15 +02:00
Benjamin Otte a639aaefae Merge branch 'wip/otte/for-main' into 'main'
listview: cull listitems that are out of view

See merge request GNOME/gtk!4799
2022-06-07 01:36:06 +00:00
Benjamin Otte 39645d3258 listview: cull listitems that are out of view
Use set_child_visible(FALSE) on those widgets and don't allocate them.

This should usually be the majority of items, so it's quite a worthwhile
addition.

Idea by Ivan Molodetskikh.

Related: #3334
2022-06-07 03:20:11 +02:00
Matthias Clasen 526b62e0be Merge branch 'fix-ui-file-translation-main' into 'main'
Fix ui files to work for translations

Closes #4957

See merge request GNOME/gtk!4798
2022-06-06 22:45:44 +00:00
Matthias Clasen 19fb336c39 Fix ui files to work for translations
We need to keep using translatable="yes", since
that is what the installed its file is looking
for.

Fixes: #4957
2022-06-06 18:29:14 -04:00
Matthias Clasen 1f3674cf3e Merge branch 'matthiasc/for-main' into 'main'
gdk: Improve GdkTimeCoord docs

See merge request GNOME/gtk!4795
2022-06-06 13:12:15 +00:00
Matthias Clasen c76069389c gdk: Improve GdkTimeCoord docs 2022-06-06 08:55:51 -04:00
Danial Behzadi eef0c81be9 Update Persian translation 2022-06-06 08:13:32 +00:00
Aleksandr Melman c78eeaa874 Update Russian translation 2022-06-05 12:34:50 +00:00
Yuri Chornoivan 2766f61abc Update Ukrainian translation 2022-06-05 08:26:34 +00:00
Benjamin Otte 45422f7b61 Merge branch 'gl-api-es-fix' into 'main'
glcontext: Respect ES API when getting gl version from shared context

Closes #4763

See merge request GNOME/gtk!4687
2022-06-04 20:26:58 +00:00
Pablo Correa Gómez c4feca1311 glcontext: Simplify get_required_version api
Simplify the API to just return the requirements that the user
has asked for. The rest of the code was undocumented and previously
used as a buggy source for a default value from internal code.
Since the buggy code is now fixed, remove all unnecessary cruft.
2022-06-04 20:48:40 +02:00
Pablo Correa Gómez 9426b20759 glcontext: Do not check for correctness in set_required_version
There are two reasons for this:
 * First, the refactored realize code now makes sure that no
   context with unsupported version is ever created.
 * Second, this code could bump into false possitives and negatives, since
   the user is not requested, nor expected to set_required_version
   in any specific order relative to set_allowed_apis. Therefore,
   some version could be rejected or accepted based on a set of
   allowed apis that the user has not yet correctly configured.
2022-06-04 20:48:40 +02:00
Pablo Correa Gómez f97cff1454 glcontext-glx: Refactor realize function
Mimic the behavior of the egl context creation by stablishing
some sane logic for the api and version used. Split the decision
of the type of context (api, legacy) and the creation of a context
of a certain version and all its properties.
2022-06-04 20:48:40 +02:00
Pablo Correa Gómez 549a2b4c86 glcontext: Refactor realize function, fix interaction with shared context 2022-06-04 20:48:40 +02:00
Pablo Correa Gómez f4f0daa113 macosglcontext: Do not rely on default from get_required_version
get_required_version cannot warranty to return any default. Instead,
fetch the user requisites clipped by the requirements in our backend.
2022-06-04 20:48:40 +02:00
Pablo Correa Gómez d4f8a80f2a glcontext-win32-wgl: Respect user required version, use display as minimum
By setting and then getting the required version in a context, the code
was not respecting user requirements. Instead, simply get the requested
version by the user clipped by the requirements (display version)
2022-06-04 20:48:40 +02:00
Pablo Correa Gómez 8d175801d7 glcontext: Add internal get_clipped_version function
It is useful for backends to get user set preferences while
ensuring the correctness of the result, which will be always
greater or equal than the minimum version provided
2022-06-04 20:48:40 +02:00
Pablo Correa Gómez 6bc3ecbe56 glcontext: Improve get_version documentation 2022-06-04 20:48:29 +02:00
António Fernandes dc4540fae9 listbase: Don't start rubberband on ::drag-end
GtkGestrureDrag::drag-end can be emitted when the pointer has just
crossed the drag threshold and we have not started the rubberband yet.
This happens if another gesture has claimed the event sequence earlier
in the current event propagation chain.

In such situation, our ::drag-end calls gtk_list_base_drag_update(), 
which proceeds to start the rubberband. That's obviously wrong.
Additionally, it also tries to get modifiers from an event it we are 
already denied,  which obviously fails with criticals:

`gdk_event_get_modifier_state: assertion 'GDK_IS_EVENT (event)' failed`

Thus, if there is no rubberband when we receive ::drag-end, do nothing.
2022-06-04 17:30:10 +00:00
Matthias Clasen 31da5f7e2a Merge branch 'expand-builtin-icontheme' into 'main'
Add more directories to the builtin hicolor index

Closes #4960

See merge request GNOME/gtk!4786
2022-06-04 10:44:48 +00:00
Matthias Clasen 48228efe42 Merge branch 'wip/carlosg/activation-roundtrip-fix' into 'main'
gdk/wayland: Check the GdkSurface wl_surface before using it for activation

Closes gnome-control-center#1862

See merge request GNOME/gtk!4789
2022-06-02 21:24:10 +00:00
Carlos Garnacho 4b41d4f78c gdk/wayland: Check the GdkSurface wl_surface before using it for activation
Double check the GdkSurface has a wl_surface before using it as the activation
token source, since we cannot use NULL surfaces here.

Fixes: https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/1862
2022-06-02 23:08:40 +02:00
Carlos Garnacho fb68600d88 gdk/wayland: Dispatch GdkAppLaunchContext activation token in its own queue
Use a separate queue to dispatch the token object exclusively, just like we
do on the GdkSurface activation paths.
2022-06-02 23:08:40 +02:00
Matthias Clasen 0e6a3ab397 Merge branch 'ebassi/a11y-text-extents' into 'main'
a11y: Implement atspi.Text.GetCharacterExtents for GtkTextView

See merge request GNOME/gtk!4754
2022-06-02 17:13:53 +00:00
Carlos Garnacho e895f7dd70 a11y: Transform GetCharacterExtents coords to native surface ones
These coordinates are "window"-relative, so transform textview coordinates
to the coordinate system of the GtkNative containing it.
2022-06-02 14:35:53 +02:00
Matthias Clasen dae892d8f6 Add more directories to the builtin hicolor index
We haven't had any scalable directories in this list.
Add some. Since we seem to have settled on including
just actions and status as subdirectories for each
size, add scalable/actions and scalable/status.

Fixes: #4960
2022-06-02 06:38:12 -04:00
Matthias Clasen ad5c3168a9 Merge branch 'wip/chergert/GTK_DEBUG_TEXT_DIR' into 'main'
main: add GTK_DEBUG_TEXT_DIR environment variable

See merge request GNOME/gtk!4768
2022-06-01 18:54:54 +00:00
Christian Hergert 8f1db27b6b gtkmain: add support for GTK_DEBUG=invert-text-dir
This allows inverting the default text-direction in an application for
debugging, testing, and QA purposes. IDEs such as Builder may automate this
to encourage more application developers to test with a text-direction
different than their own.
2022-06-01 11:26:44 -07:00
Matthias Clasen 56a1cbe217 Merge branch 'wip/chergert/fix-lookup-with-interfaces' into 'main'
builderparser: fix <lookup/> with interface types

See merge request GNOME/gtk!4782
2022-06-01 00:13:44 +00:00
Christian Hergert 63e9e7e899 builderparser: fix <lookup/> with interface types
If we have a <lookup name="foo" type="SomeInterface"> a runtime warning
would be emitted and the expression would fail to be created. This is
because the interfaces will likely be a GObject as well, meaning we check
the object type branch instead of the interface.

Instead, we need to use the fundamental type like other parts of the
expression system use.
2022-05-31 15:58:21 -07:00
Matthias Clasen 480a933546 Merge branch 'matthiasc/for-main' into 'main'
shortcutcontroller: Fix a typo

See merge request GNOME/gtk!4778
2022-05-30 21:05:34 +00:00
Matthias Clasen 2623c396cb shortcutcontroller: Fix a typo 2022-05-30 16:27:03 -04:00
Pablo Correa Gómez 826fdc4a80 glcontext: Improve documentation on get_use_es api 2022-05-30 20:48:47 +02:00
Carlos Garnacho 3b088281ca Merge branch 'gesture-click-unpaired-release-nullable-sequence' into 'main'
Mark sequence parameter in GtkGestureClick::unpaired-release signal as nullable

See merge request GNOME/gtk!4777
2022-05-30 09:55:29 +00:00
Sebastian Dröge e61aecd67e Mark sequence parameter in GtkGestureClick::unpaired-release signal as nullable 2022-05-30 11:33:59 +03:00
Aurimas Černius bd68339390 Updated Lithuanian translation 2022-05-29 23:05:31 +03:00
Matthias Clasen 491d1f67c7 Merge branch 'fix-tests-with-recent-glib' into 'main'
Avoid g_log_set_writer_func in tests

See merge request GNOME/gtk!4772
2022-05-28 15:34:13 +00:00
Matthias Clasen 73dc741a82 Avoid g_log_set_writer_func in tests
It is not usable anymore since GLib 2.72.
2022-05-28 10:43:26 -04:00
Luming Zh 38ec040fce Update Chinese (China) translation 2022-05-28 01:52:42 +00:00
Matthias Clasen 6bb1873183 Merge branch 'headerbar-demo-upgrade' into 'main'
Make our demos more likable

See merge request GNOME/gtk!4769
2022-05-27 22:18:26 +00:00
Matthias Clasen 5ba5693efd Make our demos more likable
Nobody likes Facebook.
Everybody loves the Eagles.
2022-05-27 17:34:55 -04:00
Matthias Clasen 797cc2e91b Merge branch 'wayland-cursor-scale2' into 'main'
wayland: scale cursors to the right size

See merge request GNOME/gtk!4766
2022-05-27 16:47:38 +00:00
Matthias Clasen 5507b3f8c1 wayland: scale cursors to the right size
When loading cursors at scale, we expect the
cursor images to have a size of scale * size.
If we don't find such images, load them at their
unscaled size and scale them up ourselves.

Without this, cursors will appear in unexpected
sizes depending on scales and themes.

Related: #4746
2022-05-27 12:26:45 -04:00
Matthias Clasen f9a3f13702 Merge branch 'main' into 'main'
GtkIMContextSimple: array bounds was not correctly checked

Closes #4771

See merge request GNOME/gtk!4748
2022-05-27 14:24:54 +00:00
Matthias Clasen b4c72ac508 Merge branch 'use-flathub-link' into 'main'
Make the formatted link more neutral

See merge request GNOME/gtk!4765
2022-05-27 14:10:47 +00:00
Matthias Clasen bcad305136 Make the formatted link more neutral
There have been complaints about company names in
our demos. Lets use something else.

Part of: #4716
2022-05-27 08:43:06 -04:00
Matthias Clasen 00d45c6743 Merge branch 'update-initial-layout' into 'main'
vulkan: Set initial layout to undefined

See merge request GNOME/gtk!4706
2022-05-27 12:26:24 +00:00
Matthias Clasen 38b393ff5d Merge branch 'update-command-buffer-freeing' into 'main'
vulkan: Don't attempt to free 0 command buffers

See merge request GNOME/gtk!4705
2022-05-27 12:25:48 +00:00
Matthias Clasen 23f92ca1c2 Merge branch 'wayland-cursor-scale' into 'main'
wayland: Sanity check cursor image size

Closes #4746

See merge request GNOME/gtk!4761
2022-05-27 10:58:12 +00:00
Matthias Clasen 34a9bc4632 wayland: Make cursors have the right size
The Wayland protocol requires that width and height
of cursor surfaces is an integer multiple of the
surface scale. Make it so.

Fixes: #4746
2022-05-26 22:29:37 -04:00
Matthias Clasen d603164ec2 wayland: Sanity check cursor image size
On Wayland it is a protocol violation to upload buffers with
dimensions that are not an integer multiple of the buffer scale.

Until recently, Mutter did not enforce this. When it started
doing so, some users started seeing crashes in GTK apps because the
cursor theme ended up with e.g. a 15x16 pixel image at scale of 2.

Add a small sanity check for this case.
2022-05-26 22:29:37 -04:00
Matthias Clasen a033e838b2 Merge branch 'TTMaZa-LGPL-vs-GPL' into 'main'
GDK is LGPL-2.1-or-later not GPL-2.1-or-later, right?

See merge request GNOME/gtk!4755
2022-05-26 12:23:56 +00:00
Matthias Clasen 511a2f4d03 Merge branch 'wip/chergert/fix-sysprof-wrapper' into 'main'
build: fix sysprof default options

See merge request GNOME/gtk!4759
2022-05-26 11:43:56 +00:00
Matthias Clasen c089912a52 Merge branch 'wip/otte/for-main' into 'main'
x11: Always update shadow size

Closes #4136

See merge request GNOME/gtk!4758
2022-05-26 10:03:39 +00:00
Christian Hergert 2694d81d63 build: fix sysprof default options
Sysprof just recently cleaned up it's meson_options.txt and this makes
the tracking of the master branch match the new values.
2022-05-25 22:52:34 -07:00
Benjamin Otte 213490099b x11: Always update shadow size
Not updating shadow size unconditionally would lead to shadow size not
being set on map, which would lead mutter to think that we are a Window
without extents and then become confused when we suddenly set some.

Make sure that doesn't happen by always having shadows set on map, just
like GTK3.

Fixes #4136
2022-05-26 04:38:29 +02:00
Emmanuele Bassi 166af48904 Merge branch 'fix-stack-page-at-spi-parent' into 'main'
a11y: Realize GtkStackPage parent context before trying to get a ref

Closes #4944

See merge request GNOME/gtk!4757
2022-05-25 14:29:41 +00:00
Sebastian Keller 6e3dbc42a8 a11y: Realize GtkStackPage parent context before trying to get a ref
If a context is not realized, calling gtk_at_spi_context_to_ref() will
return a null ref, because its path has not been initialized yet. This
was already done for all other cases in get_parent_context_ref(), but
was missing for the GtkStackPage case.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4944
2022-05-25 14:56:05 +02:00
Matthias Clasen 36fbbfc5c7 Merge branch 'pkgconfig' into 'main'
Meson: Simplify pkgconfig file generator

See merge request GNOME/gtk!4756
2022-05-24 16:46:18 +00:00
Luca Bacci 9bfc89e23d Merge branch 'remove-emulated-scroll-events' into 'main'
Drop pointer_emulated discrete scroll events

See merge request GNOME/gtk!4694
2022-05-24 15:26:24 +00:00
Xavier Claessens 802bf41999 Meson: Simplify pkgconfig file generator
Meson knows all private dependencies itself when passing the library as
first positional argument, no need to specify them manually. Also
simplify backend specific files by simply requiring gtk4, just like
unix-print already did.

This should fix generated gtk4-uninstalled.pc, see Meson bug report:
https://github.com/mesonbuild/meson/issues/10415
2022-05-24 10:30:58 -04:00
Manuel Zabelt 93636d4c5a Update docs/reference/gdk/gdk4-x11.toml.in 2022-05-24 13:37:43 +00:00
Manuel Zabelt 88f761f2c8 GDK is LGPL-2.1-or-later not GPL-2.1-or-later, right? 2022-05-24 13:36:07 +00:00
Luca Bacci 7752467847 Drop pointer_emulated discrete scroll events
GTK4 has had smooth scroll events since the beginning, so we
prefer not to emit emulated discrete scroll events at all
2022-05-24 12:30:49 +00:00
Luca Bacci 8514457d0f Wayland: Only send smooth scroll events for tablet tools 2022-05-24 12:30:49 +00:00
Luca Bacci c0d79aa1ef Merge branch 'scroll-surface-unit-dpi-scale' into 'main'
DirectManipulation: Account for DPI scale

See merge request GNOME/gtk!4749
2022-05-24 12:19:39 +00:00
Luca Bacci 8a6d6fe6b1 DirectManipulation: Account for DPI scale 2022-05-24 11:37:06 +02:00
Emmanuele Bassi 7750a2c423 a11y: Implement atspi.Text.GetCharacterExtents for GtkTextView
Retrieve the location of a given offset in window-relative coordinate
space.
2022-05-23 15:54:13 +01:00
Matthias Clasen 393893b8db Merge branch 'blink-assertion' into 'main'
Remove an assertion that we hit

See merge request GNOME/gtk!4753
2022-05-23 14:08:43 +00:00
Matthias Clasen 4f16242807 Merge branch 'otte-main-patch-30652' into 'main'
gesturedrag: Fix docs

See merge request GNOME/gtk!4752
2022-05-23 12:43:25 +00:00
Matthias Clasen e82fb8e894 Merge branch 'ci-meson-bump' into 'main'
CI: bump meson version from 0.59 to 0.60.3

See merge request GNOME/gtk!4751
2022-05-23 12:33:30 +00:00
Matthias Clasen b3e65bfdc1 Remove an assertion that we hit
It appears that we mess up accounting for blinking
cursors sometimes, and can hit blink_cb when there
is a nonempty selection.

Instead of asserting, warn and stop blinking.

Related: #4767
2022-05-23 08:28:00 -04:00
Aleksandr Melman 111daecd3b Update Russian translation 2022-05-23 12:25:59 +00:00
Benjamin Otte 72fe406c4d gesturedrag: Fix docs
Leftover from GTK3. Coordinates are widget relative everywhere now.
2022-05-22 12:45:28 +00:00
Christian Kirbach 0f01629ce3 Update German translation
(cherry picked from commit 7703aa5cd3)
2022-05-22 10:41:21 +00:00
Christoph Reiter 2f695388e9 CI: bump meson version from 0.59 to 0.60.3
We pull in glib main via a submodule in CI and glib has recently
bumped its meson requirement to >= 0.60:
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2641

Install 0.60.3 where needed to make things build again.
2022-05-22 11:46:54 +02:00
Víctor Marzo 3955633aa8 GtkIMContextSimple: array bounds was not correctly checked
Fixes #4771
2022-05-19 11:35:14 +02:00
Luca Bacci f77f941401 Merge branch 'fix-memory-leak' into 'main'
GdkWin32: Plug memory leak

See merge request GNOME/gtk!4747
2022-05-19 09:05:50 +00:00
Luca Bacci 288dd406e0 GdkWin32: Plug memory leak 2022-05-19 08:49:05 +02:00
Benjamin Otte 8667b7a46c Merge branch 'wip/otte/for-main' into 'main'
nodeparser: Fix parsing of color-matrix node

See merge request GNOME/gtk!4745
2022-05-18 21:08:46 +00:00
Benjamin Otte 0410125f20 nodeparser: Fix parsing of color-matrix node
Negative offsets in the color matrix were inverted because it used the
rect parser.
2022-05-18 21:16:33 +02:00
Benjamin Otte 1ea0de61e1 Merge branch 'wip/otte/for-main' into 'main'
CI: Include reftest nodes in artifacts

See merge request GNOME/gtk!4743
2022-05-18 18:27:29 +00:00
Benjamin Otte e8eb96ae0c CI: Include reftest nodes in artifacts 2022-05-18 19:54:34 +02:00
Hugo Carvalho 04f924c13e Update Portuguese translation 2022-05-18 14:54:31 +00:00
Matthias Clasen 1fbca7a76a Merge branch 'let_selectable_label_mnemonic_self_focus' into 'main'
Allow selectable labels contents to be selected by mnemonic

See merge request GNOME/gtk!4741
2022-05-18 13:55:33 +00:00
Caolán McNamara 3f49d335d1 Allow selectable labels contents to be selected by mnemonic
expecially by the mnemonic of another label that targets it.

https://gitlab.gnome.org/GNOME/gtk/-/issues/4927

see also https://bugs.documentfoundation.org/show_bug.cgi?id=137748
2022-05-18 12:40:40 +01:00
Jordi Mas 3882e14053 Update Catalan translation 2022-05-18 13:32:32 +02:00
Matthias Clasen 5f5fda911d Merge branch 'wip/chergert/fix-4934' into 'main'
checkbutton: fix critical when setting use-underline

Closes #4934

See merge request GNOME/gtk!4740
2022-05-18 01:34:47 +00:00
Christian Hergert b9574e119b checkbutton: fix critical when setting use-underline
This needs to make sure that we've created the label before applying the
setting on a child widget.

Fixes #4934
2022-05-17 12:28:25 -07:00
Benjamin Otte 5f469a0d2d Merge branch 'wip/otte/for-main' into 'main'
testsuite: Add tests for label overdraw

See merge request GNOME/gtk!4737
2022-05-17 00:19:01 +00:00
Benjamin Otte ffd3801b1d testsuite: Add tests for label overdraw
This brings back a subset of what quit-mnemonic.ui tested for, but
trying a lot harder to trigger the label overdrawing its allocation,
which will cause the text to be cut off when clipping is happening.

It should not be an issue at all with GTK4, but keeping that test around
is a good idea.
2022-05-17 00:14:19 +02:00
Matthias Clasen fd21df7244 Merge branch 'wip/chergert/fix-4625' into 'main'
gsk/gl: use critical instead of assert in dispose

Closes #4625

See merge request GNOME/gtk!4736
2022-05-16 20:27:53 +00:00
Christian Hergert 654d74bfb8 gsk/gl: use critical instead of assert in dispose
Instead of asserting only in debug builds (which are generally not
shipped in distributions) we should deliver a critical log-level message
so that these can be found sooner when not developing with jhbuild,
Flatpak, etc.

Also assert that we've setup the state correctly when realizing the
GskGLRenderer object.

Fixes #4625
2022-05-16 10:50:48 -07:00
Fran Dieguez a26c72ef79 Update Galician translation 2022-05-16 07:58:59 +00:00
Danial Behzadi 6b55a14429 Update Persian translation 2022-05-16 07:38:02 +00:00
Matthias Clasen bc241d62af Merge branch 'wip/sophie-h/remove-properties-translation' into 'main'
l10n: Remove po/pot for dropped nicks/blurbs

See merge request GNOME/gtk!4718
2022-05-16 00:14:28 +00:00
Matthias Clasen 2b2894490f Merge branch 'hb-dependency' into 'main'
Add an explicit harfbuzz dependency

See merge request GNOME/gtk!4732
2022-05-15 16:34:19 +00:00
Matthias Clasen c0747f2c2e Add an explicit harfbuzz dependency
We are using Harfbuzz api in the file chooser,
so lets make this official.
2022-05-15 10:37:24 -04:00
Luca Bacci b34beb9380 Merge branch 'gdk-win32-direct-manipulation' into 'main'
GdkWin32: Add support for DirectManipulation

See merge request GNOME/gtk!4698
2022-05-15 12:55:22 +00:00
Luca Bacci 8f19099f1a GdkWin32: Add support for DirectManipulation
Adds support for Precision TouchPads (PTPs) gestures
and scroll events.
2022-05-15 14:37:55 +02:00
Piotr Drąg db2516af0a Update Polish translation 2022-05-15 14:04:06 +02:00
Emin Tufan Çetin bd07f846ef Update Turkish translation 2022-05-15 11:14:27 +00:00
Danial Behzadi d938352fb3 Update Persian translation
(cherry picked from commit 2b1c09dd42)
2022-05-15 06:30:32 +00:00
Matthias Clasen 13eef432fc Merge branch 'ci-update' into 'main'
ci: Update the Fedora image to Fedora 36

See merge request GNOME/gtk!4730
2022-05-14 21:59:09 +00:00
Matthias Clasen 1b355ff2e0 Drop the quit-mnemonic reftest
I can't quite figure out what this test was meant
to test, and how to make it do so in a way that
does not fall afoul of rendering issues in the GL
renderer and rounding differences in pango.

Can't win with reftests.
2022-05-14 17:03:37 -04:00
Matthias Clasen aa9a8702e4 ci: Update the Fedora image to Fedora 36
Also remove systemtap from the image, since
we don't need it.

The v36 image is still used in gtk-4-6.
2022-05-14 12:23:02 -04:00
Benjamin Otte ab2109ea6b Merge branch 'wip/otte/for-main' into 'main'
listitemmanager: Clarify warning

See merge request GNOME/gtk!4731
2022-05-14 15:28:09 +00:00
Benjamin Otte 926eb161f8 broadway: Fix gcc 12 complaining 2022-05-14 16:53:44 +02:00
Benjamin Otte 61bb9bb935 listitemmanager: Clarify warning
Lars doesn't have an opinion on this problem anymore.

And when people see this warning, they should know what to do.
2022-05-14 16:53:44 +02:00
Matthias Clasen 8f55a014b1 Merge branch 'matthiasc/for-main' into 'main'
Cosmetic fixes to objcopy hack

See merge request GNOME/gtk!4729
2022-05-14 12:48:40 +00:00
Yuri Chornoivan c3e5d80853 Update Ukrainian translation 2022-05-14 12:22:13 +00:00
Matthias Clasen 8bd77441a9 Cosmetic fixes to objcopy hack
Preserve the elf section name that we would get
without the objcopy hack. Minimizing the differences
2022-05-14 07:53:47 -04:00
Anders Jonsson a2af794cb0 Update Swedish translation
(cherry picked from commit 2d8a8e3575)
2022-05-14 10:03:38 +00:00
Matthias Clasen 0c86b28828 Merge branch 'texture-serialize-tiff' into 'main'
gsk: Serialize textures as tiff

See merge request GNOME/gtk!4725
2022-05-13 17:06:46 +00:00
Matthias Clasen 4278e91a46 Merge branch 'texture-fixes' into 'main'
Fixes for gdk_memory_texture_new_subtexture

See merge request GNOME/gtk!4724
2022-05-13 16:38:45 +00:00
Matthias Clasen dd16d7c4c8 gsk: Serialize float textures as tiff
Otherwise, we lose precision when converting them
to 16bit integers.
2022-05-13 12:34:24 -04:00
Matthias Clasen 6164908bd3 Add tests for gdk_memory_texture_new_subtexture
This checks the fixes in the previous commit.
2022-05-13 11:44:11 -04:00
Matthias Clasen 2ff98dad03 Merge branch 'file-chooser-widget-make-key-controller-on-external-entry-work-at-bubble-phase' into 'main'
GtkFileChooserWidget: Propagate keys from external entry to fcwidget at the BUBBLE phase

Closes #4905

See merge request GNOME/gtk!4723
2022-05-13 14:53:23 +00:00
Matthias Clasen f33c521836 Fixes for gdk_memory_texture_new_subtexture
There were several mistakes here.

The width of subtextures was set to the width of
the main texture, the data size wasn't properly
calculated, and the preconditions were inverted.
Yay us!
2022-05-13 09:30:46 -04:00
Luca Bacci e1159dab93 GtkFileChooserWidget: Propagate keys from external entry to fcwidget at the BUBBLE phase
Now that we use event controllers we can forward keybindings from the
external entry to the filechooserwidget at the bubble phase.

Fixes #4905

References:
 * commit 1fb075dbca
 * commit 686116ba61
2022-05-13 14:19:14 +02:00
Matthias Clasen c4f423694f Merge branch 'egl-format-string' into 'main'
egl: Fix invalid format string

See merge request GNOME/gtk!4722
2022-05-12 15:25:29 +00:00
Loïc Minier 4f2b1b3cfc egl: Fix invalid format string 2022-05-12 09:06:20 -04:00
Matthias Clasen 122fa679a8 Merge branch 'wip/sophie-h/remove-param-nicks-blurbs' into 'main'
gtk: Remove all nicks and blurbs from param specs

Closes #4904

See merge request GNOME/gtk!4717
2022-05-12 02:18:02 +00:00
Matthias Clasen 7302407880 Merge branch 'wip/exalm/color-scales' into 'main'
Redesign GtkColorScale

See merge request GNOME/gtk!4720
2022-05-12 02:01:03 +00:00
Matthias Clasen 900a23e2bb Merge branch 'wip/chergert/action-critical-fixes' into 'main'
various action muxer correctness fixes

See merge request GNOME/gtk!4719
2022-05-12 01:53:48 +00:00
Alexander Mikhaylenko 0f7d93492d theme: Redesign color scales
See https://gitlab.gnome.org/GNOME/libadwaita/-/issues/469

Since this style needs changes in color scales themselves, it makes sense
to have it in GTK as well.
2022-05-12 02:22:52 +04:00
Alexander Mikhaylenko aee4475c0f range: Support border-radius for GtkColorScale troughs
With how this hack is organized, it's simpler to add more code here than
to pass it to GtkColorScale itself.
2022-05-12 02:21:51 +04:00
Alexander Mikhaylenko 1f61cb2251 coloreditor: Stop adding marks style to color scales 2022-05-12 02:21:34 +04:00
Christian Hergert 0382e3b46c actionmuxer: check for observer before unregistering
This can happen if the group can be resolved even when doing the initial
registration of an action as observer will not yet be in the GSList of
watchers (and therefore has no weak references).

Fixes a warning like the following:

 g_object_weak_unref: couldn't find weak ref
2022-05-11 14:43:31 -07:00
Christian Hergert 547b2891cb actionmuxer: set handler ids initially to zero
These were getting created with possible non-zero values and then inserted
into a hashtable where the readers may not know the state of the group.

Ensure those values are set to zero until we assign them below.
2022-05-11 14:43:24 -07:00
Sophie Herold 89614f5f72 inspector: Stop using blurb as tooltip
Does not make sense any longer if we don't set blurbs.
2022-05-11 18:16:44 +02:00
Sophie Herold f5fc71fe82 tests: Check for nicks and blurbs not being set 2022-05-11 18:16:44 +02:00
Sophie Herold a546ae32d7 Remove all nicks and blurbs from param specs
Those property features don't seem to be in use anywhere.
They are redundant since the docs cover the same information
and more. They also created unnecessary translation work.

Closes #4904
2022-05-11 18:16:29 +02:00
Sophie Herold 17578a97d6 l10n: Remove po/pot for dropped nicks/blurbs 2022-05-11 17:36:07 +02:00
Matthias Clasen 9536eb654b Merge branch 'fix-wayland-glitching-v2' into 'main'
gdk/wayland: freeze popups when hidden 2

See merge request GNOME/gtk!4712
2022-05-10 19:32:16 +00:00
Pablo Correa Gómez 0f21f6c273 glcontext: Make the creation of EGL context more obvious
By splitting it into its own function it becomes more that the
EGL code is a shared implementation.
2022-05-10 12:29:08 +02:00
Christian Hergert 4bf07aeef9 gdk/wayland: freeze popups when hidden
Previously, there was an issue with glitching after showing/hiding a
popover that was not also destroyed. This was due to the popover having
an update_freeze_count of zero after hiding the surface.

That resulted in it's toplevel continuously dropping frames such as during
high-frame-rate scrolling in textviews. This problem is much more visible
on high-frame-rate displays such as 120hz/144hz.

With this commit, we freeze the frame clock of the popup until it is
mapped again.
2022-05-10 07:28:25 +03:00
Pawan Chitrakar 26b250503d Update Nepali translation
(cherry picked from commit f60e5950dc)
2022-05-09 10:44:46 +00:00
Matthias Clasen 8533824084 Merge branch 'add-gtk-dropdown-buildable-example' into 'main'
dropdown: Add GtkBuildable doc

See merge request GNOME/gtk!4708
2022-05-08 22:15:32 +00:00
Sonny Piers 5a0d6e3fc8 dropdown: Add UI definition example 2022-05-08 22:52:05 +02:00
Pawan Chitrakar 6be466b675 Update Nepali translation
(cherry picked from commit 5ae37c6d99)
2022-05-08 08:44:59 +00:00
TestingPlant 1c587c7d7f vulkan: Set initial layout to undefined
Having the initial layout set to VK_IMAGE_LAYOUT_GENERAL causes issues
when going from the final layout to the initial layout since the image
layout is expected to be the general layout. Setting the initial layout
to undefined doesn't have this restriction.
2022-05-08 05:39:36 +00:00
TestingPlant 2f98de06bc vulkan: Don't attempt to free 0 command buffers
vkFreeCommandBuffers can't be called with commandBufferCount set to 0.
2022-05-08 05:37:14 +00:00
Matthias Clasen 9e6855cdb8 Merge branch 'matthiasc/for-main' into 'main'
printdialog: Handle nonexisting files better

See merge request GNOME/gtk!4702
2022-05-08 00:51:08 +00:00
Matthias Clasen a6c3e440f6 printdialog: Handle nonexisting files better
When a non-existing file is selected in the file chooser
for print-to-file, we weren't updating the button label
to show the new filename. Fix that.

Also, use newer file chooser api.
2022-05-07 20:31:46 -04:00
Matthias Clasen 08d386844a 4.7.0 2022-05-07 11:59:38 -04:00
Matthias Clasen 48e98d333e NEWS: Updates 2022-05-07 11:45:31 -04:00
Matthias Clasen ad4536e825 Merge branch 'install-node-editor' into 'main'
Install gtk4-node-editor

See merge request GNOME/gtk!4701
2022-05-07 12:09:29 +00:00
Piotr Drąg 2080f3db17 Update POTFILES.in and POTFILES.skip 2022-05-07 13:49:37 +02:00
Matthias Clasen 726a92200f Install gtk4-node-editor
It is an application worth having around.
2022-05-07 07:18:36 -04:00
Matthias Clasen f9afee0667 Add a man page for gtk4-node-editor 2022-05-07 07:18:36 -04:00
Matthias Clasen 78d34c098e node-editor: Add things
Add a desktop file and appdata.
2022-05-07 07:18:36 -04:00
Matthias Clasen aa4e8334ee Merge branch 'faster-listview-scrolling' into 'main'
listitemwidget: Avoid some unnecessary work

See merge request GNOME/gtk!4700
2022-05-07 03:51:45 +00:00
Matthias Clasen 5eee5e8cac Merge branch 'redo-doc-images' into 'main'
wip: Redo doc image generation

See merge request GNOME/gtk!4646
2022-05-07 03:51:10 +00:00
Matthias Clasen 376d95a549 Updated screenshots
Produced by running the screenshot command over the
ui files in the same directory.
2022-05-06 23:05:15 -04:00
Matthias Clasen a3ac414465 Generate screenshots on the fly
This commit adds a new meson option -Dupdate_screenshots=true.
When it is enabled, and -Dgtk_doc=true is also used, then the
build will generate images to include in the API docs from
ui files in docs/reference/gtk/images.

Note: we still keep a copy of the images in git, in order to
allow building without a display connection. To update the
images in git, the generated images need to be copied back
from the builddir to the srcdir.
2022-05-06 22:59:22 -04:00
Matthias Clasen 8ee6203e2c Remove the old doc shooter infrastructure
This is no longer used.
2022-05-06 22:59:22 -04:00
Matthias Clasen fadeda61e5 listitemwidget: Avoid more paramspec lookups
We can use the same helper function in all
places where we notify all three listitem
properties.
2022-05-06 22:28:14 -04:00
Matthias Clasen 3307b8ce88 listitemwidget: Avoid some unnecessary work
Only update widget and accessible state if the
selected property actually changed.
2022-05-06 21:36:22 -04:00
Matthias Clasen fff32faa67 Merge branch 'screenshot-popovers' into 'main'
builder-tool: Screenshot popovers properly

See merge request GNOME/gtk!4699
2022-05-07 00:39:35 +00:00
Matthias Clasen c0acf264a9 builder-tool: Screenshot popovers properly
Do the necessary shenanigans to get popovers to show
up in screenshots.
2022-05-06 14:43:45 -04:00
Matthias Clasen dacca9ece0 Merge branch 'check-half-float' into 'main'
gdk: Check OES_vertex_half_float GLES extension

See merge request GNOME/gtk!4689
2022-05-06 18:02:05 +00:00
Benjamin Otte bd9c491076 Merge branch 'list-item-factory-notify-by-pspec' into 'main'
list-item: Use notify_by_pspec instead of by name

See merge request GNOME/gtk!4697
2022-05-06 16:11:21 +00:00
Matthias Clasen 93d62acdf3 Merge branch 'builder-treestore-data' into 'main'
Add buildable data support to GtkTreeStore

See merge request GNOME/gtk!4695
2022-05-06 15:22:41 +00:00
Matthias Clasen 0da75b0bbf gsk: Check for half float support
The GL renderer currently relies on half float support
in vertex buffers, so check that we have it.

Related: #4894
2022-05-06 11:05:57 -04:00
Ivan Molodetskikh 8328bd9f96 list-item: Use notify_by_pspec instead of by name
This is a hot path when scrolling a ColumnView, and
g_param_spec_pool_lookup () was taking a measurable part in this hot
path. Instead, notify using pspecs to avoid the name lookup.

Related: https://gitlab.gnome.org/GNOME/gtk/-/issues/3334
2022-05-06 18:05:03 +03:00
Luca Bacci 1a82e6a762 Merge branch 'gdk-win32-rework-scroll-input-handling' into 'main'
GdkWin32: Rework scroll input handling

See merge request GNOME/gtk!4633
2022-05-06 14:58:32 +00:00
Benjamin Otte 886bb0f522 Merge branch 'list-item-factory-no-freeze-thaw' into 'main'
listitemfactory: Track notify manually instead of freeze/thaw

See merge request GNOME/gtk!4696
2022-05-06 14:52:21 +00:00
Ivan Molodetskikh d65e7c9d05 listitemfactory: Track notify manually instead of freeze/thaw
freeze/thaw_notify () showed up on the perf trace for rapid ColumnView
scrolling. Track the three properties manually to make it a little
faster.

Related: https://gitlab.gnome.org/GNOME/gtk/-/issues/3334
2022-05-06 17:31:24 +03:00
Matthias Clasen a96af76c8a Merge branch 'unclipped-screenshots' into 'main'
builder-tool: Include shadows in screenshots

See merge request GNOME/gtk!4692
2022-05-06 13:49:14 +00:00
Matthias Clasen 0ce49daa5f testsuite: test new treestore builder functionality
Verify that we can nest rows.
2022-05-06 09:29:44 -04:00
Matthias Clasen 08154c41f9 treestore: support nested data in builder
This allows <row> elements to be nested.
Note that the child rows must come after
the data for the row itself.
2022-05-06 09:29:44 -04:00
Matthias Clasen f880d24f2a builder: Allow checking for multiple parents 2022-05-06 09:29:44 -04:00
Matthias Clasen 10b5698b78 testsuite: Copy liststore builer tests for trees
This adds tests for data, but not nesting yet.
2022-05-06 09:29:44 -04:00
Matthias Clasen c2e8604805 treestore: Copy liststore buildable implementation
This add support for data, but does not allow
nesting yet.
2022-05-06 09:29:44 -04:00
Matthias Clasen 1a488722fa treestore: Cosmetics
Some renaming in the buildable code to make it more
similar to the liststore implementation.
2022-05-06 09:29:44 -04:00
Benjamin Otte 361e8ac076 Merge branch 'otte-main-patch-11831' into 'main'
Don't invalidate parent if it didn't change

See merge request GNOME/gtk!4693
2022-05-06 13:03:47 +00:00
Luca Bacci 66a0e0a59e GdkWin32: Send smooth scroll events
Bring back smooth scroll events as the issues mentioned
in [1] do not occur anymore. Also rework code style and
comments.

References:

  [1] GTK4: Scrolling hides mouse on windows
      https://gitlab.gnome.org/GNOME/gtk/-/issues/3581

  [2] Why are mouse wheel messages delivered to the focus window
      instead of the window under the mouse?
      https://devblogs.microsoft.com/oldnewthing/20160420-00/?p=93325
2022-05-06 15:01:59 +02:00
Benjamin Otte c29bf115f2 Don't invalidate parent if it didn't change
This looks like a leftover excess invalidation from when the surrounding
code was refactored to not just be called on parent changes but also
when repositioning inside the same parent in commit
507016cafc

Ivan Molodetskikh found this problem in
https://gitlab.gnome.org/GNOME/gtk/-/issues/3334#note_1445873 which
contains a longer analysis of this problem and the performance
reductions it causes.

Related: #3334
2022-05-06 11:50:55 +00:00
Matthias Clasen b74aec3606 Merge branch 'editable-label-fixes' into 'main'
theme: Fix editable label selection

See merge request GNOME/gtk!4690
2022-05-05 23:38:23 +00:00
Matthias Clasen e3abd7df5c builder-tool: Include shadows in screenshots
Remove the clipping to the widget area that
GtkWidgetPaintable imposes, so we can see shadows
and other out-of-bounds rendering. This is particularly
useful for toplevel windows with client-side decorations.
2022-05-05 18:29:05 -04:00
Matthias Clasen 25069cf233 editablelabel: Make :editing writable
This does not hurt, and lets us start editing from
a ui file, which is useful for documentation screenshots.
2022-05-05 17:33:24 -04:00
Matthias Clasen 158963ff77 gdk: Check OES_vertex_half_float GLES extension
This will be checked in the GL renderer.
2022-05-05 13:21:25 -04:00
Matthias Clasen 19fa7d513d theme: Fix editable label selection
When the editable label is in editing mode,
selections should appear the same as in other
entries.
2022-05-05 12:44:40 -04:00
Matthias Clasen a0374334d4 Merge branch 'matthiasc/for-main' into 'main'
docs: Fix a spinbutton example

See merge request GNOME/gtk!4686
2022-05-04 12:28:32 +00:00
Matthias Clasen 3bae7f540e docs: Fix a spinbutton example
We need to use editable api for editable functionality.
2022-05-04 07:42:45 -04:00
Benjamin Otte 23fc3d9ecd Merge branch 'checkbutton-label' into 'main'
Expose GtkCheckButton label child for manipulation

Closes #4698

See merge request GNOME/gtk!4489
2022-05-03 22:05:47 +00:00
Matthias Clasen c645da00dc Merge branch 'wrap-mode-invalid-cast' into 'main'
Don't cast GtkWrapMode to the incompatible enum PangoWrapMode

Closes #4869

See merge request GNOME/gtk!4671
2022-05-03 17:46:51 +00:00
Matthias Clasen 4867ac653a Merge branch 'wip/exalm/eye-icons' into 'main'
icons: Use the proper eye icons

See merge request GNOME/gtk!4663
2022-05-03 17:37:54 +00:00
Matthias Clasen b0ccfce1d6 Merge branch 'wip/carlosg/ignore-null-preedit' into 'main'
imcontextwayland: Ignore preedit updates from NULL to NULL

See merge request GNOME/gtk!4667
2022-05-03 17:37:36 +00:00
Matthias Clasen 3f6b5ccf4a Merge branch 'ebassi/issue-4883' into 'main'
Keep FileChooserNative alive while a portal is running

Closes #4883

See merge request GNOME/gtk!4675
2022-05-03 16:37:27 +00:00
Pablo Correa Gómez 07299dd9c7 Expose GtkCheckButton label as a child for manipulation
This allows consumers greater control over the label without the need
to expose each of the label properties as part of GtkCheckButton interface.
Specifically, motivation for this commit is to be able to wrap the label.

Closes #4698
2022-05-03 16:25:55 +02:00
Matthias Clasen d3ffc0c3bb Merge branch 'wip/another-randr-error-trap-4' into 'main'
x11: Trap errors happening when getting output properties

See merge request GNOME/gtk!4681
2022-05-03 00:44:05 +00:00
Luca Bacci 48ef26317e Merge branch 'fix-introspection-tests-win' into 'main'
testsuite: Fix introspection test on Windows

See merge request GNOME/gtk!4664
2022-05-02 19:00:38 +00:00
Luca Bacci 981981dc46 Merge branch 'fix-list-model-checks-null-vs-empty' into 'main'
GtkFileChooserWidget: fixes for NULL vs empty GListModel

Closes #4851 and #4858

See merge request GNOME/gtk!4678
2022-05-02 18:53:27 +00:00
Jonas Ådahl f1551a87f6 x11: Trap errors happening when getting output properties
This is to avoid getting X11 errors (thus aborting/exiting with a
failure) during rapid hotplugs, which may happen during e.g. CI testing.
2022-05-02 17:28:36 +02:00
Yuri Chornoivan 9c42b8fb2b Update Ukrainian translation 2022-05-02 09:14:32 +00:00
Yuri Chornoivan f6aa6dc59d Update Ukrainian translation 2022-05-02 09:11:07 +00:00
Matthias Clasen 35cd02cd1e Merge branch 'fix-large-compose-file' into 'main'
composetable: Add a missing NULL check

Closes #4873

See merge request GNOME/gtk!4679
2022-05-02 08:26:38 +00:00
Matthias Clasen 2b183a9f4e Reject compose tables that are too large
The fixed-size format we use currently can only handle up
to 32768 bytes of string data. If a compose file contains
more, reject it with a warning.

Fixes: #4873
2022-05-02 16:03:45 +08:00
Matthias Clasen 5df314fa8f composetable: Add a missing NULL check
gtk_compose_table_parse can return NULL. Handle it.
2022-05-02 15:39:03 +08:00
Luca Bacci 5a1396d38e GtkFileChooserWidget: return empty GListModel in get_files () instead of NULL 2022-05-01 16:52:13 +02:00
Luca Bacci 6ce36e6a7d GtkFileChooserWidget: check for empty instead of NULL GListModel
While porting GtkFileChooserWidget from GList to GListModel we did not
change some checks for NULL to checks for empty list.

Fixes #4851, #4858
2022-05-01 16:52:13 +02:00
Emmanuele Bassi 196ec107d1 Keep FileChooserNative alive while a portal is running
Even if the FileChooserNative instance drops out on us while we're still
waiting for the portal to answer, we should keep the data and pointers
alive until the sequence of asynchronous operations is running. The code
already tries to do that, by acquiring a strong reference to the
GtkFileChooserNative instance, but it's also freeing data as soon as the
dialog is hidden, while asynchronous callbacks that will look at the
fields on that data are still in flight.

To avoid that, we defer freeing the data until the asynchronous
callbacks are invoked, and we keep a reference on the dialog while we're
emitting signals on it.

Fixes: #4883
2022-04-29 15:27:10 +01:00
Federico Mena Quintero 4ddf1b70a2 Make the wrap_mode test unix-only
The relevant accessibility code is not built on Windows.
2022-04-28 09:46:48 -05:00
Emmanuele Bassi b3f04413b4 Merge branch 'wip/sophie-h/fix-4020' into 'main'
filechooser: Small fix for select folder mode

Closes #4020

See merge request GNOME/gtk!4650
2022-04-27 13:46:14 +00:00
Federico Mena Quintero 898a2e9fcf textbuffer: Test the serialization of the wrap-mode attribute 2022-04-26 20:22:59 -05:00
Federico Mena Quintero ae06e40bcc Put the text buffer tests in the internal_tests suite
We'll start testing the internal gtk_text_buffer_get_run_attributes()
soon.
2022-04-26 14:01:08 -05:00
Benjamin Otte 940248598e Merge branch 'wip/otte/for-main' into 'main'
roaring: Remove extra careful code

Closes #4252 and #4517

See merge request GNOME/gtk!4669
2022-04-26 18:58:08 +00:00
Federico Mena Quintero 737854aa0d Don't cast GtkWrapMode to the incompatible enum PangoWrapMode
The enum values are not compatible, and moreover, there is an extra
GTK_WRAP_NONE that PangoWrapMode doesn't have - thus,
pango_wrap_mode_to_string() will assert.

As far as I can tell, Orca does not read the wrap-mode key in the
dictionary for text attributes, anyway.

Fixes: #4869
2022-04-26 13:43:19 -05:00
Benjamin Otte 515b1f5292 boxlayout: Do not infloop
if the loop for determining max width grows too big, print an error and
abort assuming that a satisfactory value was reached.

This will cause wrong layout and might cause widgets to overlap, but it
will not infloop.

It actually works around and doesn't really fix the primary cause of the
following bugs, but good enough to close them:

Fixes: #4252
Fixes: #4517
2022-04-26 19:56:01 +02:00
Benjamin Otte 25520964af ffmpeg: Hey, this variable is const now! 2022-04-26 19:39:20 +02:00
Benjamin Otte ea79f2dcf4 roaring: Remove extra careful code
because gcc knows it's too careful
2022-04-26 19:38:36 +02:00
Emmanuele Bassi 1d609d2a16 Merge branch 'annotation-fix' into 'main'
gtk/popovermenu: Fix transfer annotation of new_from_model_full()

See merge request GNOME/gtk!4668
2022-04-26 13:08:00 +00:00
Florian Müllner b82fae9177 gtk/popovermenu: Fix transfer annotation of new_from_model_full()
The function doesn't return a full reference, but a floating widget
like comparable constructor functions.
2022-04-26 14:30:21 +02:00
Carlos Garnacho d6fe6f495a imcontextwayland: Ignore preedit updates from NULL to NULL
If we get consecutive preedit string updates that announce a NULL
string, we still do end up issuing ::preedit-changed with those.
Ignore changes from NULL to NULL, it is the other combinations which
must issue this signal.
2022-04-26 12:23:09 +02:00
Chun-wei Fan 65a7df47f2 Introspection test: Reverse os.add_dll_directory() order
It looks like os.add_dll_directory() works in a LIFO order, so we call
os.add_dll_directory() from the end of the list of directories in %PATH%
so that the directories are searched in the correct order.
2022-04-26 11:52:31 +08:00
Chun-wei Fan 3471c22f52 testsuite: Fix introspection test on Windows
...when we are using Python 3.8.x or later.  Python 3.8.x or later on Windows
require one to call os.add_dll_directory() on every directory that contains
dependent non-system DLLs of a module that are not bundled/installed with the
module.

Since we are very likely running programs that rely on dependent items in
%PATH%, make things easier for people by calling os.add_dll_directory() on
all the valid paths in %PATH% in api.py, so that the test will run
successfully on Windows with Python 3.8.x or later.
2022-04-26 11:51:26 +08:00
Zurab Kargareteli 3af4d53945 Update Georgian translation 2022-04-23 17:05:50 +00:00
Alexander Mikhaylenko 1ca2d41a98 icons: Use the proper eye icons
adwaita-icon-theme has more appropriate icons for showing/hiding text now.
use those, and in the process fix the fact GtkPasswordEntry has been using
them the other way around.
2022-04-22 16:22:05 +04:00
Rafael Fontenelle 12287c034b Update Brazilian Portuguese translation 2022-04-21 01:34:01 +00:00
Matthias Clasen 76dc7f1b1b Merge branch 'vertical-spin-selection-fix' into 'main'
theme: Fix vertical spin button selection

Closes #4788

See merge request GNOME/gtk!4659
2022-04-20 03:35:44 +00:00
Matthias Clasen 0ea3dcacb0 theme: Fix vertical spin button selection
The selection should be black-on-blue as it is
everywhere else now. This was just a leftover.

Fixes: #4788
2022-04-19 23:14:37 -04:00
Emmanuele Bassi 9761a4758a Merge branch 'ebassi/issue-4825' into 'main'
Fix crash when running GTK4 apps under Orca

Closes #4825

See merge request GNOME/gtk!4657
2022-04-19 21:04:25 +00:00
Emmanuele Bassi 17262d1572 a11y: Defer object registration after root registration
The root accessible object is registered asynchronously, as it needs to
call a method on the AT-SPI registry daemon. This means we need to defer
registering the GtkAtSpiContext on the accessibility bus and in the
cache until after the registration is complete.

Fixes: #4825
2022-04-19 16:35:27 +01:00
Emmanuele Bassi 4dcd02e853 Quench the anger of GCC
Direct access of the fields of the union trips compiler warnings with
GCC 12, such as:

  ../gtk/gtkimagedefinition.c:135:13: error: array subscript
  ‘GtkImageDefinition {aka union _GtkImageDefinition}[0]’ is partly
  outside array bounds of ‘GtkImageDefinitionEmpty[1]’ {aka
  ‘struct _GtkImageDefinitionEmpty[1]’} [-Werror=array-bounds]
2022-04-19 15:33:21 +01:00
Matthias Clasen 8e28b0765c Merge branch 'file-filter-fix' into 'main'
Fix file filter buildable support

Closes #4787

See merge request GNOME/gtk!4652
2022-04-19 03:51:16 +00:00
Matthias Clasen c882a611c8 Fix file filter buildable support
File filters creates from ui files had some
extraneous gunk in them. Fix that. Test included.

Fixes: #4787
2022-04-18 23:03:15 -04:00
Sophie Herold 908661fee6 filechooser: Small fix for select folder mode
When changing folders, we were making the select
button insensitive when there is no folder selected.
However, the select button should be usable to
select the current folder.

Fixes #4020
2022-04-19 00:55:05 +02:00
Matthias Clasen 1cc2b96e6b Merge branch 'matthiasc/for-main' into 'main'
gtk-builder-tool: Error out if screenshooting fails

See merge request GNOME/gtk!4649
2022-04-18 15:36:45 +00:00
Pablo Correa Gómez 314a75ed0f Set use_underline property for GtkCheckButton label conditionally
Otherwise, if the user set the property to False before creating or
setting the label, the label property will be overriden
2022-03-25 14:35:16 +01:00
919 changed files with 46040 additions and 1037427 deletions
+4 -2
View File
@@ -25,7 +25,7 @@ variables:
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v36"
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v38"
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
.only-default:
@@ -58,6 +58,7 @@ style-check-diff:
- "${CI_PROJECT_DIR}/_build/report*.xml"
- "${CI_PROJECT_DIR}/_build/report*.html"
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.png"
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*/*.node"
- "${CI_PROJECT_DIR}/_build/testsuite/tools/output/*/*"
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
@@ -172,7 +173,7 @@ macos:
needs: []
before_script:
- bash .gitlab-ci/show-info-osx.sh
- pip3 install --user meson==0.59
- pip3 install --user meson==0.60.3
- pip3 install --user ninja
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
- export MESON_FORCE_BACKTRACE=1
@@ -345,6 +346,7 @@ reference:
- _reference
publish-docs:
image: fedora:latest
stage: publish
needs: ['reference']
script:
+3
View File
@@ -14,6 +14,9 @@ Each Docker image has a tag composed of two parts:
See the [container registry][registry] for the available images for each
branch, as well as their available versions.
Note that using `latest` as version number will overwrite the most
recently uploaded image in the registry.
### Checklist for Updating a CI image
- [ ] Update the `${image}.Dockerfile` file with the dependencies
+1 -2
View File
@@ -1,4 +1,4 @@
FROM fedora:34
FROM fedora:36
RUN dnf -y install \
adwaita-icon-theme \
@@ -87,7 +87,6 @@ RUN dnf -y install \
python3-wheel \
redhat-rpm-config \
sassc \
systemtap-sdt-devel \
vulkan-devel \
wayland-devel \
wayland-protocols-devel \
+4
View File
@@ -185,6 +185,8 @@ ul.images li {
<li><img alt="ref" src="{{ failure.image_data.ref }}" /></li>
<li><img alt="out" src="{{ failure.image_data.out }}" /></li>
<li><img alt="diff" src="{{ failure.image_data.diff }}" /></li>
<li><a href="{{ failure.image_data.refnode }}">ref node</a></li>
<li><a href="{{ failure.image_data.outnode }}">out node</a></li>
</ul>
{% endif %}
</li>
@@ -311,6 +313,8 @@ for line in args.infile:
image_data = {
'ref': os.path.join(args.reftest_output_dir, '{}.ref.png'.format(basename)),
'out': os.path.join(args.reftest_output_dir, '{}.out.png'.format(basename)),
'refnode': os.path.join(args.reftest_output_dir, '{}.ref.node'.format(basename)),
'outnode': os.path.join(args.reftest_output_dir, '{}.out.node'.format(basename)),
'diff': os.path.join(args.reftest_output_dir, '{}.diff.png'.format(basename)),
}
+1 -1
View File
@@ -5,7 +5,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
@echo on
:: FIXME: make warnings fatal
pip3 install --upgrade --user meson==0.59 || goto :error
pip3 install --upgrade --user meson==0.60.3 || goto :error
meson -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error
ninja -C _build || goto :error
+1 -1
View File
@@ -28,7 +28,7 @@ pacman --noconfirm -S --needed \
mingw-w64-$MSYS2_ARCH-graphene \
mingw-w64-$MSYS2_ARCH-json-glib \
mingw-w64-$MSYS2_ARCH-libepoxy \
mingw-w64-$MSYS2_ARCH-pango \
mingw-w64-$MSYS2_ARCH-pango2 \
mingw-w64-$MSYS2_ARCH-fribidi \
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
mingw-w64-$MSYS2_ARCH-shared-mime-info \
+150
View File
@@ -1,3 +1,153 @@
Overview of Changes in 4.7.0, 07-05-2022
========================================
* GtkTextView:
- Reduce overdraws
* GtkViewport:
- Default scroll-to-focus to TRUE
* GtkText:
- Stop blinking when we lose focus
* GtkSearchEntry:
- Make search delay configurable
* GtkPopoverMenu:
- Fix RTL positioning of buttons
* GtkLabel:
- Fix focus keynav with links
* GtkFileChooser:
- Prevent undesirable completion popups
- Fix a corner case in save mode
- Keep the portal filechooser alive long enough
* GtkCheckButton:
- Allow setting a custom child
* GtkEditableLabel:
- Make the :editing property writable
* GtkColumnView:
- Various optimizations to improve scrolling performance
* GtkTreeStore:
- Allow populating tree stores from ui files
* GtkBoxLayout:
- Avoid infinite loops
* CSS:
- Optimize reordering within the same parent
* Emoji:
- Update to CLDR v40 / Unicode 14
- Add more locales
* Input:
- Add scroll unit handling
- Handle display changes in GtkIMMultiContext
- Always populate GDK_AXIS_X/Y in event history
- Don't crash for large compose tables
* Accessibility:
- Fix a crash at start when orca is running
* Theme:
- Refresh icons
- Fix selection in vertical spin buttons
- Fix selection in editable labels
* gdk:
- Optimize pixel format conversions
- Use EGL_KHR_swap_buffers_with_damage for NVidia
* gsk:
- Handle large viewports
- Prepare texture libraries for glyphy rendering
- Don't leak big glyphs in the glyph cache
- Align offscreen rendering with th pixel grid
- Check for half-float support before using it
* Wayland:
- Use xdg-activation protocol
- Fix text caret coordinates
- Fix on-screen keyboard activation
* MacOS:
- Fix sluggish and reversed scrolling
- Improve monitor detection
- Event handling fixes
- Fix keyboard input on popovers
- Support OpenGL-based video playback
- Suport fullscreen
- Improve native filechoooser size allocation
- Use CALayer and IOSurface for rendering
- Use a per-monitor CVDisplayLink
- Fix kinetic scrolling
- Improve window placement
- Improve multi-monitor handling
- Start applications in the foreground
- Fix cursor blink time
* Windows:
- Fix preedit window placement on HiDPI
* Tools:
- gtk4-builder-tool: Don't require a display for all commands
- gtk4-builder-tool: Add a screenshot command
- gtk4-node-editor: Install this utility
* Debugging:
- inspector: Show more application data
- inspector: Allow viewing PangoAttrList properties
* Documentation:
- Use the gtk-builder-tool to generate screenshots
* Build:
- Fix cross-compilation
- Fix build on aarch64
- Fix build with gcc 12
* Translation updates
Basque
Brazilian Portuguese
British English
Catalan
Chinese (China)
Chinese (Taiwan)
Croatian
Czech
Danish
Finnish
Galician
Georgian
German
Hebrew
Hungarian
Indonesian
Italian
Kazakh
Korean
Latvian
Lithuanian
Norwegian Bokmål
Persian
Polish
Portuguese
Russian
Serbian
Slovak
Slovenian
Spanish
Swedish
Turkish
Ukrainian
Overview of Changes in 4.6.1, 11-02-2022
========================================
File diff suppressed because it is too large Load Diff
+287
View File
@@ -0,0 +1,287 @@
#include "fontcolors.h"
#include "rangeedit.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
enum {
PROP_FONT_DESC = 1,
PROP_PALETTE,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _FontColors
{
GtkWidget parent;
GtkGrid *label;
GtkGrid *grid;
Pango2FontDescription *font_desc;
GSimpleAction *reset_action;
gboolean has_colors;
char *palette;
GtkCheckButton *default_check;
};
struct _FontColorsClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (FontColors, font_colors, GTK_TYPE_WIDGET);
static Pango2Font *
get_font (FontColors *self)
{
Pango2Context *context;
context = gtk_widget_get_pango_context (GTK_WIDGET (self));
return pango2_context_load_font (context, self->font_desc);
}
static void
palette_changed (GtkCheckButton *button,
FontColors *self)
{
g_free (self->palette);
self->palette = g_strdup ((const char *) g_object_get_data (G_OBJECT (button), "palette"));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PALETTE]);
}
static void
update_colors (FontColors *self)
{
Pango2Font *font;
hb_font_t *hb_font;
hb_face_t *hb_face;
GtkWidget *child;
GtkWidget *check;
unsigned int n_colors;
hb_color_t *colors;
GtkWidget *box;
g_object_ref (self->label);
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self->grid))))
gtk_grid_remove (self->grid, child);
gtk_grid_attach (self->grid, GTK_WIDGET (self->label), 0, -4, 2, 1);
g_object_unref (self->label);
self->default_check = NULL;
font = get_font (self);
hb_font = pango2_font_get_hb_font (font);
hb_face = hb_font_get_face (hb_font);
self->has_colors = hb_ot_color_has_palettes (hb_face);
gtk_widget_set_visible (GTK_WIDGET (self), self->has_colors);
if (!self->has_colors)
{
g_simple_action_set_enabled (self->reset_action, FALSE);
return;
}
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
gtk_grid_attach (self->grid, box, 0, -3, 2, 1);
check = gtk_check_button_new_with_label ("Default");
g_object_set_data (G_OBJECT (check), "palette", (gpointer)"default");
if (g_strcmp0 ("default", self->palette) == 0)
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
gtk_box_append (GTK_BOX (box), check);
self->default_check = GTK_CHECK_BUTTON (check);
check = gtk_check_button_new_with_label ("Light");
g_object_set_data (G_OBJECT (check), "palette", (gpointer)"light");
if (g_strcmp0 ("light", self->palette) == 0)
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
gtk_check_button_set_group (GTK_CHECK_BUTTON (check), self->default_check);
gtk_box_append (GTK_BOX (box), check);
check = gtk_check_button_new_with_label ("Dark");
g_object_set_data (G_OBJECT (check), "palette", (gpointer)"dark");
if (g_strcmp0 ("dark", self->palette) == 0)
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
gtk_check_button_set_group (GTK_CHECK_BUTTON (check), self->default_check);
gtk_box_append (GTK_BOX (box), check);
for (int i = 0; i < hb_ot_color_palette_get_count (hb_face); i++)
{
char *id = g_strdup_printf ("palette%d", i);
char *label = g_strdup_printf ("Palette %d", i);
GtkWidget *palette;
check = gtk_check_button_new_with_label (label);
g_object_set_data_full (G_OBJECT (check), "palette", id, g_free);
if (g_strcmp0 (id, self->palette) == 0)
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
gtk_check_button_set_group (GTK_CHECK_BUTTON (check), self->default_check);
gtk_grid_attach (self->grid, check, 0, i, 1, 1);
n_colors = hb_ot_color_palette_get_colors (hb_face, i, 0, NULL, NULL);
colors = g_new (hb_color_t, n_colors);
n_colors = hb_ot_color_palette_get_colors (hb_face, i, 0, &n_colors, colors);
palette = gtk_grid_new ();
gtk_widget_set_valign (palette, GTK_ALIGN_CENTER);
gtk_grid_attach (self->grid, palette, 1, i, 1, 1);
/* HACK - defeat first-child/last-child theming */
gtk_grid_attach (GTK_GRID (palette), gtk_picture_new (), -1, 0, 1, 1);
for (int k = 0; k < n_colors; k++)
{
GtkWidget *swatch;
swatch = g_object_new (g_type_from_name ("GtkColorSwatch"),
"rgba", &(GdkRGBA){ hb_color_get_red (colors[k])/255.,
hb_color_get_green (colors[k])/255.,
hb_color_get_blue (colors[k])/255.,
hb_color_get_alpha (colors[k])/255.},
"selectable", FALSE,
"has-menu", FALSE,
"can-drag", FALSE,
"width-request", 16,
"height-request", 16,
NULL);
gtk_grid_attach (GTK_GRID (palette), swatch, k % 6, k / 6, 1, 1);
}
/* HACK - defeat first-child/last-child theming */
gtk_grid_attach (GTK_GRID (palette), gtk_picture_new (), 6, 0, 1, 1);
}
}
static void
reset (GSimpleAction *action,
GVariant *parameter,
FontColors *self)
{
g_free (self->palette);
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
if (self->has_colors)
gtk_check_button_set_active (self->default_check, TRUE);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PALETTE]);
g_simple_action_set_enabled (self->reset_action, FALSE);
}
static void
font_colors_init (FontColors *self)
{
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
gtk_widget_init_template (GTK_WIDGET (self));
self->reset_action = g_simple_action_new ("reset", NULL);
g_simple_action_set_enabled (self->reset_action, FALSE);
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
}
static void
font_colors_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), FONT_COLORS_TYPE);
G_OBJECT_CLASS (font_colors_parent_class)->dispose (object);
}
static void
font_colors_finalize (GObject *object)
{
FontColors *self = FONT_COLORS (object);
g_clear_pointer (&self->font_desc, pango2_font_description_free);
g_free (self->palette);
G_OBJECT_CLASS (font_colors_parent_class)->finalize (object);
}
static void
font_colors_set_property (GObject *object,
unsigned int prop_id,
const GValue *value,
GParamSpec *pspec)
{
FontColors *self = FONT_COLORS (object);
switch (prop_id)
{
case PROP_FONT_DESC:
pango2_font_description_free (self->font_desc);
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
update_colors (self);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_colors_get_property (GObject *object,
unsigned int prop_id,
GValue *value,
GParamSpec *pspec)
{
FontColors *self = FONT_COLORS (object);
switch (prop_id)
{
case PROP_PALETTE:
g_value_set_string (value, self->palette);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_colors_class_init (FontColorsClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = font_colors_dispose;
object_class->finalize = font_colors_finalize;
object_class->get_property = font_colors_get_property;
object_class->set_property = font_colors_set_property;
properties[PROP_FONT_DESC] =
g_param_spec_boxed ("font-desc", "", "",
PANGO2_TYPE_FONT_DESCRIPTION,
G_PARAM_WRITABLE);
properties[PROP_PALETTE] =
g_param_spec_string ("palette", "", "",
PANGO2_COLOR_PALETTE_DEFAULT,
G_PARAM_READABLE);
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/fontcolors.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontColors, grid);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontColors, label);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontcolors");
}
FontColors *
font_colors_new (void)
{
return g_object_new (FONT_COLORS_TYPE, NULL);
}
GAction *
font_colors_get_reset_action (FontColors *self)
{
return G_ACTION (self->reset_action);
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <gtk/gtk.h>
#define FONT_COLORS_TYPE (font_colors_get_type ())
#define FONT_COLORS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_COLORS_TYPE, FontColors))
typedef struct _FontColors FontColors;
typedef struct _FontColorsClass FontColorsClass;
GType font_colors_get_type (void);
FontColors * font_colors_new (void);
GAction * font_colors_get_reset_action (FontColors *self);
+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="FontColors" parent="GtkWidget">
<property name="layout-manager"><object class="GtkBinLayout"/></property>
<child>
<object class="GtkGrid" id="grid">
<child>
<object class="GtkLabel" id="label">
<property name="label" translatable="yes">Colors</property>
<property name="margin-bottom">10</property>
<property name="xalign">0</property>
<style>
<class name="heading"/>
</style>
<layout>
<property name="row">-2</property>
<property name="column">0</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
</object>
</child>
</template>
</interface>
+271
View File
@@ -0,0 +1,271 @@
#include "fontcontrols.h"
#include "rangeedit.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
enum {
PROP_SIZE = 1,
PROP_LETTERSPACING,
PROP_LINE_HEIGHT,
PROP_FOREGROUND,
PROP_BACKGROUND,
PROP_DISABLE_SIZE,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _FontControls
{
GtkWidget parent;
GtkAdjustment *size_adjustment;
GtkAdjustment *letterspacing_adjustment;
GtkAdjustment *line_height_adjustment;
GtkColorButton *foreground;
GtkColorButton *background;
GSimpleAction *reset_action;
gboolean disable_size;
};
struct _FontControlsClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(FontControls, font_controls, GTK_TYPE_WIDGET);
static void
size_changed (GtkAdjustment *adjustment,
FontControls *self)
{
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SIZE]);
g_simple_action_set_enabled (self->reset_action, TRUE);
}
static void
letterspacing_changed (GtkAdjustment *adjustment,
FontControls *self)
{
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LETTERSPACING]);
g_simple_action_set_enabled (self->reset_action, TRUE);
}
static void
line_height_changed (GtkAdjustment *adjustment,
FontControls *self)
{
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LINE_HEIGHT]);
g_simple_action_set_enabled (self->reset_action, TRUE);
}
static void
color_set (GtkColorButton *button,
GParamSpec *pspec,
FontControls *self)
{
if (button == self->foreground)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FOREGROUND]);
else
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_BACKGROUND]);
g_simple_action_set_enabled (self->reset_action, TRUE);
}
static void
swap_colors (GtkButton *button,
FontControls *self)
{
GdkRGBA fg;
GdkRGBA bg;
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->foreground), &fg);
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->background), &bg);
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->foreground), &bg);
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->background), &fg);
}
static void
reset (GSimpleAction *action,
GVariant *parameter,
FontControls *self)
{
gtk_adjustment_set_value (self->size_adjustment, 12.);
gtk_adjustment_set_value (self->letterspacing_adjustment, 0.);
gtk_adjustment_set_value (self->line_height_adjustment, 1.);
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->foreground), &(GdkRGBA){0., 0., 0., 1.0 });
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->background), &(GdkRGBA){1., 1., 1., 1.0 });
g_simple_action_set_enabled (self->reset_action, FALSE);
}
static void
font_controls_init (FontControls *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
self->reset_action = g_simple_action_new ("reset", NULL);
g_simple_action_set_enabled (self->reset_action, FALSE);
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
}
static void
font_controls_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), FONT_CONTROLS_TYPE);
G_OBJECT_CLASS (font_controls_parent_class)->dispose (object);
}
static void
font_controls_finalize (GObject *object)
{
//FontControls *self = FONT_CONTROLS (object);
G_OBJECT_CLASS (font_controls_parent_class)->finalize (object);
}
static void
font_controls_set_property (GObject *object,
unsigned int prop_id,
const GValue *value,
GParamSpec *pspec)
{
FontControls *self = FONT_CONTROLS (object);
switch (prop_id)
{
case PROP_SIZE:
gtk_adjustment_set_value (self->size_adjustment, g_value_get_float (value));
break;
case PROP_DISABLE_SIZE:
self->disable_size = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_controls_get_property (GObject *object,
unsigned int prop_id,
GValue *value,
GParamSpec *pspec)
{
FontControls *self = FONT_CONTROLS (object);
switch (prop_id)
{
case PROP_SIZE:
g_value_set_float (value, gtk_adjustment_get_value (self->size_adjustment));
break;
case PROP_LETTERSPACING:
g_value_set_int (value, (int) gtk_adjustment_get_value (self->letterspacing_adjustment));
break;
case PROP_LINE_HEIGHT:
g_value_set_float (value, gtk_adjustment_get_value (self->line_height_adjustment));
break;
case PROP_FOREGROUND:
{
GdkRGBA rgba;
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->foreground), &rgba);
g_value_set_boxed (value, &rgba);
}
break;
case PROP_BACKGROUND:
{
GdkRGBA rgba;
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->background), &rgba);
g_value_set_boxed (value, &rgba);
}
break;
case PROP_DISABLE_SIZE:
g_value_set_boolean (value, self->disable_size);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_controls_class_init (FontControlsClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
g_type_ensure (RANGE_EDIT_TYPE);
object_class->dispose = font_controls_dispose;
object_class->finalize = font_controls_finalize;
object_class->get_property = font_controls_get_property;
object_class->set_property = font_controls_set_property;
properties[PROP_SIZE] =
g_param_spec_float ("size", "", "",
0., 100., 12.,
G_PARAM_READABLE);
properties[PROP_LETTERSPACING] =
g_param_spec_int ("letterspacing", "", "",
-G_MAXINT, G_MAXINT, 0,
G_PARAM_READABLE);
properties[PROP_LINE_HEIGHT] =
g_param_spec_float ("line-height", "", "",
0., 100., 1.,
G_PARAM_READABLE);
properties[PROP_FOREGROUND] =
g_param_spec_boxed ("foreground", "", "",
GDK_TYPE_RGBA,
G_PARAM_READABLE);
properties[PROP_BACKGROUND] =
g_param_spec_boxed ("background", "", "",
GDK_TYPE_RGBA,
G_PARAM_READABLE);
properties[PROP_DISABLE_SIZE] =
g_param_spec_boolean ("disable-size", "", "",
FALSE,
G_PARAM_READWRITE);
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/fontcontrols.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, size_adjustment);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, letterspacing_adjustment);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, line_height_adjustment);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, foreground);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, background);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), size_changed);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), letterspacing_changed);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), line_height_changed);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), color_set);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), swap_colors);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontcontrols");
}
FontControls *
font_controls_new (void)
{
return g_object_new (FONT_CONTROLS_TYPE, NULL);
}
GAction *
font_controls_get_reset_action (FontControls *self)
{
return G_ACTION (self->reset_action);
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <gtk/gtk.h>
#define FONT_CONTROLS_TYPE (font_controls_get_type ())
#define FONT_CONTROLS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_CONTROLS_TYPE, FontControls))
typedef struct _FontControls FontControls;
typedef struct _FontControlsClass FontControlsClass;
GType font_controls_get_type (void);
FontControls * font_controls_new (void);
GAction * font_controls_get_reset_action (FontControls *self);
+175
View File
@@ -0,0 +1,175 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="FontControls" parent="GtkWidget">
<property name="layout-manager"><object class="GtkGridLayout"/></property>
<child>
<object class="GtkLabel">
<property name="sensitive" bind-source="FontControls" bind-property="disable-size" bind-flags="invert-boolean"/>
<property name="label">Size</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="RangeEdit">
<property name="sensitive" bind-source="FontControls" bind-property="disable-size" bind-flags="invert-boolean"/>
<property name="hexpand">1</property>
<property name="width-request">160</property>
<property name="valign">baseline</property>
<property name="adjustment">
<object class="GtkAdjustment" id="size_adjustment">
<property name="lower">7</property>
<property name="upper">100</property>
<property name="value">14</property>
<property name="step_increment">0.5</property>
<property name="page_increment">10</property>
<signal name="value-changed" handler="size_changed"/>
</object>
</property>
<property name="default-value">12</property>
<property name="n-chars">5</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Letterspacing</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="RangeEdit">
<property name="hexpand">1</property>
<property name="width-request">160</property>
<property name="valign">baseline</property>
<property name="adjustment">
<object class="GtkAdjustment" id="letterspacing_adjustment">
<property name="lower">-1024</property>
<property name="upper">8192</property>
<property name="value">0</property>
<property name="step_increment">1</property>
<property name="page_increment">512</property>
<signal name="value-changed" handler="letterspacing_changed"/>
</object>
</property>
<property name="default-value">0</property>
<property name="n-chars">5</property>
<layout>
<property name="column">1</property>
<property name="row">1</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Line Height</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="RangeEdit">
<property name="hexpand">1</property>
<property name="width-request">160</property>
<property name="valign">baseline</property>
<property name="adjustment">
<object class="GtkAdjustment" id="line_height_adjustment">
<property name="lower">0.75</property>
<property name="upper">2.5</property>
<property name="value">1.0</property>
<property name="step_increment">0.1</property>
<property name="page_increment">1</property>
<signal name="value-changed" handler="line_height_changed"/>
</object>
</property>
<property name="default-value">1</property>
<property name="n-chars">5</property>
<layout>
<property name="column">1</property>
<property name="row">2</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Foreground</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkColorButton" id="foreground">
<property name="rgba">black</property>
<signal name="notify::rgba" handler="color_set"/>
<layout>
<property name="column">1</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Background</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkColorButton" id="background">
<property name="rgba">white</property>
<signal name="notify::rgba" handler="color_set"/>
<layout>
<property name="column">1</property>
<property name="row">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">object-flip-vertical-symbolic</property>
<property name="halign">start</property>
<property name="valign">center</property>
<style>
<class name="circular"/>
</style>
<signal name="clicked" handler="swap_colors"/>
<layout>
<property name="column">2</property>
<property name="row">3</property>
<property name="row-span">2</property>
</layout>
</object>
</child>
</template>
</interface>
+20
View File
@@ -0,0 +1,20 @@
box.sidebar {
padding: 20px;
border-spacing: 20px;
}
fontcontrols {
border-spacing: 10px;
}
fontvariations > grid {
border-spacing: 10px;
}
fontcolors > grid {
border-spacing: 10px;
}
samplechooser {
border-spacing: 10px;
}
fontview {
padding: 10px;
border-spacing: 10px;
}
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gtk/fontexplorer">
<file preprocess="xml-stripblanks">fontexplorerwin.ui</file>
<file preprocess="xml-stripblanks">fontview.ui</file>
<file preprocess="xml-stripblanks">fontcontrols.ui</file>
<file preprocess="xml-stripblanks">samplechooser.ui</file>
<file preprocess="xml-stripblanks">fontcolors.ui</file>
<file preprocess="xml-stripblanks">fontfeatures.ui</file>
<file preprocess="xml-stripblanks">fontvariations.ui</file>
<file preprocess="xml-stripblanks">rangeedit.ui</file>
<file>fontexplorer.css</file>
</gresource>
</gresources>
+165
View File
@@ -0,0 +1,165 @@
#include "config.h"
#include <gtk/gtk.h>
#include "fontexplorerapp.h"
#include "fontexplorerwin.h"
#include "demo_conf.h"
struct _FontExplorerApp
{
GtkApplication parent;
};
struct _FontExplorerAppClass
{
GtkApplicationClass parent_class;
};
G_DEFINE_TYPE(FontExplorerApp, font_explorer_app, GTK_TYPE_APPLICATION);
static void
font_explorer_app_init (FontExplorerApp *app)
{
}
static void
quit_activated (GSimpleAction *action,
GVariant *parameter,
gpointer app)
{
g_application_quit (G_APPLICATION (app));
}
static void
inspector_activated (GSimpleAction *action,
GVariant *parameter,
gpointer app)
{
gtk_window_set_interactive_debugging (TRUE);
}
static void
about_activated (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkApplication *app = user_data;
const char *authors[] = {
"The GTK Team",
NULL
};
char *icon_theme;
char *version;
GString *s;
char *os_name;
char *os_version;
g_object_get (gtk_settings_get_default (),
"gtk-icon-theme-name", &icon_theme,
NULL);
s = g_string_new ("");
os_name = g_get_os_info (G_OS_INFO_KEY_NAME);
os_version = g_get_os_info (G_OS_INFO_KEY_VERSION_ID);
if (os_name && os_version)
g_string_append_printf (s, "OS\t%s %s\n\n", os_name, os_version);
g_string_append (s, "System libraries\n");
g_string_append_printf (s, "\tGLib\t%d.%d.%d\n",
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (s, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ());
g_string_append_printf (s, "\nIcon theme\n\t%s", icon_theme);
version = g_strdup_printf ("%s%s%s\nRunning against GTK %d.%d.%d",
PACKAGE_VERSION,
g_strcmp0 (PROFILE, "devel") == 0 ? "-" : "",
g_strcmp0 (PROFILE, "devel") == 0 ? VCS_TAG : "",
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ());
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
"program-name", g_strcmp0 (PROFILE, "devel") == 0
? "GTK Font Explorer (Development)"
: "GTK Font Explorer",
"version", version,
"copyright", "© 1997—2021 The GTK Team",
"license-type", GTK_LICENSE_LGPL_2_1,
"website", "http://www.gtk.org",
"comments", "Program to explore font features",
"authors", authors,
"logo-icon-name", "org.gtk.FontExplorer",
"title", "About GTK Font Explorer",
"system-information", s->str,
NULL);
g_string_free (s, TRUE);
g_free (version);
g_free (icon_theme);
g_free (os_name);
g_free (os_version);
}
static GActionEntry app_entries[] =
{
{ "quit", quit_activated, NULL, NULL, NULL },
{ "inspector", inspector_activated, NULL, NULL, NULL },
{ "about", about_activated, NULL, NULL, NULL }
};
static void
font_explorer_app_startup (GApplication *app)
{
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
GtkCssProvider *provider;
G_APPLICATION_CLASS (font_explorer_app_parent_class)->startup (app);
g_action_map_add_action_entries (G_ACTION_MAP (app),
app_entries, G_N_ELEMENTS (app_entries),
app);
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"app.quit",
quit_accels);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/org/gtk/fontexplorer/fontexplorer.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
static void
font_explorer_app_activate (GApplication *app)
{
FontExplorerWindow *win;
win = font_explorer_window_new (FONT_EXPLORER_APP (app));
if (g_strcmp0 (PROFILE, "devel") == 0)
gtk_widget_add_css_class (GTK_WIDGET (win), "devel");
gtk_window_present (GTK_WINDOW (win));
}
static void
font_explorer_app_class_init (FontExplorerAppClass *class)
{
G_APPLICATION_CLASS (class)->startup = font_explorer_app_startup;
G_APPLICATION_CLASS (class)->activate = font_explorer_app_activate;
}
FontExplorerApp *
font_explorer_app_new (void)
{
return g_object_new (FONT_EXPLORER_APP_TYPE,
"application-id", "org.gtk.FontExplorer",
NULL);
}
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <gtk/gtk.h>
#define FONT_EXPLORER_APP_TYPE (font_explorer_app_get_type ())
#define FONT_EXPLORER_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_EXPLORER_APP_TYPE, FontExplorerApp))
typedef struct _FontExplorerApp FontExplorerApp;
typedef struct _FontExplorerAppClass FontExplorerAppClass;
GType font_explorer_app_get_type (void);
FontExplorerApp * font_explorer_app_new (void);
+131
View File
@@ -0,0 +1,131 @@
#include "fontexplorerapp.h"
#include "fontexplorerwin.h"
#include "fontview.h"
#include "fontcontrols.h"
#include "samplechooser.h"
#include "fontcolors.h"
#include "fontfeatures.h"
#include "fontvariations.h"
#include <gtk/gtk.h>
#include <string.h>
struct _FontExplorerWindow
{
GtkApplicationWindow parent;
GtkFontButton *fontbutton;
FontControls *controls;
FontFeatures *features;
FontVariations *variations;
FontColors *colors;
FontView *view;
};
struct _FontExplorerWindowClass
{
GtkApplicationWindowClass parent_class;
};
G_DEFINE_TYPE(FontExplorerWindow, font_explorer_window, GTK_TYPE_APPLICATION_WINDOW);
static void
reset (GSimpleAction *action,
GVariant *parameter,
FontExplorerWindow *win)
{
g_action_activate (font_controls_get_reset_action (win->controls), NULL);
g_action_activate (font_features_get_reset_action (win->features), NULL);
g_action_activate (font_variations_get_reset_action (win->variations), NULL);
g_action_activate (font_colors_get_reset_action (win->colors), NULL);
}
static void
update_reset (GSimpleAction *action,
GParamSpec *pspec,
FontExplorerWindow *win)
{
gboolean enabled;
GAction *reset_action;
enabled = g_action_get_enabled (font_controls_get_reset_action (win->controls)) ||
g_action_get_enabled (font_features_get_reset_action (win->features)) ||
g_action_get_enabled (font_variations_get_reset_action (win->variations)) ||
g_action_get_enabled (font_colors_get_reset_action (win->colors));
reset_action = g_action_map_lookup_action (G_ACTION_MAP (win), "reset");
g_simple_action_set_enabled (G_SIMPLE_ACTION (reset_action), enabled);
}
static void
font_explorer_window_init (FontExplorerWindow *win)
{
GSimpleAction *reset_action;
gtk_widget_init_template (GTK_WIDGET (win));
reset_action = g_simple_action_new ("reset", NULL);
g_signal_connect (reset_action, "activate", G_CALLBACK (reset), win);
g_signal_connect (font_controls_get_reset_action (win->controls),
"notify::enabled", G_CALLBACK (update_reset), win);
g_signal_connect (font_variations_get_reset_action (win->variations),
"notify::enabled", G_CALLBACK (update_reset), win);
g_signal_connect (font_colors_get_reset_action (win->colors),
"notify::enabled", G_CALLBACK (update_reset), win);
g_signal_connect (font_features_get_reset_action (win->features),
"notify::enabled", G_CALLBACK (update_reset), win);
g_action_map_add_action (G_ACTION_MAP (win), G_ACTION (reset_action));
update_reset (NULL, NULL, win);
}
static void
font_explorer_window_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), FONT_EXPLORER_WINDOW_TYPE);
G_OBJECT_CLASS (font_explorer_window_parent_class)->dispose (object);
}
static void
font_explorer_window_finalize (GObject *object)
{
// FontExplorerWindow *win = FONT_EXPLORER_WINDOW (object);
G_OBJECT_CLASS (font_explorer_window_parent_class)->finalize (object);
}
static void
font_explorer_window_class_init (FontExplorerWindowClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
g_type_ensure (FONT_VIEW_TYPE);
g_type_ensure (FONT_CONTROLS_TYPE);
g_type_ensure (SAMPLE_CHOOSER_TYPE);
g_type_ensure (FONT_VARIATIONS_TYPE);
g_type_ensure (FONT_COLORS_TYPE);
g_type_ensure (FONT_FEATURES_TYPE);
object_class->dispose = font_explorer_window_dispose;
object_class->finalize = font_explorer_window_finalize;
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/fontexplorerwin.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, fontbutton);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, controls);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, variations);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, colors);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, features);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, view);
}
FontExplorerWindow *
font_explorer_window_new (FontExplorerApp *app)
{
return g_object_new (FONT_EXPLORER_WINDOW_TYPE, "application", app, NULL);
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <gtk/gtk.h>
#include "fontexplorerapp.h"
#define FONT_EXPLORER_WINDOW_TYPE (font_explorer_window_get_type ())
#define FONT_EXPLORER_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_EXPLORER_WINDOW_TYPE, FontExplorerWindow))
typedef struct _FontExplorerWindow FontExplorerWindow;
typedef struct _FontExplorerWindowClass FontExplorerWindowClass;
GType font_explorer_window_get_type (void);
FontExplorerWindow * font_explorer_window_new (FontExplorerApp *app);
+100
View File
@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="gear_menu">
<section>
<item>
<attribute name="label" translatable="yes">_Inspector</attribute>
<attribute name="action">app.inspector</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_About GTK Font Explorer</attribute>
<attribute name="action">app.about</attribute>
</item>
</section>
</menu>
<template class="FontExplorerWindow" parent="GtkApplicationWindow">
<property name="title" translatable="yes">Font Explorer</property>
<property name="default-width">1024</property>
<property name="default-height">768</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child>
<object class="GtkButton" id="reset">
<property name="receives-default">1</property>
<property name="tooltip-text">Reset</property>
<property name="icon-name">view-refresh-symbolic</property>
<property name="action-name">win.reset</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="gear_menu_button">
<property name="focus-on-click">0</property>
<property name="valign">center</property>
<property name="menu-model">gear_menu</property>
<property name="icon-name">open-menu-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<style>
<class name="sidebar"/>
</style>
<child>
<object class="GtkFontButton" id="fontbutton">
<property name="level">family|style</property>
</object>
</child>
<child>
<object class="FontControls" id="controls">
<property name="disable-size" bind-source="view" bind-property="ignore-size" bind-flags="sync-create"/>
</object>
</child>
<child>
<object class="SampleChooser" id="samplechooser"/>
</child>
<child>
<object class="FontVariations" id="variations">
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
</object>
</child>
<child>
<object class="FontFeatures" id="features">
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
<property name="language" bind-source="fontbutton" bind-flags="sync-create"/>
</object>
</child>
<child>
<object class="FontColors" id="colors">
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="FontView" id="view">
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
<property name="size" bind-source="controls" bind-flags="sync-create"/>
<property name="letterspacing" bind-source="controls" bind-flags="sync-create"/>
<property name="line-height" bind-source="controls" bind-flags="sync-create"/>
<property name="foreground" bind-source="controls" bind-flags="sync-create"/>
<property name="background" bind-source="controls" bind-flags="sync-create"/>
<property name="sample-text" bind-source="samplechooser" bind-flags="sync-create"/>
<property name="features" bind-source="features" bind-flags="sync-create"/>
<property name="variations" bind-source="variations" bind-flags="sync-create"/>
<property name="palette" bind-source="colors" bind-flags="sync-create"/>
</object>
</child>
</object>
</child>
</template>
</interface>
+727
View File
@@ -0,0 +1,727 @@
#include "fontfeatures.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
#include <glib/gi18n.h>
#include "open-type-layout.h"
#include "language-names.h"
enum {
PROP_FONT_DESC = 1,
PROP_LANGUAGE,
PROP_FEATURES,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
typedef struct {
unsigned int tag;
const char *name;
GtkWidget *feat;
} FeatureItem;
struct _FontFeatures
{
GtkWidget parent;
GtkGrid *label;
GtkGrid *grid;
Pango2FontDescription *font_desc;
GSimpleAction *reset_action;
Pango2Language *lang;
GList *feature_items;
};
struct _FontFeaturesClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(FontFeatures, font_features, GTK_TYPE_WIDGET);
static Pango2Font *
get_font (FontFeatures *self)
{
Pango2Context *context;
context = gtk_widget_get_pango_context (GTK_WIDGET (self));
return pango2_context_load_font (context, self->font_desc);
}
static gboolean
is_ssNN (const char *buf)
{
return g_str_has_prefix (buf, "ss") && g_ascii_isdigit (buf[2]) && g_ascii_isdigit (buf[3]);
}
static gboolean
is_cvNN (const char *buf)
{
return g_str_has_prefix (buf, "cv") && g_ascii_isdigit (buf[2]) && g_ascii_isdigit (buf[3]);
}
static char *
get_feature_display_name (unsigned int tag)
{
int i;
static char buf[5] = { 0, };
if (tag == HB_TAG ('x', 'x', 'x', 'x'))
return g_strdup (_("Default"));
hb_tag_to_string (tag, buf);
if (is_ssNN (buf))
{
int num = (buf[2] - '0') * 10 + (buf[3] - '0');
return g_strdup_printf (g_dpgettext2 (NULL, "OpenType layout", "Stylistic Set %d"), num);
}
else if (is_cvNN (buf))
{
int num = (buf[2] - '0') * 10 + (buf[3] - '0');
return g_strdup_printf (g_dpgettext2 (NULL, "OpenType layout", "Character Variant %d"), num);
}
for (i = 0; i < G_N_ELEMENTS (open_type_layout_features); i++)
{
if (tag == open_type_layout_features[i].tag)
return g_strdup (g_dpgettext2 (NULL, "OpenType layout", open_type_layout_features[i].name));
}
g_warning ("unknown OpenType layout feature tag: %s", buf);
return g_strdup (buf);
}
static void
update_feature_label (FontFeatures *self,
FeatureItem *item,
hb_font_t *hb_font,
hb_tag_t script_tag,
hb_tag_t lang_tag)
{
hb_face_t *hb_face;
unsigned int script_index, lang_index, feature_index;
hb_ot_name_id_t id;
unsigned int len;
char *label;
char name[5] = { 0, };
hb_face = hb_font_get_face (hb_font);
hb_tag_to_string (item->tag, name);
if (!is_ssNN (name) && !is_cvNN (name))
return;
hb_ot_layout_table_find_script (hb_face, HB_OT_TAG_GSUB, script_tag, &script_index);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
hb_ot_layout_script_find_language (hb_face, HB_OT_TAG_GSUB, script_index, lang_tag, &lang_index);
G_GNUC_END_IGNORE_DEPRECATIONS
if (hb_ot_layout_language_find_feature (hb_face, HB_OT_TAG_GSUB, script_index, lang_index, item->tag, &feature_index) &&
hb_ot_layout_feature_get_name_ids (hb_face, HB_OT_TAG_GSUB, feature_index, &id, NULL, NULL, NULL, NULL))
{
len = hb_ot_name_get_utf8 (hb_face, id, HB_LANGUAGE_INVALID, NULL, NULL);
len++;
label = g_new (char, len);
hb_ot_name_get_utf8 (hb_face, id, HB_LANGUAGE_INVALID, &len, label);
gtk_check_button_set_label (GTK_CHECK_BUTTON (item->feat), label);
g_free (label);
}
else
{
label = get_feature_display_name (item->tag);
gtk_check_button_set_label (GTK_CHECK_BUTTON (item->feat), label);
g_free (label);
}
}
static void
set_inconsistent (GtkCheckButton *button,
gboolean inconsistent)
{
gtk_check_button_set_inconsistent (GTK_CHECK_BUTTON (button), inconsistent);
gtk_widget_set_opacity (gtk_widget_get_first_child (GTK_WIDGET (button)), inconsistent ? 0.0 : 1.0);
}
static void
find_language_and_script (FontFeatures *self,
hb_face_t *hb_face,
hb_tag_t *lang_tag,
hb_tag_t *script_tag)
{
int i, j, k;
hb_tag_t scripts[80];
unsigned int n_scripts;
unsigned int count;
hb_tag_t table[2] = { HB_OT_TAG_GSUB, HB_OT_TAG_GPOS };
hb_language_t lang;
const char *langname, *p;
langname = pango2_language_to_string (self->lang);
p = strchr (langname, '-');
lang = hb_language_from_string (langname, p ? p - langname : -1);
n_scripts = 0;
for (i = 0; i < 2; i++)
{
count = G_N_ELEMENTS (scripts);
hb_ot_layout_table_get_script_tags (hb_face, table[i], n_scripts, &count, scripts);
n_scripts += count;
}
for (j = 0; j < n_scripts; j++)
{
hb_tag_t languages[80];
unsigned int n_languages;
n_languages = 0;
for (i = 0; i < 2; i++)
{
count = G_N_ELEMENTS (languages);
hb_ot_layout_script_get_language_tags (hb_face, table[i], j, n_languages, &count, languages);
n_languages += count;
}
for (k = 0; k < n_languages; k++)
{
if (lang == hb_ot_tag_to_language (languages[k]))
{
*script_tag = scripts[j];
*lang_tag = languages[k];
return;
}
}
}
*lang_tag = HB_OT_TAG_DEFAULT_LANGUAGE;
*script_tag = HB_OT_TAG_DEFAULT_SCRIPT;
}
static void
hide_feature_maybe (FeatureItem *item,
gboolean has_feature)
{
gtk_widget_set_visible (item->feat, has_feature);
if (has_feature)
gtk_widget_set_visible (gtk_widget_get_parent (item->feat), TRUE);
}
/* Make features insensitive if the font/langsys does not have them,
* and reset all others to their initial value
*/
static void
update_features (FontFeatures *self)
{
guint script_index, lang_index;
hb_tag_t lang_tag;
hb_tag_t script_tag;
Pango2Font *font;
hb_font_t *hb_font;
hb_face_t *hb_face;
font = get_font (self);
hb_font = pango2_font_get_hb_font (font);
hb_face = hb_font_get_face (hb_font);
{
hb_tag_t table[2] = { HB_OT_TAG_GSUB, HB_OT_TAG_GPOS };
hb_tag_t features[256];
unsigned int count;
unsigned int n_features = 0;
find_language_and_script (self, hb_face, &lang_tag, &script_tag);
/* Collect all features */
for (int i = 0; i < 2; i++)
{
hb_ot_layout_table_find_script (hb_face,
table[i],
script_tag,
&script_index);
hb_ot_layout_script_select_language (hb_face,
table[i],
script_index,
1,
&lang_tag,
&lang_index);
count = G_N_ELEMENTS (features);
hb_ot_layout_language_get_feature_tags (hb_face,
table[i],
script_index,
lang_index,
n_features,
&count,
features);
n_features += count;
}
/* Update all the features */
for (GList *l = self->feature_items; l; l = l->next)
{
FeatureItem *item = l->data;
gboolean has_feature = FALSE;
for (int j = 0; j < n_features; j++)
{
if (item->tag == features[j])
{
has_feature = TRUE;
break;
}
}
update_feature_label (self, item, hb_font, script_tag, lang_tag);
hide_feature_maybe (item, has_feature);
if (GTK_IS_CHECK_BUTTON (item->feat))
{
GtkWidget *def = GTK_WIDGET (g_object_get_data (G_OBJECT (item->feat), "default"));
if (def)
{
gtk_widget_show (def);
gtk_widget_show (gtk_widget_get_parent (def));
gtk_check_button_set_active (GTK_CHECK_BUTTON (def), TRUE);
}
else
set_inconsistent (GTK_CHECK_BUTTON (item->feat), TRUE);
}
}
}
/* Hide empty groups */
for (GList *l = self->feature_items; l; l = l->next)
{
FeatureItem *item = l->data;
GtkWidget *box;
box = gtk_widget_get_parent (item->feat);
if (gtk_widget_get_visible (box))
{
GtkWidget *c;
int count;
count = 0;
for (c = gtk_widget_get_first_child (box); c; c = gtk_widget_get_next_sibling (c))
{
if (gtk_widget_get_visible (c))
count++;
}
if (count == 1)
gtk_widget_hide (box);
else if (count == 2 &&
item->tag == HB_TAG ('x', 'x', 'x', 'x'))
gtk_widget_hide (box);
}
}
}
static void
script_changed (GtkComboBox *combo,
FontFeatures *self)
{
update_features (self);
}
static char *
get_features (FontFeatures *self)
{
GString *s;
char buf[128];
s = g_string_new ("");
for (GList *l = self->feature_items; l; l = l->next)
{
FeatureItem *item = l->data;
if (!gtk_widget_is_sensitive (item->feat))
continue;
if (GTK_IS_CHECK_BUTTON (item->feat) && g_object_get_data (G_OBJECT (item->feat), "default"))
{
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat)) &&
item->tag != HB_TAG ('x', 'x', 'x', 'x'))
{
hb_feature_to_string (&(hb_feature_t) { item->tag, 1, 0, -1 }, buf, sizeof (buf));
if (s->len > 0)
g_string_append_c (s, ',');
g_string_append (s, buf);
}
}
else if (GTK_IS_CHECK_BUTTON (item->feat))
{
guint32 value;
if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (item->feat)))
continue;
value = gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat));
hb_feature_to_string (&(hb_feature_t) { item->tag, value, 0, -1 }, buf, sizeof (buf));
if (s->len > 0)
g_string_append_c (s, ',');
g_string_append (s, buf);
}
}
return g_string_free (s, FALSE);
}
static void
update_display (FontFeatures *self)
{
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FEATURES]);
g_simple_action_set_enabled (self->reset_action, TRUE);
}
static GtkWidget *
make_title_label (const char *title)
{
GtkWidget *label;
label = gtk_label_new (title);
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_widget_set_halign (label, GTK_ALIGN_START);
g_object_set (label, "margin-top", 10, "margin-bottom", 10, NULL);
gtk_widget_add_css_class (label, "heading");
return label;
}
static void
feat_toggled_cb (GtkCheckButton *check_button,
gpointer data)
{
set_inconsistent (check_button, FALSE);
}
static void
feat_pressed (GtkGestureClick *gesture,
int n_press,
double x,
double y,
GtkWidget *feat)
{
const guint button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
if (button == GDK_BUTTON_PRIMARY)
{
g_signal_handlers_block_by_func (feat, feat_pressed, NULL);
if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat)))
{
set_inconsistent (GTK_CHECK_BUTTON (feat), FALSE);
gtk_check_button_set_active (GTK_CHECK_BUTTON (feat), TRUE);
}
g_signal_handlers_unblock_by_func (feat, feat_pressed, NULL);
}
else if (button == GDK_BUTTON_SECONDARY)
{
gboolean inconsistent = gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat));
set_inconsistent (GTK_CHECK_BUTTON (feat), !inconsistent);
}
}
static void
add_check_group (FontFeatures *self,
const char *title,
const char **tags,
unsigned int n_tags,
int row)
{
GtkWidget *group;
int i;
group = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_halign (group, GTK_ALIGN_START);
gtk_box_append (GTK_BOX (group), make_title_label (title));
for (i = 0; i < n_tags; i++)
{
unsigned int tag;
GtkWidget *feat;
FeatureItem *item;
GtkGesture *gesture;
char *name;
tag = hb_tag_from_string (tags[i], -1);
name = get_feature_display_name (tag);
feat = gtk_check_button_new_with_label (name);
g_free (name);
set_inconsistent (GTK_CHECK_BUTTON (feat), TRUE);
g_signal_connect_swapped (feat, "notify::active", G_CALLBACK (update_display), self);
g_signal_connect_swapped (feat, "notify::inconsistent", G_CALLBACK (update_display), self);
g_signal_connect (feat, "toggled", G_CALLBACK (feat_toggled_cb), NULL);
gesture = gtk_gesture_click_new ();
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
g_signal_connect (gesture, "pressed", G_CALLBACK (feat_pressed), feat);
gtk_widget_add_controller (feat, GTK_EVENT_CONTROLLER (gesture));
gtk_box_append (GTK_BOX (group), feat);
item = g_new (FeatureItem, 1);
item->name = tags[i];
item->tag = tag;
item->feat = feat;
self->feature_items = g_list_prepend (self->feature_items, item);
}
gtk_grid_attach (self->grid, group, 0, row, 2, 1);
}
static void
add_radio_group (FontFeatures *self,
const char *title,
const char **tags,
unsigned int n_tags,
int row)
{
GtkWidget *group;
int i;
GtkWidget *group_button = NULL;
group = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_halign (group, GTK_ALIGN_START);
gtk_box_append (GTK_BOX (group), make_title_label (title));
for (i = 0; i < n_tags; i++)
{
unsigned int tag;
GtkWidget *feat;
FeatureItem *item;
char *name;
tag = hb_tag_from_string (tags[i], -1);
name = get_feature_display_name (tag);
feat = gtk_check_button_new_with_label (name ? name : _("Default"));
g_free (name);
if (group_button == NULL)
group_button = feat;
else
gtk_check_button_set_group (GTK_CHECK_BUTTON (feat), GTK_CHECK_BUTTON (group_button));
g_signal_connect_swapped (feat, "notify::active", G_CALLBACK (update_display), self);
g_object_set_data (G_OBJECT (feat), "default", group_button);
gtk_box_append (GTK_BOX (group), feat);
item = g_new (FeatureItem, 1);
item->name = tags[i];
item->tag = tag;
item->feat = feat;
self->feature_items = g_list_prepend (self->feature_items, item);
}
gtk_grid_attach (self->grid, group, 0, row, 2, 1);
}
static void
setup_features (FontFeatures *self)
{
const char *kerning[] = { "kern" };
const char *ligatures[] = { "liga", "dlig", "hlig", "clig", "rlig" };
const char *letter_case[] = {
"smcp", "c2sc", "pcap", "c2pc", "unic", "cpsp", "case"
};
const char *number_case[] = { "xxxx", "lnum", "onum" };
const char *number_spacing[] = { "xxxx", "pnum", "tnum" };
const char *fractions[] = { "xxxx", "frac", "afrc" };
const char *num_extras[] = { "zero", "nalt", "sinf" };
const char *char_alt[] = {
"swsh", "cswh", "locl", "calt", "falt", "hist",
"salt", "jalt", "titl", "rand", "subs", "sups",
"ordn", "ltra", "ltrm", "rtla", "rtlm", "rclt"
};
const char *pos_alt[] = {
"init", "medi", "med2", "fina", "fin2", "fin3", "isol"
};
const char *width_var[] = {
"fwid", "hwid", "halt", "pwid", "palt", "twid", "qwid"
};
const char *style_alt[] = {
"ss01", "ss02", "ss03", "ss04", "ss05", "ss06",
"ss07", "ss08", "ss09", "ss10", "ss11", "ss12",
"ss13", "ss14", "ss15", "ss16", "ss17", "ss18",
"ss19", "ss20"
};
const char *char_var[] = {
"cv01", "cv02", "cv03", "cv04", "cv05", "cv06",
"cv07", "cv08", "cv09", "cv10", "cv11", "cv12",
"cv13", "cv14", "cv15", "cv16", "cv17", "cv18",
"cv19", "cv20"
};
const char *math[] = { "dtls", "flac", "mgrk", "ssty" };
const char *bounds[] = { "opbd", "lfbd", "rtbd" };
int row = 0;
add_check_group (self, _("Kerning"), kerning, G_N_ELEMENTS (kerning), row++);
add_check_group (self, _("Ligatures"), ligatures, G_N_ELEMENTS (ligatures), row++);
add_check_group (self, _("Letter Case"), letter_case, G_N_ELEMENTS (letter_case), row++);
add_radio_group (self, _("Number Case"), number_case, G_N_ELEMENTS (number_case), row++);
add_radio_group (self, _("Number Spacing"), number_spacing, G_N_ELEMENTS (number_spacing), row++);
add_radio_group (self, _("Fractions"), fractions, G_N_ELEMENTS (fractions), row++);
add_check_group (self, _("Numeric Extras"), num_extras, G_N_ELEMENTS (num_extras), row++);
add_check_group (self, _("Character Alternatives"), char_alt, G_N_ELEMENTS (char_alt), row++);
add_check_group (self, _("Positional Alternatives"), pos_alt, G_N_ELEMENTS (pos_alt), row++);
add_check_group (self, _("Width Variants"), width_var, G_N_ELEMENTS (width_var), row++);
add_check_group (self, _("Alternative Stylistic Sets"), style_alt, G_N_ELEMENTS (style_alt), row++);
add_check_group (self, _("Character Variants"), char_var, G_N_ELEMENTS (char_var), row++);
add_check_group (self, _("Mathematical"), math, G_N_ELEMENTS (math), row++);
add_check_group (self, _("Optical Bounds"), bounds, G_N_ELEMENTS (bounds), row++);
self->feature_items = g_list_reverse (self->feature_items);
}
static void
reset (GSimpleAction *action,
GVariant *parameter,
FontFeatures *self)
{
update_features (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FEATURES]);
g_simple_action_set_enabled (self->reset_action, FALSE);
}
static void
font_features_init (FontFeatures *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
self->font_desc = pango2_font_description_from_string ("sans 12");
self->lang = pango2_language_get_default ();
setup_features (self);
self->reset_action = g_simple_action_new ("reset", NULL);
g_simple_action_set_enabled (self->reset_action, FALSE);
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
}
static void
font_features_dispose (GObject *object)
{
FontFeatures *self = FONT_FEATURES (object);
gtk_widget_clear_template (GTK_WIDGET (object), FONT_FEATURES_TYPE);
g_list_free_full (self->feature_items, g_free);
G_OBJECT_CLASS (font_features_parent_class)->dispose (object);
}
static void
font_features_finalize (GObject *object)
{
FontFeatures *self = FONT_FEATURES (object);
g_clear_pointer (&self->font_desc, pango2_font_description_free);
G_OBJECT_CLASS (font_features_parent_class)->finalize (object);
}
static void
font_features_set_property (GObject *object,
unsigned int prop_id,
const GValue *value,
GParamSpec *pspec)
{
FontFeatures *self = FONT_FEATURES (object);
switch (prop_id)
{
case PROP_FONT_DESC:
pango2_font_description_free (self->font_desc);
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
update_features (self);
break;
case PROP_LANGUAGE:
self->lang = pango2_language_from_string (g_value_get_string (value));
update_features (self);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_features_get_property (GObject *object,
unsigned int prop_id,
GValue *value,
GParamSpec *pspec)
{
FontFeatures *self = FONT_FEATURES (object);
switch (prop_id)
{
case PROP_FEATURES:
g_value_take_string (value, get_features (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_features_class_init (FontFeaturesClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = font_features_dispose;
object_class->finalize = font_features_finalize;
object_class->get_property = font_features_get_property;
object_class->set_property = font_features_set_property;
properties[PROP_FONT_DESC] =
g_param_spec_boxed ("font-desc", "", "",
PANGO2_TYPE_FONT_DESCRIPTION,
G_PARAM_WRITABLE);
properties[PROP_LANGUAGE] =
g_param_spec_string ("language", "", "",
"en",
G_PARAM_WRITABLE);
properties[PROP_FEATURES] =
g_param_spec_string ("features", "", "",
"",
G_PARAM_READABLE);
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/fontfeatures.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontFeatures, grid);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontFeatures, label);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), script_changed);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontfeatures");
}
FontFeatures *
font_features_new (void)
{
return g_object_new (FONT_FEATURES_TYPE, NULL);
}
GAction *
font_features_get_reset_action (FontFeatures *self)
{
return G_ACTION (self->reset_action);
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <gtk/gtk.h>
#define FONT_FEATURES_TYPE (font_features_get_type ())
#define FONT_FEATURES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_FEATURES_TYPE, FontFeatures))
typedef struct _FontFeatures FontFeatures;
typedef struct _FontFeaturesClass FontFeaturesClass;
GType font_features_get_type (void);
FontFeatures * font_features_new (void);
GAction * font_features_get_reset_action (FontFeatures *self);
+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="FontFeatures" parent="GtkWidget">
<property name="layout-manager"><object class="GtkBinLayout"/></property>
<child>
<object class="GtkGrid" id="grid">
<child>
<object class="GtkLabel" id="label">
<property name="label" translatable="yes">Features</property>
<property name="margin-bottom">10</property>
<property name="xalign">0</property>
<style>
<class name="heading"/>
</style>
<layout>
<property name="row">-1</property>
<property name="column">0</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
</object>
</child>
</template>
</interface>
+488
View File
@@ -0,0 +1,488 @@
#include "fontvariations.h"
#include "rangeedit.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
enum {
PROP_FONT_DESC = 1,
PROP_VARIATIONS,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _FontVariations
{
GtkWidget parent;
GtkGrid *label;
GtkGrid *grid;
Pango2FontDescription *font_desc;
GSimpleAction *reset_action;
gboolean has_variations;
GtkWidget *instance_combo;
GHashTable *axes;
GHashTable *instances;
};
struct _FontVariationsClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(FontVariations, font_variations, GTK_TYPE_WIDGET);
static Pango2Font *
get_font (FontVariations *self)
{
Pango2Context *context;
context = gtk_widget_get_pango_context (GTK_WIDGET (self));
return pango2_context_load_font (context, self->font_desc);
}
typedef struct {
guint32 tag;
GtkAdjustment *adjustment;
double default_value;
} Axis;
static guint
axes_hash (gconstpointer v)
{
const Axis *p = v;
return p->tag;
}
static gboolean
axes_equal (gconstpointer v1, gconstpointer v2)
{
const Axis *p1 = v1;
const Axis *p2 = v2;
return p1->tag == p2->tag;
}
static void
unset_instance (GtkAdjustment *adjustment,
FontVariations *self)
{
if (self->instance_combo)
gtk_combo_box_set_active (GTK_COMBO_BOX (self->instance_combo), 0);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
g_simple_action_set_enabled (self->reset_action, TRUE);
}
static void
add_axis (FontVariations *self,
hb_face_t *hb_face,
hb_ot_var_axis_info_t *ax,
int i)
{
GtkWidget *axis_label;
GtkWidget *axis_scale;
GtkAdjustment *adjustment;
Axis *axis;
char name[20];
unsigned int name_len = 20;
hb_ot_name_get_utf8 (hb_face, ax->name_id, HB_LANGUAGE_INVALID, &name_len, name);
axis_label = gtk_label_new (name);
gtk_widget_set_halign (axis_label, GTK_ALIGN_START);
gtk_widget_set_valign (axis_label, GTK_ALIGN_BASELINE);
gtk_grid_attach (self->grid, axis_label, 0, i, 1, 1);
adjustment = gtk_adjustment_new (ax->default_value, ax->min_value, ax->max_value,
1.0, 10.0, 0.0);
axis_scale = g_object_new (RANGE_EDIT_TYPE,
"adjustment", adjustment,
"default-value", ax->default_value,
"n-chars", 5,
"hexpand", TRUE,
"halign", GTK_ALIGN_FILL,
"valign", GTK_ALIGN_BASELINE,
NULL);
gtk_grid_attach (self->grid, axis_scale, 1, i, 1, 1);
axis = g_new0 (Axis, 1);
axis->tag = ax->tag;
axis->adjustment = adjustment;
axis->default_value = ax->default_value;
g_hash_table_add (self->axes, axis);
g_signal_connect (adjustment, "value-changed", G_CALLBACK (unset_instance), self);
}
typedef struct {
char *name;
unsigned int index;
} Instance;
static guint
instance_hash (gconstpointer v)
{
const Instance *p = v;
return g_str_hash (p->name);
}
static gboolean
instance_equal (gconstpointer v1, gconstpointer v2)
{
const Instance *p1 = v1;
const Instance *p2 = v2;
return g_str_equal (p1->name, p2->name);
}
static void
free_instance (gpointer data)
{
Instance *instance = data;
g_free (instance->name);
g_free (instance);
}
static void
add_instance (FontVariations *self,
hb_face_t *face,
unsigned int index,
GtkWidget *combo,
int pos)
{
Instance *instance;
hb_ot_name_id_t name_id;
char name[20];
unsigned int name_len = 20;
instance = g_new0 (Instance, 1);
name_id = hb_ot_var_named_instance_get_subfamily_name_id (face, index);
hb_ot_name_get_utf8 (face, name_id, HB_LANGUAGE_INVALID, &name_len, name);
instance->name = g_strdup (name);
instance->index = index;
g_hash_table_add (self->instances, instance);
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), instance->name);
}
static void
instance_changed (GtkComboBox *combo,
FontVariations *self)
{
char *text;
Instance *instance;
Instance ikey;
int i;
unsigned int coords_length;
float *coords = NULL;
hb_ot_var_axis_info_t *ai = NULL;
unsigned int n_axes;
Pango2Font *font = NULL;
hb_font_t *hb_font;
hb_face_t *hb_face;
text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo));
if (text[0] == '\0')
goto out;
ikey.name = text;
instance = g_hash_table_lookup (self->instances, &ikey);
if (!instance)
{
g_print ("did not find instance %s\n", text);
goto out;
}
font = get_font (self);
hb_font = pango2_font_get_hb_font (font);
hb_face = hb_font_get_face (hb_font);
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
ai = g_new (hb_ot_var_axis_info_t, n_axes);
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, ai);
coords = g_new (float, n_axes);
hb_ot_var_named_instance_get_design_coords (hb_face,
instance->index,
&coords_length,
coords);
for (i = 0; i < n_axes; i++)
{
Axis *axis;
Axis akey;
double value;
value = coords[ai[i].axis_index];
akey.tag = ai[i].tag;
axis = g_hash_table_lookup (self->axes, &akey);
if (axis)
{
g_signal_handlers_block_by_func (axis->adjustment, unset_instance, self);
gtk_adjustment_set_value (axis->adjustment, value);
g_signal_handlers_unblock_by_func (axis->adjustment, unset_instance, self);
}
}
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
g_simple_action_set_enabled (self->reset_action, TRUE);
out:
g_free (text);
g_clear_object (&font);
g_free (ai);
g_free (coords);
}
static void
update_variations (FontVariations *self)
{
GtkWidget *child;
Pango2Font *font;
hb_font_t *hb_font;
hb_face_t *hb_face;
unsigned int n_axes;
hb_ot_var_axis_info_t *ai = NULL;
int i;
font = get_font (self);
hb_font = pango2_font_get_hb_font (font);
hb_face = hb_font_get_face (hb_font);
g_object_ref (self->label);
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self->grid))))
gtk_grid_remove (self->grid, child);
gtk_grid_attach (self->grid, GTK_WIDGET (self->label), 0, -2, 2, 1);
g_object_unref (self->label);
self->instance_combo = NULL;
g_hash_table_remove_all (self->axes);
g_hash_table_remove_all (self->instances);
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
self->has_variations = n_axes > 0;
gtk_widget_set_visible (GTK_WIDGET (self), self->has_variations);
if (!self->has_variations)
{
g_simple_action_set_enabled (self->reset_action, FALSE);
return;
}
if (hb_ot_var_get_named_instance_count (hb_face) > 0)
{
GtkWidget *label;
GtkWidget *combo;
label = gtk_label_new ("Instance");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
gtk_grid_attach (self->grid, label, 0, -1, 1, 1);
combo = gtk_combo_box_text_new ();
gtk_widget_set_halign (combo, GTK_ALIGN_START);
gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE);
gtk_widget_set_hexpand (combo, TRUE);
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "");
for (i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
add_instance (self, hb_face, i, combo, i);
gtk_grid_attach (GTK_GRID (self->grid), combo, 1, -1, 1, 1);
g_signal_connect (combo, "changed", G_CALLBACK (instance_changed), self);
self->instance_combo = combo;
}
ai = g_new (hb_ot_var_axis_info_t, n_axes);
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, ai);
for (i = 0; i < n_axes; i++)
add_axis (self, hb_face, &ai[i], i);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
g_clear_object (&font);
g_free (ai);
}
static char *
get_variations (FontVariations *self)
{
GHashTableIter iter;
Axis *axis;
char buf[G_ASCII_DTOSTR_BUF_SIZE];
const char *sep = "";
GString *s;
if (!self->has_variations)
return g_strdup ("");
s = g_string_new ("");
g_hash_table_iter_init (&iter, self->axes);
while (g_hash_table_iter_next (&iter, (gpointer *)NULL, (gpointer *)&axis))
{
char tag[5];
double value;
hb_tag_to_string (axis->tag, tag);
tag[4] = '\0';
value = gtk_adjustment_get_value (axis->adjustment);
g_string_append_printf (s, "%s%s=%s", sep, tag, g_ascii_dtostr (buf, sizeof (buf), value));
sep = ",";
}
return g_string_free (s, FALSE);
}
static void
reset (GSimpleAction *action,
GVariant *parameter,
FontVariations *self)
{
GHashTableIter iter;
Axis *axis;
if (self->instance_combo)
gtk_combo_box_set_active (GTK_COMBO_BOX (self->instance_combo), 0);
g_hash_table_iter_init (&iter, self->axes);
while (g_hash_table_iter_next (&iter, (gpointer *)NULL, (gpointer *)&axis))
{
g_signal_handlers_block_by_func (axis->adjustment, unset_instance, self);
gtk_adjustment_set_value (axis->adjustment, axis->default_value);
g_signal_handlers_unblock_by_func (axis->adjustment, unset_instance, self);
}
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
g_simple_action_set_enabled (self->reset_action, FALSE);
}
static void
font_variations_init (FontVariations *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
self->reset_action = g_simple_action_new ("reset", NULL);
g_simple_action_set_enabled (self->reset_action, FALSE);
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
self->instances = g_hash_table_new_full (instance_hash, instance_equal,
NULL, free_instance);
self->axes = g_hash_table_new_full (axes_hash, axes_equal,
NULL, g_free);
}
static void
font_variations_dispose (GObject *object)
{
FontVariations *self = FONT_VARIATIONS (object);
gtk_widget_clear_template (GTK_WIDGET (object), FONT_VARIATIONS_TYPE);
g_hash_table_unref (self->instances);
g_hash_table_unref (self->axes);
G_OBJECT_CLASS (font_variations_parent_class)->dispose (object);
}
static void
font_variations_finalize (GObject *object)
{
FontVariations *self = FONT_VARIATIONS (object);
g_clear_pointer (&self->font_desc, pango2_font_description_free);
G_OBJECT_CLASS (font_variations_parent_class)->finalize (object);
}
static void
font_variations_set_property (GObject *object,
unsigned int prop_id,
const GValue *value,
GParamSpec *pspec)
{
FontVariations *self = FONT_VARIATIONS (object);
switch (prop_id)
{
case PROP_FONT_DESC:
pango2_font_description_free (self->font_desc);
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
update_variations (self);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_variations_get_property (GObject *object,
unsigned int prop_id,
GValue *value,
GParamSpec *pspec)
{
FontVariations *self = FONT_VARIATIONS (object);
switch (prop_id)
{
case PROP_VARIATIONS:
g_value_take_string (value, get_variations (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_variations_class_init (FontVariationsClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = font_variations_dispose;
object_class->finalize = font_variations_finalize;
object_class->get_property = font_variations_get_property;
object_class->set_property = font_variations_set_property;
properties[PROP_FONT_DESC] =
g_param_spec_boxed ("font-desc", "", "",
PANGO2_TYPE_FONT_DESCRIPTION,
G_PARAM_WRITABLE);
properties[PROP_VARIATIONS] =
g_param_spec_string ("variations", "", "",
"",
G_PARAM_READABLE);
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/fontvariations.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontVariations, grid);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontVariations, label);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontvariations");
}
FontVariations *
font_variations_new (void)
{
return g_object_new (FONT_VARIATIONS_TYPE, NULL);
}
GAction *
font_variations_get_reset_action (FontVariations *self)
{
return G_ACTION (self->reset_action);
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <gtk/gtk.h>
#define FONT_VARIATIONS_TYPE (font_variations_get_type ())
#define FONT_VARIATIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_VARIATIONS_TYPE, FontVariations))
typedef struct _FontVariations FontVariations;
typedef struct _FontVariationsClass FontVariationsClass;
GType font_variations_get_type (void);
FontVariations * font_variations_new (void);
GAction * font_variations_get_reset_action (FontVariations *self);
+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="FontVariations" parent="GtkWidget">
<property name="layout-manager"><object class="GtkBinLayout"/></property>
<child>
<object class="GtkGrid" id="grid">
<child>
<object class="GtkLabel" id="label">
<property name="label" translatable="yes">Variations</property>
<property name="margin-bottom">10</property>
<property name="xalign">0</property>
<style>
<class name="heading"/>
</style>
<layout>
<property name="row">-2</property>
<property name="column">0</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
</object>
</child>
</template>
</interface>
+413
View File
@@ -0,0 +1,413 @@
#include "fontview.h"
#include <gtk/gtk.h>
enum {
PROP_FONT_DESC = 1,
PROP_SIZE,
PROP_LETTERSPACING,
PROP_LINE_HEIGHT,
PROP_FOREGROUND,
PROP_BACKGROUND,
PROP_VARIATIONS,
PROP_FEATURES,
PROP_PALETTE,
PROP_SAMPLE_TEXT,
PROP_IGNORE_SIZE,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _FontView
{
GtkWidget parent;
GtkStack *stack;
GtkTextView *edit;
GtkLabel *content;
GtkScrolledWindow *swin;
Pango2FontDescription *font_desc;
float size;
char *variations;
char *features;
char *palette;
int letterspacing;
float line_height;
GdkRGBA foreground;
GdkRGBA background;
GtkCssProvider *bg_provider;
char *sample_text;
gboolean do_waterfall;
};
struct _FontViewClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(FontView, font_view, GTK_TYPE_WIDGET);
static void
font_view_init (FontView *self)
{
self->font_desc = pango2_font_description_from_string ("sans 12");
self->size = 12.;
self->letterspacing = 0;
self->line_height = 1.;
self->variations = g_strdup ("");
self->features = g_strdup ("");
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
self->foreground = (GdkRGBA){0., 0., 0., 1. };
self->background = (GdkRGBA){1., 1., 1., 1. };
self->sample_text = g_strdup ("Some sample text is better than other sample text");
gtk_widget_set_layout_manager (GTK_WIDGET (self),
gtk_box_layout_new (GTK_ORIENTATION_VERTICAL));
gtk_widget_init_template (GTK_WIDGET (self));
self->bg_provider = gtk_css_provider_new ();
gtk_style_context_add_provider (gtk_widget_get_style_context (GTK_WIDGET (self->content)),
GTK_STYLE_PROVIDER (self->bg_provider), 800);
}
static void
font_view_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), FONT_VIEW_TYPE);
G_OBJECT_CLASS (font_view_parent_class)->dispose (object);
}
static void
font_view_finalize (GObject *object)
{
FontView *self = FONT_VIEW (object);
pango2_font_description_free (self->font_desc);
g_free (self->variations);
g_free (self->features);
g_free (self->palette);
G_OBJECT_CLASS (font_view_parent_class)->finalize (object);
}
static void
update_view (FontView *self)
{
Pango2FontDescription *desc;
Pango2AttrList *attrs;
char *fg, *bg, *css;
desc = pango2_font_description_copy_static (self->font_desc);
pango2_font_description_set_size (desc, 12 * PANGO2_SCALE);
pango2_font_description_set_variations (desc, self->variations);
attrs = pango2_attr_list_new ();
pango2_attr_list_insert (attrs, pango2_attr_font_desc_new (desc));
pango2_attr_list_insert (attrs, pango2_attr_size_new (self->size * PANGO2_SCALE));
pango2_attr_list_insert (attrs, pango2_attr_letter_spacing_new (self->letterspacing));
pango2_attr_list_insert (attrs, pango2_attr_line_height_new (self->line_height));
pango2_attr_list_insert (attrs, pango2_attr_foreground_new (&(Pango2Color){65535 * self->foreground.red,
65535 * self->foreground.green,
65535 * self->foreground.blue,
65535 * self->foreground.alpha}));
pango2_attr_list_insert (attrs, pango2_attr_font_features_new (self->features));
pango2_attr_list_insert (attrs, pango2_attr_palette_new (self->palette));
pango2_font_description_free (desc);
gtk_scrolled_window_set_policy (self->swin,
self->do_waterfall ? GTK_POLICY_AUTOMATIC : GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
gtk_label_set_wrap (self->content, !self->do_waterfall);
if (self->do_waterfall)
{
GString *str;
int sizes[] = { 7, 8, 9, 10, 12, 14, 16, 20, 24, 30, 40, 50, 60, 70, 90 };
int start, text_len;
str = g_string_new ("");
start = 0;
text_len = strlen (self->sample_text);
for (int i = 0; i < G_N_ELEMENTS (sizes); i++)
{
Pango2Attribute *attr;
g_string_append (str, self->sample_text);
g_string_append (str, ""); /* Unicode line separator */
attr = pango2_attr_size_new (sizes[i] * PANGO2_SCALE);
pango2_attribute_set_range (attr, start, start + text_len);
pango2_attr_list_insert (attrs, attr);
start += text_len + strlen ("");
}
gtk_label_set_text (self->content, str->str);
gtk_label_set_attributes (self->content, attrs);
g_string_free (str, TRUE);
}
else
{
gtk_label_set_label (self->content, self->sample_text);
gtk_label_set_attributes (self->content, attrs);
}
pango2_attr_list_unref (attrs);
fg = gdk_rgba_to_string (&self->foreground);
bg = gdk_rgba_to_string (&self->background);
css = g_strdup_printf (".view_background { caret-color: %s; background-color: %s; }", fg, bg);
gtk_css_provider_load_from_data (self->bg_provider, css, strlen (css));
g_free (css);
g_free (fg);
g_free (bg);
}
static void
toggle_edit (GtkToggleButton *button,
FontView *self)
{
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer (self->edit);
if (gtk_toggle_button_get_active (button))
{
gtk_text_buffer_set_text (buffer, self->sample_text, -1);
gtk_stack_set_visible_child_name (self->stack, "edit");
gtk_widget_grab_focus (GTK_WIDGET (self->edit));
}
else
{
GtkTextIter start, end;
g_free (self->sample_text);
gtk_text_buffer_get_bounds (buffer, &start, &end);
self->sample_text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
update_view (self);
gtk_stack_set_visible_child_name (self->stack, "content");
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
}
}
static void
waterfall_changed (GtkToggleButton *button,
GParamSpec *pspec,
FontView *self)
{
self->do_waterfall = gtk_toggle_button_get_active (button);
update_view (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_IGNORE_SIZE]);
}
static void
font_view_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
FontView *self = FONT_VIEW (object);
switch (prop_id)
{
case PROP_FONT_DESC:
pango2_font_description_free (self->font_desc);
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
break;
case PROP_SIZE:
self->size = g_value_get_float (value);
break;
case PROP_LETTERSPACING:
self->letterspacing = g_value_get_int (value);
break;
case PROP_LINE_HEIGHT:
self->line_height = g_value_get_float (value);
break;
case PROP_FOREGROUND:
self->foreground = *(GdkRGBA *)g_value_get_boxed (value);
break;
case PROP_BACKGROUND:
self->background = *(GdkRGBA *)g_value_get_boxed (value);
break;
case PROP_VARIATIONS:
g_free (self->variations);
self->variations = g_strdup (g_value_get_string (value));
break;
case PROP_FEATURES:
g_free (self->features);
self->features = g_strdup (g_value_get_string (value));
break;
case PROP_PALETTE:
g_free (self->palette);
self->palette = g_strdup (g_value_get_string (value));
break;
case PROP_SAMPLE_TEXT:
g_free (self->sample_text);
self->sample_text = g_strdup (g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
update_view (self);
}
static void
font_view_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
FontView *self = FONT_VIEW (object);
switch (prop_id)
{
case PROP_FONT_DESC:
g_value_set_boxed (value, self->font_desc);
break;
case PROP_SIZE:
g_value_set_float (value, self->size);
break;
case PROP_LETTERSPACING:
g_value_set_int (value, self->letterspacing);
break;
case PROP_LINE_HEIGHT:
g_value_set_float (value, self->line_height);
break;
case PROP_FOREGROUND:
g_value_set_boxed (value, &self->foreground);
break;
case PROP_BACKGROUND:
g_value_set_boxed (value, &self->background);
break;
case PROP_VARIATIONS:
g_value_set_string (value, self->variations);
break;
case PROP_FEATURES:
g_value_set_string (value, self->features);
break;
case PROP_PALETTE:
g_value_set_string (value, self->palette);
break;
case PROP_SAMPLE_TEXT:
g_value_set_string (value, self->sample_text);
break;
case PROP_IGNORE_SIZE:
g_value_set_boolean (value, self->do_waterfall);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_view_class_init (FontViewClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = font_view_dispose;
object_class->finalize = font_view_finalize;
object_class->get_property = font_view_get_property;
object_class->set_property = font_view_set_property;
properties[PROP_FONT_DESC] =
g_param_spec_boxed ("font-desc", "", "",
PANGO2_TYPE_FONT_DESCRIPTION,
G_PARAM_READWRITE);
properties[PROP_SIZE] =
g_param_spec_float ("size", "", "",
0., 100., 12.,
G_PARAM_READWRITE);
properties[PROP_LETTERSPACING] =
g_param_spec_int ("letterspacing", "", "",
-G_MAXINT, G_MAXINT, 0,
G_PARAM_READWRITE);
properties[PROP_LINE_HEIGHT] =
g_param_spec_float ("line-height", "", "",
0., 100., 1.,
G_PARAM_READWRITE);
properties[PROP_FOREGROUND] =
g_param_spec_boxed ("foreground", "", "",
GDK_TYPE_RGBA,
G_PARAM_READWRITE);
properties[PROP_BACKGROUND] =
g_param_spec_boxed ("background", "", "",
GDK_TYPE_RGBA,
G_PARAM_READWRITE);
properties[PROP_VARIATIONS] =
g_param_spec_string ("variations", "", "",
"",
G_PARAM_READWRITE);
properties[PROP_FEATURES] =
g_param_spec_string ("features", "", "",
"",
G_PARAM_READWRITE);
properties[PROP_PALETTE] =
g_param_spec_string ("palette", "", "",
PANGO2_COLOR_PALETTE_DEFAULT,
G_PARAM_READWRITE);
properties[PROP_SAMPLE_TEXT] =
g_param_spec_string ("sample-text", "", "",
"",
G_PARAM_READWRITE);
properties[PROP_IGNORE_SIZE] =
g_param_spec_boolean ("ignore-size", "", "",
FALSE,
G_PARAM_READWRITE);
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/fontview.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontView, swin);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontView, content);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontView, stack);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontView, edit);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), toggle_edit);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), waterfall_changed);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontview");
}
FontView *
font_view_new (void)
{
return g_object_new (FONT_VIEW_TYPE, NULL);
}
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <gtk/gtk.h>
#define FONT_VIEW_TYPE (font_view_get_type ())
#define FONT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_VIEW_TYPE, FontView))
typedef struct _FontView FontView;
typedef struct _FontViewClass FontViewClass;
GType font_view_get_type (void);
FontView * font_view_new (void);
+91
View File
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="FontView" parent="GtkWidget">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<style>
<class name="view"/>
</style>
<child>
<object class="GtkStack" id="stack">
<child>
<object class="GtkStackPage">
<property name="name">content</property>
<property name="child">
<object class="GtkScrolledWindow" id="swin">
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<child>
<object class="GtkLabel" id="content">
<property name="label">ContentContent</property>
<property name="wrap">1</property>
<property name="wrap-mode">word-char</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">fill</property>
<property name="valign">fill</property>
<style>
<class name="view_background"/>
</style>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">edit</property>
<property name="child">
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<child>
<object class="GtkTextView" id="edit">
<property name="wrap-mode">word-char</property>
</object>
</child>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<child>
<object class="GtkBox">
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkToggleButton" id="plain_toggle">
<property name="label" translatable="yes">Plain</property>
<property name="active">1</property>
</object>
</child>
<child>
<object class="GtkToggleButton" id="waterfall_toggle">
<property name="label" translatable="yes">Waterfall</property>
<property name="group">plain_toggle</property>
<signal name="notify::active" handler="waterfall_changed"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToggleButton">
<property name="icon-name">document-edit-symbolic</property>
<property name="tooltip-text" translatable="yes">Edit the sample</property>
<property name="halign">end</property>
<property name="valign">end</property>
<property name="hexpand">1</property>
<signal name="clicked" handler="toggle_edit"/>
</object>
</child>
</object>
</child>
</template>
</interface>
+336
View File
@@ -0,0 +1,336 @@
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <errno.h>
#include <locale.h>
#include <sys/stat.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <hb-ot.h>
#include "language-names.h"
#ifdef G_OS_WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#ifndef ISO_CODES_PREFIX
#define ISO_CODES_PREFIX "/usr"
#endif
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
#endif
static GHashTable *language_map;
#ifdef G_OS_WIN32
/* if we are using native Windows use native Windows API for language names */
static BOOL CALLBACK
get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
{
wchar_t *langname_w = NULL;
wchar_t locale_abbrev_w[9];
gchar *langname, *locale_abbrev, *locale, *p;
gint i;
const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 };
GHashTable *ht_scripts_langs = (GHashTable *) param;
Pango2Language *lang;
gint langname_size, locale_abbrev_size;
langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0);
if (langname_size == 0)
return FALSE;
langname_w = g_new0 (wchar_t, langname_size);
if (langname_size == 0)
return FALSE;
GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, langname_size);
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
p = strchr (locale, '-');
lang = pango2_language_from_string (locale);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);
/*
* Track 3+-letter ISO639-2/3 language codes as well (these have a max length of 9 including terminating NUL)
* ISO639-2: iso639_lctypes[0] = LOCALE_SISO639LANGNAME
* ISO639-3: iso639_lctypes[1] = LOCALE_SISO639LANGNAME2
*/
for (i = 0; i < 2; i++)
{
locale_abbrev_size = GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, 0);
if (locale_abbrev_size > 0)
{
GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size);
locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL);
lang = pango2_language_from_string (locale_abbrev);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);
g_free (locale_abbrev);
}
}
g_free (locale);
g_free (langname_w);
return TRUE;
}
#else /* non-Windows */
static char *
get_first_item_in_semicolon_list (const char *list)
{
char **items;
char *item;
items = g_strsplit (list, "; ", 2);
item = g_strdup (items[0]);
g_strfreev (items);
return item;
}
static char *
capitalize_utf8_string (const char *str)
{
char first[8] = { 0 };
if (!str)
return NULL;
g_unichar_to_utf8 (g_unichar_totitle (g_utf8_get_char (str)), first);
return g_strconcat (first, g_utf8_offset_to_pointer (str, 1), NULL);
}
static char *
get_display_name (const char *language)
{
const char *translated;
char *tmp;
char *name;
translated = dgettext ("iso_639", language);
tmp = get_first_item_in_semicolon_list (translated);
name = capitalize_utf8_string (tmp);
g_free (tmp);
return name;
}
static void
languages_parse_start_tag (GMarkupParseContext *ctx,
const char *element_name,
const char **attr_names,
const char **attr_values,
gpointer user_data,
GError **error)
{
const char *ccode_longB;
const char *ccode_longT;
const char *ccode;
const char *ccode_id;
const char *lang_name;
char *display_name;
const char *long_names[] = {
"Dogri",
"Greek, Modern",
"Interlingua",
"Konkani",
"Tonga",
"Turkish, Ottoman",
};
int i;
if (!(g_str_equal (element_name, "iso_639_entry") ||
g_str_equal (element_name, "iso_639_3_entry")) ||
attr_names == NULL ||
attr_values == NULL)
return;
ccode = NULL;
ccode_longB = NULL;
ccode_longT = NULL;
ccode_id = NULL;
lang_name = NULL;
while (*attr_names && *attr_values)
{
if (g_str_equal (*attr_names, "iso_639_1_code"))
{
if (**attr_values)
{
if (strlen (*attr_values) != 2)
return;
ccode = *attr_values;
}
}
else if (g_str_equal (*attr_names, "iso_639_2B_code"))
{
if (**attr_values)
{
if (strlen (*attr_values) != 3)
return;
ccode_longB = *attr_values;
}
}
else if (g_str_equal (*attr_names, "iso_639_2T_code"))
{
if (**attr_values)
{
if (strlen (*attr_values) != 3)
return;
ccode_longT = *attr_values;
}
}
else if (g_str_equal (*attr_names, "id"))
{
if (**attr_values)
{
if (strlen (*attr_values) != 2 &&
strlen (*attr_values) != 3)
return;
ccode_id = *attr_values;
}
}
else if (g_str_equal (*attr_names, "name"))
{
lang_name = *attr_values;
}
++attr_names;
++attr_values;
}
if (lang_name == NULL)
return;
display_name = get_display_name (lang_name);
/* Fix up some egregious names */
for (i = 0; i < G_N_ELEMENTS (long_names); i++)
{
if (g_str_has_prefix (display_name, long_names[i]))
display_name[strlen (long_names[i])] = '\0';
}
if (ccode != NULL)
g_hash_table_insert (language_map,
pango2_language_from_string (ccode),
g_strdup (display_name));
if (ccode_longB != NULL)
g_hash_table_insert (language_map,
pango2_language_from_string (ccode_longB),
g_strdup (display_name));
if (ccode_longT != NULL)
g_hash_table_insert (language_map,
pango2_language_from_string (ccode_longT),
g_strdup (display_name));
if (ccode_id != NULL)
g_hash_table_insert (language_map,
pango2_language_from_string (ccode_id),
g_strdup (display_name));
g_free (display_name);
}
static void
languages_variant_init (const char *variant)
{
gboolean res;
gsize buf_len;
char *buf;
char *filename;
GError *error;
bindtextdomain (variant, ISO_CODES_LOCALESDIR);
bind_textdomain_codeset (variant, "UTF-8");
error = NULL;
filename = g_strconcat (ISO_CODES_DATADIR, "/", variant, ".xml", NULL);
res = g_file_get_contents (filename, &buf, &buf_len, &error);
if (res)
{
GMarkupParseContext *ctx = NULL;
GMarkupParser parser = { languages_parse_start_tag, NULL, NULL, NULL, NULL };
ctx = g_markup_parse_context_new (&parser, 0, NULL, NULL);
res = g_markup_parse_context_parse (ctx, buf, buf_len, &error);
g_free (ctx);
if (!res)
{
g_warning ("Failed to parse '%s': %s\n", filename, error->message);
g_error_free (error);
}
}
else
{
g_warning ("Failed to load '%s': %s\n", filename, error->message);
g_error_free (error);
}
g_free (filename);
g_free (buf);
}
#endif
static void
languages_init (void)
{
if (language_map)
return;
language_map = g_hash_table_new_full (NULL, NULL, NULL, g_free);
#ifdef G_OS_WIN32
g_return_if_fail (EnumSystemLocalesEx (&get_win32_all_locales_scripts, LOCALE_ALL, (LPARAM) language_map, NULL));
#else
languages_variant_init ("iso_639");
languages_variant_init ("iso_639_3");
#endif
}
const char *
get_language_name (Pango2Language *language)
{
languages_init ();
return (const char *) g_hash_table_lookup (language_map, language);
}
const char *
get_language_name_for_tag (guint32 tag)
{
hb_language_t lang;
const char *s;
lang = hb_ot_tag_to_language (tag);
s = hb_language_to_string (lang);
return get_language_name (pango2_language_from_string (s));
}
+13
View File
@@ -0,0 +1,13 @@
#ifndef LANGUAGE_NAMES_H
#define LANGUAGE_NAMES_H
#include <pango2/pango.h>
G_BEGIN_DECLS
const char * get_language_name (Pango2Language *language);
const char * get_language_name_for_tag (guint32 tag);
G_END_DECLS
#endif
+8
View File
@@ -0,0 +1,8 @@
#include <gtk/gtk.h>
#include <fontexplorerapp.h>
int
main (int argc, char *argv[])
{
return g_application_run (G_APPLICATION (font_explorer_app_new ()), argc, argv);
}
+27
View File
@@ -0,0 +1,27 @@
fontexplorer_sources = [
'main.c',
'fontexplorerapp.c',
'fontexplorerwin.c',
'fontcontrols.c',
'samplechooser.c',
'fontcolors.c',
'fontfeatures.c',
'fontvariations.c',
'fontview.c',
'rangeedit.c',
'language-names.c',
]
fontexplorer_resources = gnome.compile_resources('fontexplorer_resources',
'fontexplorer.gresource.xml',
source_dir: '.',
)
executable('gtk4-font-explorer',
sources: [fontexplorer_sources, fontexplorer_resources],
c_args: common_cflags,
dependencies: [ libgtk_dep, demo_conf_h ],
include_directories: confinc,
link_args: extra_demo_ldflags,
install: true,
)
+173
View File
@@ -0,0 +1,173 @@
#include "rangeedit.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
enum {
PROP_ADJUSTMENT = 1,
PROP_DEFAULT_VALUE,
PROP_N_CHARS,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _RangeEdit
{
GtkWidget parent;
GtkAdjustment *adjustment;
GtkScale *scale;
GtkEntry *entry;
double default_value;
int n_chars;
};
struct _RangeEditClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (RangeEdit, range_edit, GTK_TYPE_WIDGET);
static void
range_edit_init (RangeEdit *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
}
static void
range_edit_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), RANGE_EDIT_TYPE);
G_OBJECT_CLASS (range_edit_parent_class)->dispose (object);
}
static void
range_edit_get_property (GObject *object,
unsigned int prop_id,
GValue *value,
GParamSpec *pspec)
{
RangeEdit *self = RANGE_EDIT (object);
switch (prop_id)
{
case PROP_ADJUSTMENT:
g_value_set_object (value, self->adjustment);
break;
case PROP_DEFAULT_VALUE:
g_value_set_double (value, self->default_value);
break;
case PROP_N_CHARS:
g_value_set_int (value, self->n_chars);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
adjustment_changed (GtkAdjustment *adjustment,
RangeEdit *self)
{
char *str;
str = g_strdup_printf ("%.1f", gtk_adjustment_get_value (adjustment));
gtk_editable_set_text (GTK_EDITABLE (self->entry), str);
g_free (str);
}
static void
range_edit_set_property (GObject *object,
unsigned int prop_id,
const GValue *value,
GParamSpec *pspec)
{
RangeEdit *self = RANGE_EDIT (object);
switch (prop_id)
{
case PROP_ADJUSTMENT:
g_set_object (&self->adjustment, g_value_get_object (value));
g_signal_connect (self->adjustment, "value-changed", G_CALLBACK (adjustment_changed), self);
adjustment_changed (self->adjustment, self);
break;
case PROP_DEFAULT_VALUE:
self->default_value = g_value_get_double (value);
break;
case PROP_N_CHARS:
self->n_chars = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
range_edit_constructed (GObject *object)
{
RangeEdit *self = RANGE_EDIT (object);
gtk_scale_add_mark (self->scale, self->default_value, GTK_POS_TOP, NULL);
}
static void
entry_activated (GtkEntry *entry,
RangeEdit *self)
{
double value;
char *err = NULL;
value = g_strtod (gtk_editable_get_text (GTK_EDITABLE (entry)), &err);
if (err != NULL)
gtk_adjustment_set_value (self->adjustment, value);
}
static void
range_edit_class_init (RangeEditClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = range_edit_dispose;
object_class->get_property = range_edit_get_property;
object_class->set_property = range_edit_set_property;
object_class->constructed = range_edit_constructed;
properties[PROP_ADJUSTMENT] =
g_param_spec_object ("adjustment", "", "",
GTK_TYPE_ADJUSTMENT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
properties[PROP_DEFAULT_VALUE] =
g_param_spec_double ("default-value", "", "",
-G_MAXDOUBLE, G_MAXDOUBLE, 0.,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
properties[PROP_N_CHARS] =
g_param_spec_int ("n-chars", "", "",
0, G_MAXINT, 10,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/rangeedit.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), RangeEdit, scale);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), RangeEdit, entry);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), entry_activated);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "rangeedit");
}
RangeEdit *
range_edit_new (void)
{
return g_object_new (RANGE_EDIT_TYPE, NULL);
}
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <gtk/gtk.h>
#define RANGE_EDIT_TYPE (range_edit_get_type ())
#define RANGE_EDIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RANGE_EDIT_TYPE, RangeEdit))
typedef struct _RangeEdit RangeEdit;
typedef struct _RangeEditClass RangeEditClass;
GType range_edit_get_type (void);
RangeEdit * range_edit_new (void);
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="RangeEdit" parent="GtkWidget">
<property name="layout-manager">
<object class="GtkBoxLayout">
<property name="spacing">10</property>
</object>
</property>
<child>
<object class="GtkScale" id="scale">
<property name="orientation">horizontal</property>
<property name="hexpand">1</property>
<property name="adjustment" bind-source="RangeEdit" bind-flags="sync-create"/>
</object>
</child>
<child>
<object class="GtkEntry" id="entry">
<property name="width-chars" bind-source="RangeEdit" bind-property="n-chars" bind-flags="sync-create"/>
<property name="max-width-chars" bind-source="RangeEdit" bind-property="n-chars" bind-flags="sync-create"/>
<signal name="activate" handler="entry_activated"/>
</object>
</child>
</template>
</interface>
+162
View File
@@ -0,0 +1,162 @@
#include "samplechooser.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
enum {
PROP_SAMPLE_TEXT = 1,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _SampleChooser
{
GtkWidget parent;
int sample;
const char *sample_text;
};
struct _SampleChooserClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(SampleChooser, sample_chooser, GTK_TYPE_WIDGET);
static const char *pangrams[] = {
"The quick brown fox jumps over the lazy dog.",
"Waltz, bad nymph, for quick jigs vex.",
"Quick zephyrs blow, vexing daft Jim.",
"Crazy Fredrick bought many very exquisite opal jewels.",
"Jaded zombies acted quaintly but kept driving their oxen forward.",
};
static const char *paragraphs[] = {
"Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.",
" Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) – вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!",
"Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός",
};
static const char *alphabets[] = {
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"0123456789",
"!@#$%^&*()?",
};
static const char *titles[] = {
"From My Cold Dead Hands",
"From Afar Upon the Back of a Tiger",
"Spontaneous Apple Creation",
"Big Bizness (Screwed & Chopped)",
"Pizza Shop Extended",
"Good News & Bad News",
};
static void
next_pangram (GtkButton *button,
SampleChooser *self)
{
self->sample++;
self->sample_text = pangrams[self->sample % G_N_ELEMENTS (pangrams)];
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
}
static void
next_paragraph (GtkButton *button,
SampleChooser *self)
{
self->sample++;
self->sample_text = paragraphs[self->sample % G_N_ELEMENTS (paragraphs)];
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
}
static void
next_alphabet (GtkButton *button,
SampleChooser *self)
{
self->sample++;
self->sample_text = alphabets[self->sample % G_N_ELEMENTS (alphabets)];
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
}
static void
next_title (GtkButton *button,
SampleChooser *self)
{
self->sample++;
self->sample_text = titles[self->sample % G_N_ELEMENTS (titles)];
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
}
static void
sample_chooser_init (SampleChooser *self)
{
self->sample_text = "Boring sample text";
gtk_widget_init_template (GTK_WIDGET (self));
}
static void
sample_chooser_dispose (GObject *object)
{
GtkWidget *child;
gtk_widget_clear_template (GTK_WIDGET (object), SAMPLE_CHOOSER_TYPE);
while ((child = gtk_widget_get_first_child (GTK_WIDGET (object))) != NULL)
gtk_widget_unparent (child);
G_OBJECT_CLASS (sample_chooser_parent_class)->dispose (object);
}
static void
sample_chooser_get_property (GObject *object,
unsigned int prop_id,
GValue *value,
GParamSpec *pspec)
{
SampleChooser *self = SAMPLE_CHOOSER (object);
switch (prop_id)
{
case PROP_SAMPLE_TEXT:
g_value_set_string (value, self->sample_text);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sample_chooser_class_init (SampleChooserClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = sample_chooser_dispose;
object_class->get_property = sample_chooser_get_property;
properties[PROP_SAMPLE_TEXT] =
g_param_spec_string ("sample-text", "", "",
"",
G_PARAM_READABLE);
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/samplechooser.ui");
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_pangram);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_paragraph);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_alphabet);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_title);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "samplechooser");
}
SampleChooser *
sample_chooser_new (void)
{
return g_object_new (SAMPLE_CHOOSER_TYPE, NULL);
}
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <gtk/gtk.h>
#define SAMPLE_CHOOSER_TYPE (sample_chooser_get_type ())
#define SAMPLE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SAMPLE_CHOOSER_TYPE, SampleChooser))
typedef struct _SampleChooser SampleChooser;
typedef struct _SampleChooserClass SampleChooserClass;
GType sample_chooser_get_type (void);
SampleChooser * sample_chooser_new (void);
+46
View File
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="SampleChooser" parent="GtkWidget">
<property name="layout-manager"><object class="GtkGridLayout"/></property>
<child>
<object class="GtkButton">
<property name="label">Pangram</property>
<signal name="clicked" handler="next_pangram"/>
<layout>
<property name="row">0</property>
<property name="column">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Paragraph</property>
<signal name="clicked" handler="next_paragraph"/>
<layout>
<property name="row">0</property>
<property name="column">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Alphabet</property>
<signal name="clicked" handler="next_alphabet"/>
<layout>
<property name="row">1</property>
<property name="column">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Title</property>
<signal name="clicked" handler="next_title"/>
<layout>
<property name="row">1</property>
<property name="column">1</property>
</layout>
</object>
</child>
</template>
</interface>
+7 -10
View File
@@ -341,16 +341,13 @@ do_clipboard (GtkWidget *do_widget)
GtkWidget *button;
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
"copy_button_clicked", G_CALLBACK (copy_button_clicked),
"paste_button_clicked", G_CALLBACK (paste_button_clicked),
"source_changed_cb", G_CALLBACK (source_changed_cb),
"text_changed_cb", G_CALLBACK (text_changed_cb),
"open_file_cb", G_CALLBACK (open_file_cb),
"on_drop", G_CALLBACK (on_drop),
"drag_prepare", G_CALLBACK (drag_prepare),
NULL);
gtk_builder_cscope_add_callback (scope, copy_button_clicked);
gtk_builder_cscope_add_callback (scope, paste_button_clicked);
gtk_builder_cscope_add_callback (scope, source_changed_cb);
gtk_builder_cscope_add_callback (scope, text_changed_cb);
gtk_builder_cscope_add_callback (scope, open_file_cb);
gtk_builder_cscope_add_callback (scope, on_drop);
gtk_builder_cscope_add_callback (scope, drag_prepare);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
gtk_builder_add_from_resource (builder, "/clipboard/clipboard.ui", NULL);
+5 -4
View File
@@ -260,12 +260,13 @@ mask_entry_set_background (MaskEntry *entry)
{
if (!g_regex_match_simple (entry->mask, gtk_editable_get_text (GTK_EDITABLE (entry)), 0, 0))
{
PangoAttrList *attrs;
Pango2AttrList *attrs;
Pango2Color color = { 65535, 32767, 32767, 65535 };
attrs = pango_attr_list_new ();
pango_attr_list_insert (attrs, pango_attr_foreground_new (65535, 32767, 32767));
attrs = pango2_attr_list_new ();
pango2_attr_list_insert (attrs, pango2_attr_foreground_new (&color));
gtk_entry_set_attributes (GTK_ENTRY (entry), attrs);
pango_attr_list_unref (attrs);
pango2_attr_list_unref (attrs);
return;
}
}
+2 -2
View File
@@ -84,11 +84,11 @@ do_css_basics (GtkWidget *do_widget)
text = gtk_text_buffer_new (NULL);
gtk_text_buffer_create_tag (text,
"warning",
"underline", PANGO_UNDERLINE_SINGLE,
"underline", PANGO2_LINE_STYLE_SOLID,
NULL);
gtk_text_buffer_create_tag (text,
"error",
"underline", PANGO_UNDERLINE_ERROR,
"underline", PANGO2_LINE_STYLE_DOTTED,
NULL);
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
+2 -2
View File
@@ -122,11 +122,11 @@ do_css_multiplebgs (GtkWidget *do_widget)
text = gtk_text_buffer_new (NULL);
gtk_text_buffer_create_tag (text,
"warning",
"underline", PANGO_UNDERLINE_SINGLE,
"underline", PANGO2_LINE_STYLE_SOLID,
NULL);
gtk_text_buffer_create_tag (text,
"error",
"underline", PANGO_UNDERLINE_ERROR,
"underline", PANGO2_LINE_STYLE_DOTTED,
NULL);
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
+2 -2
View File
@@ -93,11 +93,11 @@ do_css_pixbufs (GtkWidget *do_widget)
text = gtk_text_buffer_new (NULL);
gtk_text_buffer_create_tag (text,
"warning",
"underline", PANGO_UNDERLINE_SINGLE,
"underline", PANGO2_LINE_STYLE_SOLID,
NULL);
gtk_text_buffer_create_tag (text,
"error",
"underline", PANGO_UNDERLINE_ERROR,
"underline", PANGO2_LINE_STYLE_DOTTED,
NULL);
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
+2 -2
View File
@@ -111,11 +111,11 @@ do_css_shadows (GtkWidget *do_widget)
text = gtk_text_buffer_new (NULL);
gtk_text_buffer_create_tag (text,
"warning",
"underline", PANGO_UNDERLINE_SINGLE,
"underline", PANGO2_LINE_STYLE_SOLID,
NULL);
gtk_text_buffer_create_tag (text,
"error",
"underline", PANGO_UNDERLINE_ERROR,
"underline", PANGO2_LINE_STYLE_DOTTED,
NULL);
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
+2 -1
View File
@@ -329,6 +329,7 @@
<file>pickers.c</file>
<file>printing.c</file>
<file>revealer.c</file>
<file>read_more.c</file>
<file>rotated_text.c</file>
<file>scale.c</file>
<file>search_entry.c</file>
@@ -375,7 +376,7 @@
<file>glarea-gles.vs.glsl</file>
</gresource>
<gresource prefix="/font_features">
<file>font-features.ui</file>
<file>font_features.ui</file>
<file>fontplane.c</file>
</gresource>
<gresource prefix="/spinbutton">
+11 -10
View File
@@ -263,7 +263,7 @@ drop_down_new_from_strings (const char *const *titles,
static char *
get_family_name (gpointer item)
{
return g_strdup (pango_font_family_get_name (PANGO_FONT_FAMILY (item)));
return g_strdup (pango2_font_family_get_name (PANGO2_FONT_FAMILY (item)));
}
static char *
@@ -326,8 +326,8 @@ bind_highlight_item (GtkSignalListItemFactory *factory,
{
MatchObject *obj;
GtkWidget *label;
PangoAttrList *attrs;
PangoAttribute *attr;
Pango2AttrList *attrs;
Pango2Attribute *attr;
const char *str;
obj = MATCH_OBJECT (gtk_list_item_get_item (item));
@@ -336,13 +336,14 @@ bind_highlight_item (GtkSignalListItemFactory *factory,
str = match_object_get_string (obj);
gtk_label_set_label (GTK_LABEL (label), str);
attrs = pango_attr_list_new ();
attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
attr->start_index = match_object_get_match_start (obj);
attr->end_index = match_object_get_match_end (obj);
pango_attr_list_insert (attrs, attr);
attrs = pango2_attr_list_new ();
attr = pango2_attr_weight_new (PANGO2_WEIGHT_BOLD);
pango2_attribute_set_range (attr,
match_object_get_match_start (obj),
match_object_get_match_end (obj));
pango2_attr_list_insert (attrs, attr);
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs);
pango2_attr_list_unref (attrs);
}
static void
@@ -434,7 +435,7 @@ do_dropdown (GtkWidget *do_widget)
button = gtk_drop_down_new (NULL, NULL);
model = G_LIST_MODEL (pango_cairo_font_map_get_default ());
model = G_LIST_MODEL (pango2_font_map_get_default ());
gtk_drop_down_set_model (GTK_DROP_DOWN (button), model);
gtk_drop_down_set_selected (GTK_DROP_DOWN (button), 0);
+3 -6
View File
@@ -90,12 +90,9 @@ do_errorstates (GtkWidget *do_widget)
toplevel = GTK_WIDGET (gtk_widget_get_root (do_widget));
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
"validate_more_details", G_CALLBACK (validate_more_details),
"mode_switch_state_set", G_CALLBACK (mode_switch_state_set),
"level_scale_value_changed", G_CALLBACK (level_scale_value_changed),
NULL);
gtk_builder_cscope_add_callback (scope, validate_more_details);
gtk_builder_cscope_add_callback (scope, mode_switch_state_set);
gtk_builder_cscope_add_callback (scope, level_scale_value_changed);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
gtk_builder_expose_object (builder, "toplevel", G_OBJECT (toplevel));
-190
View File
@@ -1,190 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="default-width">600</property>
<property name="default-height">500</property>
<property name="title">Font Explorer</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child>
<object class="GtkButton" id="reset">
<property name="receives-default">1</property>
<property name="tooltip-text">Reset</property>
<property name="icon-name">view-refresh-symbolic</property>
<signal name="clicked" handler="font_features_reset_features" swapped="no"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<child>
<object class="GtkViewport">
<child>
<object class="GtkBox">
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkFontButton" id="font">
<property name="receives-default">1</property>
<property name="font">Sans 12</property>
<property name="level">family|style|size|variations|features</property>
<signal name="font-set" handler="font_features_font_changed" swapped="no"/>
</object>
</child>
<child>
<object class="GtkExpander">
<child type="label">
<object class="GtkLabel">
<property name="xalign">0</property>
<property name="label" translatable="yes">Font Features</property>
<attributes>
<attribute name="weight" value="bold"></attribute>
</attributes>
</object>
</child>
<child>
<object class="GtkBox" id="feature_list">
<property name="orientation">vertical</property>
<child>
<object class="GtkComboBox" id="script_lang">
<property name="margin-top">10</property>
<signal name="changed" handler="font_features_script_changed" swapped="no"/>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkExpander">
<child type="label">
<object class="GtkLabel" id="variations_heading">
<property name="label" translatable="yes">Font Variations</property>
<property name="xalign">0</property>
<attributes>
<attribute name="weight" value="bold"></attribute>
</attributes>
</object>
</child>
<child>
<object class="GtkGrid" id="variations_grid">
<property name="column-spacing">10</property>
<property name="row-spacing">10</property>
</object>
</child>
</object>
</child>
</object>
</child>
<style>
<class name="view"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
<property name="margin-top">20</property>
<property name="margin-bottom">20</property>
<property name="spacing">20</property>
<child>
<object class="GtkStack" id="stack">
<child>
<object class="GtkStackPage">
<property name="name">label</property>
<property name="child">
<object class="GtkLabel" id="label">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="valign">start</property>
<property name="selectable">1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">entry</property>
<property name="child">
<object class="GtkEntry" id="entry">
<property name="text">Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.
Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) – вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
<signal name="activate" handler="font_features_stop_edit"/>
<property name="valign">start</property>
<property name="width-chars">50</property>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel" id="settings">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="valign">end</property>
<property name="width-chars">50</property>
<property name="max-width-chars">50</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<style>
<class name="monospace"/>
</style>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkLabel" id="description">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="valign">end</property>
<property name="width-chars">50</property>
<property name="max-width-chars">50</property>
<property name="hexpand">1</property>
<style>
<class name="monospace"/>
</style>
</object>
</child>
<child>
<object class="GtkToggleButton" id="edit_toggle">
<property name="icon-name">document-edit-symbolic</property>
<property name="halign">end</property>
<property name="valign">end</property>
<signal name="toggled" handler="font_features_toggle_edit"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
File diff suppressed because it is too large Load Diff
+65
View File
@@ -0,0 +1,65 @@
--- demos/gtk-demo/font_features.c
+++ demos/gtk-demo/font_features.c
@@ -434,7 +434,7 @@ static void
update_display (void)
{
GString *s;
- const char *text;
+ char *text;
gboolean has_feature;
GtkTreeIter iter;
GtkTreeModel *model;
@@ -452,8 +452,12 @@ update_display (void)
gboolean do_waterfall;
GString *waterfall;
char *palette;
+ GtkTextBuffer *buffer;
+ GtkTextIter start_iter, end_iter;
- text = gtk_editable_get_text (GTK_EDITABLE (demo->the_entry));
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry));
+ gtk_text_buffer_get_bounds (buffer, &start_iter, &end_iter);
+ text = gtk_text_buffer_get_text (buffer, &start_iter, &end_iter, FALSE);
text_len = strlen (text);
do_waterfall = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (demo->waterfall_toggle));
@@ -631,6 +635,8 @@ update_display (void)
pango2_font_description_free (desc);
g_free (features);
pango2_attr_list_unref (attrs);
+
+ g_free (text);
}
static Pango2Font *
@@ -1603,8 +1609,12 @@ font_features_toggle_edit (void)
{
if (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (demo->stack)), "entry") != 0)
{
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
g_free (demo->text);
- demo->text = g_strdup (gtk_editable_get_text (GTK_EDITABLE (demo->the_entry)));
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry));
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
+ demo->text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
gtk_stack_set_visible_child_name (GTK_STACK (demo->stack), "entry");
gtk_widget_grab_focus (demo->the_entry);
gtk_adjustment_set_value (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (demo->swin)), 0);
@@ -1632,7 +1642,7 @@ entry_key_press (GtkEventController *controller,
{
if (keyval == GDK_KEY_Escape)
{
- gtk_editable_set_text (GTK_EDITABLE (entry), demo->text);
+ gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry)), demo->text, -1);
return GDK_EVENT_STOP;
}
@@ -1701,7 +1711,6 @@ do_font_features (GtkWidget *do_widget)
basic_value_changed (demo->line_height_adjustment, demo->line_height_entry);
controller = gtk_event_controller_key_new ();
- g_object_set_data_full (G_OBJECT (demo->the_entry), "controller", g_object_ref (controller), g_object_unref);
g_signal_connect (controller, "key-pressed", G_CALLBACK (entry_key_press), demo->the_entry);
gtk_widget_add_controller (demo->the_entry, controller);
+476
View File
@@ -0,0 +1,476 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkAdjustment" id="size_adjustment">
<property name="lower">7</property>
<property name="upper">100</property>
<property name="value">14</property>
<property name="step_increment">0.5</property>
<property name="page_increment">10</property>
<signal name="value-changed" handler="basic_value_changed" object="size_entry" swapped="false"/>
</object>
<object class="GtkAdjustment" id="letterspacing_adjustment">
<property name="lower">-1024</property>
<property name="upper">8192</property>
<property name="value">0</property>
<property name="step_increment">1</property>
<property name="page_increment">512</property>
<signal name="value-changed" handler="basic_value_changed" object="letterspacing_entry" swapped="false"/>
</object>
<object class="GtkAdjustment" id="line_height_adjustment">
<property name="lower">0.75</property>
<property name="upper">2.5</property>
<property name="value">1.0</property>
<property name="step_increment">0.1</property>
<property name="page_increment">1</property>
<signal name="value-changed" handler="basic_value_changed" object="line_height_entry" swapped="false"/>
</object>
<object class="GtkWindow" id="window">
<property name="default-width">600</property>
<property name="default-height">500</property>
<property name="title">Font Explorer</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child>
<object class="GtkButton" id="reset">
<property name="receives-default">1</property>
<property name="tooltip-text">Reset</property>
<property name="icon-name">view-refresh-symbolic</property>
<signal name="clicked" handler="font_features_reset_basic" swapped="no"/>
<signal name="clicked" handler="font_features_reset_features" swapped="no"/>
<signal name="clicked" handler="font_features_reset_variations" swapped="no"/>
<signal name="clicked" handler="font_features_reset_colors" swapped="no"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<child>
<object class="GtkViewport">
<child>
<object class="GtkBox">
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkFontButton" id="font">
<property name="receives-default">1</property>
<property name="font">Sans 12</property>
<property name="level">family|style</property>
<signal name="font-set" handler="font_features_font_changed" swapped="no"/>
</object>
</child>
<child>
<object class="GtkGrid">
<property name="column-spacing">10</property>
<property name="row-spacing">10</property>
<child>
<object class="GtkLabel">
<property name="label">Size</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale" id="size_scale">
<property name="hexpand">1</property>
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">size_adjustment</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="size_entry">
<property name="width-chars">4</property>
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<signal name="activate" handler="basic_entry_activated"
object="size_adjustment" swapped="false"/>
<layout>
<property name="column">2</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Letterspacing</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale">
<property name="hexpand">1</property>
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">letterspacing_adjustment</property>
<layout>
<property name="column">1</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="letterspacing_entry">
<property name="width-chars">4</property>
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<signal name="activate" handler="basic_entry_activated"
object="letterspacing_adjustment" swapped="false"/>
<layout>
<property name="column">2</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Line Height</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale">
<property name="hexpand">1</property>
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">line_height_adjustment</property>
<layout>
<property name="column">1</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="line_height_entry">
<property name="width-chars">4</property>
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<signal name="activate" handler="basic_entry_activated"
object="line_height_adjustment" swapped="false"/>
<layout>
<property name="column">2</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Foreground</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkColorButton" id="foreground">
<property name="valign">baseline</property>
<property name="rgba">black</property>
<signal name="notify::rgba" handler="color_set_cb"/>
<layout>
<property name="column">1</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Background</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkColorButton" id="background">
<property name="valign">baseline</property>
<property name="rgba">white</property>
<signal name="notify::rgba" handler="color_set_cb"/>
<layout>
<property name="column">1</property>
<property name="row">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">object-flip-vertical-symbolic</property>
<property name="halign">start</property>
<property name="valign">center</property>
<style>
<class name="circular"/>
</style>
<signal name="clicked" handler="swap_colors"/>
<layout>
<property name="column">2</property>
<property name="row">3</property>
<property name="row-span">2</property>
</layout>
</object>
</child>
</object>
</child>
<child>
<object class="GtkExpander">
<child type="label">
<object class="GtkLabel">
<property name="xalign">0</property>
<property name="label" translatable="yes">OpenType Features</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<style>
<class name="title-4"/>
</style>
</object>
</child>
<child>
<object class="GtkBox" id="feature_list">
<property name="orientation">vertical</property>
<child>
<object class="GtkComboBox" id="script_lang">
<property name="tooltip-text" translatable="yes">Language System</property>
<property name="margin-top">10</property>
<signal name="changed" handler="font_features_script_changed" swapped="no"/>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkExpander">
<child type="label">
<object class="GtkLabel" id="variations_heading">
<property name="label" translatable="yes">Variation Axes</property>
<property name="xalign">0</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<style>
<class name="title-4"/>
</style>
</object>
</child>
<child>
<object class="GtkGrid" id="variations_grid">
<property name="column-spacing">10</property>
<property name="row-spacing">10</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkExpander">
<child type="label">
<object class="GtkLabel">
<property name="label" translatable="yes">Color Palettes</property>
<property name="xalign">0</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<style>
<class name="title-4"/>
</style>
</object>
</child>
<child>
<object class="GtkGrid" id="colors_grid">
<property name="column-spacing">10</property>
<property name="row-spacing">10</property>
</object>
</child>
</object>
</child>
</object>
</child>
<style>
<class name="view"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
<property name="margin-top">20</property>
<property name="margin-bottom">20</property>
<property name="spacing">20</property>
<child>
<object class="GtkScrolledWindow" id="swin">
<property name="hscrollbar-policy">automatic</property>
<property name="vscrollbar-policy">automatic</property>
<property name="propagate-natural-height">1</property>
<property name="vexpand">1</property>
<style>
<class name="font_features_background"/>
</style>
<child>
<object class="GtkStack" id="stack">
<child>
<object class="GtkStackPage">
<property name="name">label</property>
<property name="child">
<object class="GtkLabel" id="label">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="valign">start</property>
<property name="selectable">1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">entry</property>
<property name="child">
<object class="GtkTextView" id="entry">
<property name="buffer">
<object class="GtkTextBuffer">
<property name="text">Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.
Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) – вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
</object>
</property>
<property name="valign">fill</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkLabel" id="settings">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="valign">end</property>
<property name="width-chars">50</property>
<property name="max-width-chars">50</property>
<property name="hexpand">1</property>
<style>
<class name="monospace"/>
</style>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Alphabet</property>
<signal name="clicked" handler="set_text_alphabet"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Paragraph</property>
<signal name="clicked" handler="set_text_paragraph"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkLabel" id="description">
<property name="wrap">1</property>
<property name="wrap-mode">char</property>
<property name="xalign">0</property>
<property name="valign">end</property>
<property name="width-chars">50</property>
<property name="max-width-chars">50</property>
<property name="hexpand">1</property>
<style>
<class name="monospace"/>
</style>
</object>
</child>
<child>
<object class="GtkBox">
<style>
<class name="linked"/>
</style>
<property name="valign">end</property>
<child>
<object class="GtkToggleButton" id="plain_toggle">
<property name="label" translatable="yes">Plain</property>
<property name="active">1</property>
<property name="valign">baseline</property>
<signal name="toggled" handler="font_features_toggle_plain"/>
</object>
</child>
<child>
<object class="GtkToggleButton" id="waterfall_toggle">
<property name="label" translatable="yes">Waterfall</property>
<property name="valign">baseline</property>
<property name="group">plain_toggle</property>
<signal name="toggled" handler="font_features_toggle_plain"/>
<signal name="notify::active" handler="font_features_notify_waterfall"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToggleButton" id="edit_toggle">
<property name="group">waterfall_toggle</property>
<property name="icon-name">document-edit-symbolic</property>
<property name="halign">end</property>
<property name="valign">end</property>
<signal name="clicked" handler="font_features_toggle_edit"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
+71 -89
View File
@@ -19,7 +19,7 @@
*/
static void
insert_tags_for_attributes (GtkTextBuffer *buffer,
PangoAttrIterator *iter,
Pango2AttrIterator *iter,
GtkTextIter *start,
GtkTextIter *end)
{
@@ -27,13 +27,12 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
GSList *attrs, *l;
GtkTextTag *tag;
char name[256];
float fg_alpha, bg_alpha;
table = gtk_text_buffer_get_tag_table (buffer);
#define LANGUAGE_ATTR(attr_name) \
{ \
const char *language = pango_language_to_string (((PangoAttrLanguage*)attr)->value); \
const char *language = pango2_language_to_string (pango2_attribute_get_language (attr)); \
g_snprintf (name, 256, "language=%s", language); \
tag = gtk_text_tag_table_lookup (table, name); \
if (!tag) \
@@ -48,7 +47,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
#define STRING_ATTR(attr_name) \
{ \
const char *string = ((PangoAttrString*)attr)->value; \
const char *string = pango2_attribute_get_string (attr); \
g_snprintf (name, 256, #attr_name "=%s", string); \
tag = gtk_text_tag_table_lookup (table, name); \
if (!tag) \
@@ -63,7 +62,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
#define INT_ATTR(attr_name) \
{ \
int value = ((PangoAttrInt*)attr)->value; \
int value = pango2_attribute_get_int (attr); \
g_snprintf (name, 256, #attr_name "=%d", value); \
tag = gtk_text_tag_table_lookup (table, name); \
if (!tag) \
@@ -78,8 +77,8 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
#define FONT_ATTR(attr_name) \
{ \
PangoFontDescription *desc = ((PangoAttrFontDesc*)attr)->desc; \
char *str = pango_font_description_to_string (desc); \
Pango2FontDescription *desc = pango2_attribute_get_font_desc (attr); \
char *str = pango2_font_description_to_string (desc); \
g_snprintf (name, 256, "font-desc=%s", str); \
g_free (str); \
tag = gtk_text_tag_table_lookup (table, name); \
@@ -95,7 +94,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
#define FLOAT_ATTR(attr_name) \
{ \
float value = ((PangoAttrFloat*)attr)->value; \
float value = pango2_attribute_get_float (attr); \
g_snprintf (name, 256, #attr_name "=%g", value); \
tag = gtk_text_tag_table_lookup (table, name); \
if (!tag) \
@@ -108,15 +107,14 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
#define RGBA_ATTR(attr_name, alpha_value) \
#define RGBA_ATTR(attr_name) \
{ \
PangoColor *color; \
Pango2Color *color = pango2_attribute_get_color (attr); \
GdkRGBA rgba; \
color = &((PangoAttrColor*)attr)->color; \
rgba.red = color->red / 65535.; \
rgba.green = color->green / 65535.; \
rgba.blue = color->blue / 65535.; \
rgba.alpha = alpha_value; \
rgba.alpha = color->alpha / 65535.; \
char *str = gdk_rgba_to_string (&rgba); \
g_snprintf (name, 256, #attr_name "=%s", str); \
g_free (str); \
@@ -144,173 +142,157 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
fg_alpha = bg_alpha = 1.;
attrs = pango_attr_iterator_get_attrs (iter);
attrs = pango2_attr_iterator_get_attrs (iter);
for (l = attrs; l; l = l->next)
{
PangoAttribute *attr = l->data;
Pango2Attribute *attr = l->data;
switch ((int)attr->klass->type)
switch (pango2_attribute_type (attr))
{
case PANGO_ATTR_FOREGROUND_ALPHA:
fg_alpha = ((PangoAttrInt*)attr)->value / 65535.;
break;
case PANGO_ATTR_BACKGROUND_ALPHA:
bg_alpha = ((PangoAttrInt*)attr)->value / 65535.;
break;
default:
break;
}
}
for (l = attrs; l; l = l->next)
{
PangoAttribute *attr = l->data;
switch (attr->klass->type)
{
case PANGO_ATTR_LANGUAGE:
case PANGO2_ATTR_LANGUAGE:
LANGUAGE_ATTR (language);
break;
case PANGO_ATTR_FAMILY:
case PANGO2_ATTR_FAMILY:
STRING_ATTR (family);
break;
case PANGO_ATTR_STYLE:
case PANGO2_ATTR_STYLE:
INT_ATTR (style);
break;
case PANGO_ATTR_WEIGHT:
case PANGO2_ATTR_WEIGHT:
INT_ATTR (weight);
break;
case PANGO_ATTR_VARIANT:
case PANGO2_ATTR_VARIANT:
INT_ATTR (variant);
break;
case PANGO_ATTR_STRETCH:
case PANGO2_ATTR_STRETCH:
INT_ATTR (stretch);
break;
case PANGO_ATTR_SIZE:
case PANGO2_ATTR_SIZE:
INT_ATTR (size);
break;
case PANGO_ATTR_FONT_DESC:
case PANGO2_ATTR_FONT_DESC:
FONT_ATTR (font-desc);
break;
case PANGO_ATTR_FOREGROUND:
RGBA_ATTR (foreground_rgba, fg_alpha);
case PANGO2_ATTR_FOREGROUND:
RGBA_ATTR (foreground_rgba);
break;
case PANGO_ATTR_BACKGROUND:
RGBA_ATTR (background_rgba, bg_alpha);
case PANGO2_ATTR_BACKGROUND:
RGBA_ATTR (background_rgba);
break;
case PANGO_ATTR_UNDERLINE:
case PANGO2_ATTR_UNDERLINE:
INT_ATTR (underline);
break;
case PANGO_ATTR_UNDERLINE_COLOR:
RGBA_ATTR (underline_rgba, fg_alpha);
case PANGO2_ATTR_UNDERLINE_COLOR:
RGBA_ATTR (underline_rgba);
break;
case PANGO_ATTR_OVERLINE:
case PANGO2_ATTR_OVERLINE:
INT_ATTR (overline);
break;
case PANGO_ATTR_OVERLINE_COLOR:
RGBA_ATTR (overline_rgba, fg_alpha);
case PANGO2_ATTR_OVERLINE_COLOR:
RGBA_ATTR (overline_rgba);
break;
case PANGO_ATTR_STRIKETHROUGH:
case PANGO2_ATTR_STRIKETHROUGH:
INT_ATTR (strikethrough);
break;
case PANGO_ATTR_STRIKETHROUGH_COLOR:
RGBA_ATTR (strikethrough_rgba, fg_alpha);
case PANGO2_ATTR_STRIKETHROUGH_COLOR:
RGBA_ATTR (strikethrough_rgba);
break;
case PANGO_ATTR_RISE:
case PANGO2_ATTR_RISE:
INT_ATTR (rise);
break;
case PANGO_ATTR_SCALE:
case PANGO2_ATTR_SCALE:
FLOAT_ATTR (scale);
break;
case PANGO_ATTR_FALLBACK:
case PANGO2_ATTR_FALLBACK:
INT_ATTR (fallback);
break;
case PANGO_ATTR_LETTER_SPACING:
case PANGO2_ATTR_LETTER_SPACING:
INT_ATTR (letter_spacing);
break;
case PANGO_ATTR_FONT_FEATURES:
case PANGO2_ATTR_FONT_FEATURES:
STRING_ATTR (font_features);
break;
case PANGO_ATTR_ALLOW_BREAKS:
case PANGO2_ATTR_ALLOW_BREAKS:
INT_ATTR (allow_breaks);
break;
case PANGO_ATTR_SHOW:
case PANGO2_ATTR_SHOW:
INT_ATTR (show_spaces);
break;
case PANGO_ATTR_INSERT_HYPHENS:
case PANGO2_ATTR_INSERT_HYPHENS:
INT_ATTR (insert_hyphens);
break;
case PANGO_ATTR_LINE_HEIGHT:
case PANGO2_ATTR_LINE_HEIGHT:
FLOAT_ATTR (line_height);
break;
case PANGO_ATTR_ABSOLUTE_LINE_HEIGHT:
case PANGO2_ATTR_ABSOLUTE_LINE_HEIGHT:
break;
case PANGO_ATTR_WORD:
case PANGO2_ATTR_LINE_SPACING:
INT_ATTR (pixels_inside_wrap);
break;
case PANGO2_ATTR_WORD:
VOID_ATTR (word);
break;
case PANGO_ATTR_SENTENCE:
case PANGO2_ATTR_SENTENCE:
VOID_ATTR (sentence);
break;
case PANGO_ATTR_BASELINE_SHIFT:
case PANGO2_ATTR_PARAGRAPH:
VOID_ATTR (paragraph);
break;
case PANGO2_ATTR_BASELINE_SHIFT:
INT_ATTR (baseline_shift);
break;
case PANGO_ATTR_FONT_SCALE:
case PANGO2_ATTR_FONT_SCALE:
INT_ATTR (font_scale);
break;
case PANGO_ATTR_SHAPE:
case PANGO_ATTR_ABSOLUTE_SIZE:
case PANGO_ATTR_GRAVITY:
case PANGO_ATTR_GRAVITY_HINT:
case PANGO_ATTR_FOREGROUND_ALPHA:
case PANGO_ATTR_BACKGROUND_ALPHA:
case PANGO2_ATTR_ABSOLUTE_SIZE:
case PANGO2_ATTR_GRAVITY:
case PANGO2_ATTR_GRAVITY_HINT:
break;
case PANGO_ATTR_TEXT_TRANSFORM:
case PANGO2_ATTR_TEXT_TRANSFORM:
INT_ATTR (text_transform);
break;
case PANGO_ATTR_INVALID:
case PANGO2_ATTR_INVALID:
default:
g_assert_not_reached ();
break;
}
}
g_slist_free_full (attrs, (GDestroyNotify)pango_attribute_destroy);
g_slist_free_full (attrs, (GDestroyNotify)pango2_attribute_destroy);
#undef LANGUAGE_ATTR
#undef STRING_ATTR
@@ -329,9 +311,9 @@ typedef struct
GtkTextBuffer *buffer;
GtkTextIter iter;
GtkTextMark *mark;
PangoAttrList *attributes;
Pango2AttrList *attributes;
char *text;
PangoAttrIterator *attr;
Pango2AttrIterator *attr;
} MarkupData;
static void
@@ -340,8 +322,8 @@ free_markup_data (MarkupData *mdata)
g_free (mdata->markup);
g_clear_pointer (&mdata->parser, g_markup_parse_context_free);
gtk_text_buffer_delete_mark (mdata->buffer, mdata->mark);
g_clear_pointer (&mdata->attr, pango_attr_iterator_destroy);
g_clear_pointer (&mdata->attributes, pango_attr_list_unref);
g_clear_pointer (&mdata->attr, pango2_attr_iterator_destroy);
g_clear_pointer (&mdata->attributes, pango2_attr_list_unref);
g_free (mdata->text);
g_object_unref (mdata->buffer);
g_free (mdata);
@@ -367,7 +349,7 @@ insert_markup_idle (gpointer data)
return G_SOURCE_REMOVE;
}
pango_attr_iterator_range (mdata->attr, &start, &end);
pango2_attr_iterator_range (mdata->attr, &start, &end);
if (end == G_MAXINT) /* last chunk */
end = start - 1; /* resulting in -1 to be passed to _insert */
@@ -380,7 +362,7 @@ insert_markup_idle (gpointer data)
gtk_text_buffer_get_iter_at_mark (mdata->buffer, &mdata->iter, mdata->mark);
}
while (pango_attr_iterator_next (mdata->attr));
while (pango2_attr_iterator_next (mdata->attr));
free_markup_data (mdata);
return G_SOURCE_REMOVE;
@@ -416,7 +398,7 @@ parse_markup_idle (gpointer data)
mdata->pos += 4096;
} while (mdata->pos < mdata->len);
if (!pango_markup_parser_finish (mdata->parser,
if (!pango2_markup_parser_finish (mdata->parser,
&mdata->attributes,
&mdata->text,
NULL,
@@ -435,7 +417,7 @@ parse_markup_idle (gpointer data)
return G_SOURCE_REMOVE;
}
mdata->attr = pango_attr_list_get_iterator (mdata->attributes);
mdata->attr = pango2_attr_list_get_iterator (mdata->attributes);
insert_markup_idle (data);
return G_SOURCE_REMOVE;
@@ -461,7 +443,7 @@ insert_markup (GtkTextBuffer *buffer,
data->markup = markup;
data->len = len;
data->parser = pango_markup_parser_new (0);
data->parser = pango2_markup_parser_new (0);
data->pos = 0;
/* create mark with right gravity */
+44 -42
View File
@@ -25,7 +25,7 @@ static GtkWidget *show_extents = NULL;
static GtkWidget *show_pixels = NULL;
static GtkWidget *show_outlines = NULL;
static PangoContext *context;
static Pango2Context *context;
static int scale = 7;
static double pixel_alpha = 1.0;
@@ -35,9 +35,9 @@ static void
update_image (void)
{
const char *text;
PangoFontDescription *desc;
PangoLayout *layout;
PangoRectangle ink, logical;
Pango2FontDescription *desc;
Pango2Layout *layout;
Pango2Rectangle ink, logical;
int baseline;
cairo_surface_t *surface;
cairo_t *cr;
@@ -56,7 +56,7 @@ update_image (void)
text = gtk_editable_get_text (GTK_EDITABLE (entry));
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font_button));
fopt = cairo_font_options_copy (pango_cairo_context_get_font_options (context));
fopt = cairo_font_options_copy (pango2_cairo_context_get_font_options (context));
hint = gtk_combo_box_get_active_id (GTK_COMBO_BOX (hinting));
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
@@ -85,20 +85,20 @@ update_image (void)
antialias = CAIRO_ANTIALIAS_NONE;
cairo_font_options_set_antialias (fopt, antialias);
pango_context_set_round_glyph_positions (context, hintmetrics == CAIRO_HINT_METRICS_ON);
pango_cairo_context_set_font_options (context, fopt);
pango2_context_set_round_glyph_positions (context, hintmetrics == CAIRO_HINT_METRICS_ON);
pango2_cairo_context_set_font_options (context, fopt);
cairo_font_options_destroy (fopt);
pango_context_changed (context);
pango2_context_changed (context);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (text_radio)))
{
layout = pango_layout_new (context);
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, text, -1);
pango_layout_get_extents (layout, &ink, &logical);
baseline = pango_layout_get_baseline (layout);
layout = pango2_layout_new (context);
pango2_layout_set_font_description (layout, desc);
pango2_layout_set_text (layout, text, -1);
pango2_lines_get_extents (pango2_layout_get_lines (layout), &ink, &logical);
baseline = pango2_lines_get_baseline (pango2_layout_get_lines (layout));
pango_extents_to_pixels (&ink, NULL);
pango2_extents_to_pixels (&ink, NULL);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ink.width + 20, ink.height + 20);
cr = cairo_create (surface);
@@ -108,9 +108,9 @@ update_image (void)
cairo_set_source_rgba (cr, 0, 0, 0, pixel_alpha);
cairo_move_to (cr, 10, 10);
pango_cairo_show_layout (cr, layout);
pango2_cairo_show_layout (cr, layout);
pango_cairo_layout_path (cr, layout);
pango2_cairo_layout_path (cr, layout);
path = cairo_copy_path (cr);
cairo_destroy (cr);
@@ -154,15 +154,15 @@ update_image (void)
cairo_set_source_rgb (cr, 0, 0, 1);
cairo_rectangle (cr,
scale * (10 + pango_units_to_double (logical.x)) - 0.5,
scale * (10 + pango_units_to_double (logical.y)) - 0.5,
scale * pango_units_to_double (logical.width) + 1,
scale * pango_units_to_double (logical.height) + 1);
scale * (10 + pango2_units_to_double (logical.x)) - 0.5,
scale * (10 + pango2_units_to_double (logical.y)) - 0.5,
scale * pango2_units_to_double (logical.width) + 1,
scale * pango2_units_to_double (logical.height) + 1);
cairo_stroke (cr);
cairo_move_to (cr, scale * (10 + pango_units_to_double (logical.x)) - 0.5,
scale * (10 + pango_units_to_double (baseline)) - 0.5);
cairo_line_to (cr, scale * (10 + pango_units_to_double (logical.x + logical.width)) + 1,
scale * (10 + pango_units_to_double (baseline)) - 0.5);
cairo_move_to (cr, scale * (10 + pango2_units_to_double (logical.x)) - 0.5,
scale * (10 + pango2_units_to_double (baseline)) - 0.5);
cairo_line_to (cr, scale * (10 + pango2_units_to_double (logical.x + logical.width)) + 1,
scale * (10 + pango2_units_to_double (baseline)) - 0.5);
cairo_stroke (cr);
cairo_set_source_rgb (cr, 1, 0, 0);
cairo_rectangle (cr,
@@ -206,9 +206,10 @@ update_image (void)
}
else
{
PangoLayoutIter *iter;
PangoLayoutRun *run;
PangoGlyphInfo *g;
Pango2LineIter *iter;
Pango2Run *run;
Pango2GlyphString *glyphs;
Pango2GlyphInfo *g;
int i, j;
GString *str;
gunichar ch;
@@ -226,43 +227,44 @@ update_image (void)
g_string_append_unichar (str, 0x200c);
}
layout = pango_layout_new (context);
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, str->str, -1);
layout = pango2_layout_new (context);
pango2_layout_set_font_description (layout, desc);
pango2_layout_set_text (layout, str->str, -1);
g_string_free (str, TRUE);
pango_layout_get_extents (layout, &ink, &logical);
pango_extents_to_pixels (&logical, NULL);
pango2_lines_get_extents (pango2_layout_get_lines (layout), &ink, &logical);
pango2_extents_to_pixels (&logical, NULL);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, logical.width * 3 / 2, 4*logical.height);
cr = cairo_create (surface);
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
iter = pango_layout_get_iter (layout);
run = pango_layout_iter_get_run (iter);
iter = pango2_layout_get_iter (layout);
run = pango2_line_iter_get_run (iter);
glyphs = pango2_run_get_glyphs (run);
cairo_set_source_rgb (cr, 0, 0, 0);
for (i = 0; i < 4; i++)
{
g = &(run->glyphs->glyphs[2*i]);
g->geometry.width = PANGO_UNITS_ROUND (g->geometry.width * 3 / 2);
g = &(glyphs->glyphs[2*i]);
g->geometry.width = PANGO2_UNITS_ROUND (g->geometry.width * 3 / 2);
}
for (j = 0; j < 4; j++)
{
for (i = 0; i < 4; i++)
{
g = &(run->glyphs->glyphs[2*i]);
g->geometry.x_offset = i * (PANGO_SCALE / 4);
g->geometry.y_offset = j * (PANGO_SCALE / 4);
g = &(glyphs->glyphs[2*i]);
g->geometry.x_offset = i * (PANGO2_SCALE / 4);
g->geometry.y_offset = j * (PANGO2_SCALE / 4);
}
cairo_move_to (cr, 0, j * logical.height);
pango_cairo_show_layout (cr, layout);
pango2_cairo_show_layout (cr, layout);
}
cairo_destroy (cr);
pango_layout_iter_free (iter);
pango2_line_iter_free (iter);
g_object_unref (layout);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
@@ -275,7 +277,7 @@ update_image (void)
g_object_unref (pixbuf2);
pango_font_description_free (desc);
pango2_font_description_free (desc);
}
static gboolean fading = FALSE;
+2 -1
View File
@@ -23,7 +23,7 @@ do_headerbar (GtkWidget *do_widget)
{
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Welcome to Facebook - Log in, sign up or learn more");
gtk_window_set_title (GTK_WINDOW (window), "Welcome to the Hotel California");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
@@ -31,6 +31,7 @@ do_headerbar (GtkWidget *do_widget)
header = gtk_header_bar_new ();
button = gtk_button_new_from_icon_name ("mail-send-receive-symbolic");
gtk_widget_set_tooltip_text (button, "Check out");
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+4 -4
View File
@@ -29,7 +29,7 @@ insert_link (GtkTextBuffer *buffer,
tag = gtk_text_buffer_create_tag (buffer, NULL,
"foreground", "blue",
"underline", PANGO_UNDERLINE_SINGLE,
"underline", PANGO2_LINE_STYLE_SOLID,
NULL);
g_object_set_data (G_OBJECT (tag), "page", GINT_TO_POINTER (page));
gtk_text_buffer_insert_with_tags (buffer, iter, text, -1, tag, NULL);
@@ -72,8 +72,8 @@ show_page (GtkTextView *text_view,
buffer = gtk_text_view_get_buffer (text_view);
bold = gtk_text_buffer_create_tag (buffer, NULL,
"weight", PANGO_WEIGHT_BOLD,
"scale", PANGO_SCALE_X_LARGE,
"weight", PANGO2_WEIGHT_BOLD,
"scale", PANGO2_SCALE_X_LARGE,
NULL);
mono = gtk_text_buffer_create_tag (buffer, NULL,
"family", "monospace",
@@ -100,7 +100,7 @@ show_page (GtkTextView *text_view,
theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (text_view)));
icon = gtk_icon_theme_lookup_icon (theme,
"eye-not-looking-symbolic",
"view-conceal-symbolic",
NULL,
16,
1,
+2 -2
View File
@@ -123,11 +123,11 @@ populate_emoji_text (void)
for (int i = 0; i < 500; i++)
{
if (i % 2)
g_string_append (s, "<span underline=\"single\" underline_color=\"red\">x</span>");
g_string_append (s, "<span underline=\"solid\" underline_color=\"red\">x</span>");
for (int j = 0; j < 30; j++)
{
g_string_append (s, "💓");
g_string_append (s, "<span underline=\"single\" underline_color=\"red\">x</span>");
g_string_append (s, "<span underline=\"solid\" underline_color=\"red\">x</span>");
}
g_string_append (s, "\n");
}
+9 -9
View File
@@ -44,7 +44,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
gint i;
const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 };
GHashTable *ht_scripts_langs = (GHashTable *) param;
PangoLanguage *lang;
Pango2Language *lang;
gint langname_size, locale_abbrev_size;
langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0);
@@ -60,7 +60,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
p = strchr (locale, '-');
lang = pango_language_from_string (locale);
lang = pango2_language_from_string (locale);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);
@@ -77,7 +77,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size);
locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL);
lang = pango_language_from_string (locale_abbrev);
lang = pango2_language_from_string (locale_abbrev);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);
@@ -218,22 +218,22 @@ languages_parse_start_tag (GMarkupParseContext *ctx,
if (ccode != NULL)
g_hash_table_insert (language_map,
pango_language_from_string (ccode),
pango2_language_from_string (ccode),
g_strdup (display_name));
if (ccode_longB != NULL)
g_hash_table_insert (language_map,
pango_language_from_string (ccode_longB),
pango2_language_from_string (ccode_longB),
g_strdup (display_name));
if (ccode_longT != NULL)
g_hash_table_insert (language_map,
pango_language_from_string (ccode_longT),
pango2_language_from_string (ccode_longT),
g_strdup (display_name));
if (ccode_id != NULL)
g_hash_table_insert (language_map,
pango_language_from_string (ccode_id),
pango2_language_from_string (ccode_id),
g_strdup (display_name));
g_free (display_name);
@@ -295,7 +295,7 @@ languages_init (void)
}
const char *
get_language_name (PangoLanguage *language)
get_language_name (Pango2Language *language)
{
languages_init ();
@@ -311,5 +311,5 @@ get_language_name_for_tag (guint32 tag)
lang = hb_ot_tag_to_language (tag);
s = hb_language_to_string (lang);
return get_language_name (pango_language_from_string (s));
return get_language_name (pango2_language_from_string (s));
}
+2 -2
View File
@@ -1,11 +1,11 @@
#ifndef LANGUAGE_NAMES_H
#define LANGUAGE_NAMES_H
#include <pango/pango.h>
#include <pango2/pango.h>
G_BEGIN_DECLS
const char * get_language_name (PangoLanguage *language);
const char * get_language_name (Pango2Language *language);
const char * get_language_name_for_tag (guint32 tag);
G_END_DECLS
+4 -6
View File
@@ -66,15 +66,13 @@ do_links (GtkWidget *do_widget)
"as hyperlinks, which can be clicked "
"or activated via <a href=\"keynav\">keynav</a> "
"and they work fine with other markup, like when "
"searching on <a href=\"http://www.google.com/\">"
"<span color=\"#0266C8\">G</span><span color=\"#F90101\">o</span>"
"<span color=\"#F2B50F\">o</span><span color=\"#0266C8\">g</span>"
"<span color=\"#00933B\">l</span><span color=\"#F90101\">e</span>"
"</a>.");
"linking to <a href=\"http://www.flathub.org/\"><b>"
"<span letter_spacing=\"1024\" underline=\"none\" color=\"pink\" background=\"darkslategray\">Flathub</span>"
"</b></a>.");
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
gtk_label_set_max_width_chars (GTK_LABEL (label), 40);
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD);
gtk_label_set_wrap_mode (GTK_LABEL (label), PANGO2_WRAP_WORD);
g_signal_connect (label, "activate-link", G_CALLBACK (activate_link), NULL);
gtk_widget_set_margin_start (label, 20);
gtk_widget_set_margin_end (label, 20);
+1 -2
View File
@@ -42,8 +42,7 @@ do_listbox_controls (GtkWidget *do_widget)
GtkBuilder *builder;
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope),
"row_activated", G_CALLBACK (row_activated));
gtk_builder_cscope_add_callback (scope, row_activated);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
+8 -8
View File
@@ -758,15 +758,15 @@ setup_number_item (GtkSignalListItemFactory *factory,
GtkListItem *item)
{
GtkWidget *label;
PangoAttrList *attrs;
Pango2AttrList *attrs;
label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (label), 1);
attrs = pango_attr_list_new ();
pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum"));
attrs = pango2_attr_list_new ();
pango2_attr_list_insert (attrs, pango2_attr_font_features_new ("tnum"));
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs);
pango2_attr_list_unref (attrs);
gtk_list_item_set_child (item, label);
}
@@ -862,7 +862,7 @@ do_listview_colors (GtkWidget *do_widget)
GtkExpression *expression;
GtkWidget *button;
GtkWidget *label;
PangoAttrList *attrs;
Pango2AttrList *attrs;
char *string;
guint len;
GtkWidget *selection_view;
@@ -990,10 +990,10 @@ do_listview_colors (GtkWidget *do_widget)
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
label = gtk_label_new ("0 /");
attrs = pango_attr_list_new ();
pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum"));
attrs = pango2_attr_list_new ();
pango2_attr_list_insert (attrs, pango2_attr_font_features_new ("tnum"));
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs);
pango2_attr_list_unref (attrs);
string = g_strdup_printf ("%'u", 4096);
len = g_utf8_strlen (string, -1);
g_free (string);
+4 -4
View File
@@ -356,10 +356,10 @@ do_listview_settings (GtkWidget *do_widget)
g_type_ensure (SETTINGS_TYPE_KEY);
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "search_enabled", (GCallback)search_enabled);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "search_changed", (GCallback)search_changed);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "stop_search", (GCallback)stop_search);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "item_value_changed", (GCallback)item_value_changed);
gtk_builder_cscope_add_callback (scope, search_enabled);
gtk_builder_cscope_add_callback (scope, search_changed);
gtk_builder_cscope_add_callback (scope, stop_search);
gtk_builder_cscope_add_callback (scope, item_value_changed);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
+1 -1
View File
@@ -123,7 +123,7 @@ setup_ellipsizing_label (GtkSignalListItemFactory *factory,
GtkWidget *label;
label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO2_ELLIPSIZE_END);
gtk_label_set_width_chars (GTK_LABEL (label), 20);
gtk_list_item_set_child (GTK_LIST_ITEM (listitem), label);
}
+3 -4
View File
@@ -1,5 +1,5 @@
/* Lists/Words
* #Keywords: GtkListView, GtkFilterListModel
* #Keywords: GtkListView, GtkFilterListModel, GtkInscription
*
* This demo shows filtering a long list - of words.
*
@@ -17,10 +17,9 @@ const char *factory_text =
"<interface>\n"
" <template class='GtkListItem'>\n"
" <property name='child'>\n"
" <object class='GtkLabel'>\n"
" <property name='ellipsize'>end</property>\n"
" <object class='GtkInscription'>\n"
" <property name='xalign'>0</property>\n"
" <binding name='label'>\n"
" <binding name='text'>\n"
" <lookup name='string' type='GtkStringObject'>\n"
" <lookup name='item'>GtkListItem</lookup>\n"
" </lookup>\n"
+3 -3
View File
@@ -7,9 +7,9 @@
<lookup name="item">GtkListItem</lookup>
</binding>
<property name="child">
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<object class="GtkInscription">
<property name="hexpand">1</property>
<binding name="text">
<lookup name="title" type="GtkDemo">
<lookup name="item">expander</lookup>
</lookup>
+2 -2
View File
@@ -190,8 +190,8 @@ activate_about (GSimpleAction *action,
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (s, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (s, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
+3 -3
View File
@@ -7,9 +7,9 @@ Text weights: <span weight="thin">thin</span> <span weight="light">light</span>
Text <span color="gray">c<span color="green">o</span>l<span color="tomato">o</span>rs</span> and <span background="pink">backgrounds</span>
Colorful <span underline="low" underline-color="blue"><span underline="double" underline-color="red">under</span>lines</span> and <span background="pink"><span underline="error">mo</span><span underline="error" underline-color="green">re</span></span>
Colorful <span underline_position="under" underline-color="blue"><span underline="double" underline-color="red">under</span>lines</span> and <span background="pink"><span underline="wavy">mo</span><span underline="wavy" underline-color="green">re</span></span>
Colorful <span strikethrough="true" strikethrough-color="magenta">strikethroughs</span> and <span overline="single" overline_color="green">overlines</span>
Colorful <span strikethrough="solid" strikethrough-color="magenta">strikethroughs</span> and <span overline="solid" overline_color="green">overlines</span>
Superscripts and subscripts: 𝜀<span rise="-6000" size="x-small" font_desc="italic">0</span> = 𝜔<span rise="8000" size="smaller">𝜔<span rise="14000" size="smaller">𝜔<span rise="20000">.<span rise="23000">.<span rise="26000">.</span></span></span></span></span>
@@ -19,7 +19,7 @@ OpenType font features: <span font_desc="sans regular" font_features="dlig=0">fe
Shortcuts: <tt>Monospace</tt> <b>Bold</b> <i>Italic</i> <big>Big</big> <small>Small</small> <u>Underlined</u> <s>Strikethrough</s> Super<sup>script</sup> Sub<sub>script</sub>
hy­phen­ation al­go­rithm is a <span allow_breaks="false" style="italic">set of rules</span>, espe­ci­ally one co­di­fied for im­ple­men­tation in a com­pu­ter pro­gram, that de­ci­des at which points a word can be bro­ken over two lines with a hy­phen. For ex­am­ple, a hy­phen­ation al­go­rithm might de­cide that im­peach­ment can be broken as impeach‧ment or im‧peachment but not impe‧achment.
A hy­phen­ation al­go­rithm is a <span allow_breaks="false" style="italic">set of rules</span>, espe­ci­ally one co­di­fied for im­ple­men­tation in a com­pu­ter pro­gram, that de­ci­des at which points a word can be bro­ken over two lines with a hy­phen. For ex­am­ple, a hy­phen­ation al­go­rithm might de­cide that im­peach­ment can be broken as impeach‧ment or im‧peachment but not impe‧achment.
<span insert_hyphens="false">one/two three/four five/six seven/eight nine/ten</span>
+2 -1
View File
@@ -73,8 +73,9 @@ demos = files([
'peg_solitaire.c',
'pickers.c',
'printing.c',
'read_more.c',
'revealer.c',
'rotated_text.c',
#'rotated_text.c', FIXME
'scale.c',
'search_entry.c',
'search_entry2.c',
+11 -5
View File
@@ -2,7 +2,7 @@
* #Keywords: GtkColorChooser, GtkFontChooser, GtkApplicationChooser
*
* These widgets are mainly intended for use in preference dialogs.
* They allow to select colors, fonts, directories and applications.
* They allow to select colors, fonts and applications.
*
* This demo shows both the default appearance for these dialogs,
* as well as some of the customizations that are possible.
@@ -11,8 +11,8 @@
#include <gtk/gtk.h>
static gboolean
filter_font_cb (const PangoFontFamily *family,
const PangoFontFace *face,
filter_font_cb (const Pango2FontFamily *family,
const Pango2FontFace *face,
gpointer data)
{
const char *alias_families[] = {
@@ -26,9 +26,15 @@ filter_font_cb (const PangoFontFamily *family,
};
const char *family_name;
family_name = pango_font_family_get_name (PANGO_FONT_FAMILY (family));
family_name = pango2_font_family_get_name ((Pango2FontFamily *)family);
return g_strv_contains (alias_families, family_name);
for (int i = 0; alias_families[i]; i++)
{
if (g_ascii_strcasecmp (alias_families[i], family_name) == 0)
return TRUE;
}
return FALSE;
}
#define COLOR(r,g,b) { r/255., g/255., b/255., 1.0 }
+28 -25
View File
@@ -59,11 +59,11 @@ draw_page (GtkPrintOperation *operation,
{
PrintData *data = (PrintData *)user_data;
cairo_t *cr;
PangoLayout *layout;
int text_width, text_height;
Pango2Layout *layout;
Pango2Rectangle ext;
double width;
int line, i;
PangoFontDescription *desc;
Pango2FontDescription *desc;
char *page_str;
cr = gtk_print_context_get_cairo_context (context);
@@ -80,47 +80,50 @@ draw_page (GtkPrintOperation *operation,
layout = gtk_print_context_create_pango_layout (context);
desc = pango_font_description_from_string ("sans 14");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
desc = pango2_font_description_from_string ("sans 14");
pango2_layout_set_font_description (layout, desc);
pango2_font_description_free (desc);
pango_layout_set_text (layout, data->resourcename, -1);
pango_layout_get_pixel_size (layout, &text_width, &text_height);
pango2_layout_set_text (layout, data->resourcename, -1);
pango2_lines_get_extents (pango2_layout_get_lines (layout), NULL, &ext);
pango2_extents_to_pixels (&ext, NULL);
if (text_width > width)
if (ext.width > width)
{
pango_layout_set_width (layout, width);
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_START);
pango_layout_get_pixel_size (layout, &text_width, &text_height);
pango2_layout_set_width (layout, width);
pango2_layout_set_ellipsize (layout, PANGO2_ELLIPSIZE_START);
pango2_lines_get_extents (pango2_layout_get_lines (layout), NULL, &ext);
pango2_extents_to_pixels (&ext, NULL);
}
cairo_move_to (cr, (width - text_width) / 2, (HEADER_HEIGHT - text_height) / 2);
pango_cairo_show_layout (cr, layout);
cairo_move_to (cr, (width - ext.width) / 2, (HEADER_HEIGHT - ext.height) / 2);
pango2_cairo_show_layout (cr, layout);
page_str = g_strdup_printf ("%d/%d", page_nr + 1, data->num_pages);
pango_layout_set_text (layout, page_str, -1);
pango2_layout_set_text (layout, page_str, -1);
g_free (page_str);
pango_layout_set_width (layout, -1);
pango_layout_get_pixel_size (layout, &text_width, &text_height);
cairo_move_to (cr, width - text_width - 4, (HEADER_HEIGHT - text_height) / 2);
pango_cairo_show_layout (cr, layout);
pango2_layout_set_width (layout, -1);
pango2_lines_get_extents (pango2_layout_get_lines (layout), NULL, &ext);
pango2_extents_to_pixels (&ext, NULL);
cairo_move_to (cr, width - ext.width - 4, (HEADER_HEIGHT - ext.height) / 2);
pango2_cairo_show_layout (cr, layout);
g_object_unref (layout);
layout = gtk_print_context_create_pango_layout (context);
desc = pango_font_description_from_string ("monospace");
pango_font_description_set_size (desc, data->font_size * PANGO_SCALE);
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
desc = pango2_font_description_from_string ("monospace");
pango2_font_description_set_size (desc, data->font_size * PANGO2_SCALE);
pango2_layout_set_font_description (layout, desc);
pango2_font_description_free (desc);
cairo_move_to (cr, 0, HEADER_HEIGHT + HEADER_GAP);
line = page_nr * data->lines_per_page;
for (i = 0; i < data->lines_per_page && line < data->num_lines; i++)
{
pango_layout_set_text (layout, data->lines[line], -1);
pango_cairo_show_layout (cr, layout);
pango2_layout_set_text (layout, data->lines[line], -1);
pango2_cairo_show_layout (cr, layout);
cairo_rel_move_to (cr, 0, data->font_size);
line++;
}
+239
View File
@@ -0,0 +1,239 @@
/* Read More
* #Keywords: GtkInscription
*
* A simple implementation of a widget that can either
* display a lot of text or just the first few lines with a
* "Read More" button.
*/
#include <gtk/gtk.h>
#define READ_TYPE_MORE (read_more_get_type ())
G_DECLARE_FINAL_TYPE(ReadMore, read_more, READ, MORE, GtkWidget)
struct _ReadMore {
GtkWidget parent_instance;
GtkWidget *label;
GtkWidget *inscription;
GtkWidget *box;
gboolean show_more;
};
G_DEFINE_TYPE (ReadMore, read_more, GTK_TYPE_WIDGET)
static GtkSizeRequestMode
read_more_get_request_mode (GtkWidget *widget)
{
return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
}
static void
read_more_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
ReadMore *self = READ_MORE (widget);
int label_min, label_nat, label_min_baseline, label_nat_baseline;
int box_min, box_nat, box_min_baseline, box_nat_baseline;
int min_check;
if (self->show_more)
min_check = G_MAXINT;
else if (for_size >= 0)
gtk_widget_measure (self->box, 1 - orientation, -1, &min_check, NULL, NULL, NULL);
else
min_check = -1;
if (min_check > for_size)
{
gtk_widget_measure (self->label,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
return;
}
else if (for_size >= 0)
gtk_widget_measure (self->label, 1 - orientation, -1, &min_check, NULL, NULL, NULL);
else
min_check = -1;
if (min_check > for_size)
{
gtk_widget_measure (self->box,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
return;
}
gtk_widget_measure (self->label,
orientation,
for_size,
&label_min, &label_nat,
&label_min_baseline, &label_nat_baseline);
gtk_widget_measure (self->box,
orientation,
for_size,
&box_min, &box_nat,
&box_min_baseline, &box_nat_baseline);
*minimum = MIN (label_min, box_min);
*natural = MIN (label_nat, box_nat);
/* FIXME: Figure out baselines! */
}
static void
read_more_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
ReadMore *self = READ_MORE (widget);
gboolean show_more;
if (self->show_more)
{
show_more = TRUE;
}
else
{
int needed;
/* check to see if we have enough space to show all text */
gtk_widget_measure (self->label,
GTK_ORIENTATION_VERTICAL,
width,
&needed, NULL, NULL, NULL);
show_more = needed <= height;
}
gtk_widget_set_child_visible (self->label, show_more);
gtk_widget_set_child_visible (self->box, !show_more);
if (show_more)
gtk_widget_size_allocate (self->label, &(GtkAllocation) { 0, 0, width, height }, baseline);
else
gtk_widget_size_allocate (self->box, &(GtkAllocation) { 0, 0, width, height }, baseline);
}
static void
read_more_dispose (GObject *object)
{
ReadMore *self = READ_MORE (object);
g_clear_pointer (&self->label, gtk_widget_unparent);
g_clear_pointer (&self->box, gtk_widget_unparent);
G_OBJECT_CLASS (read_more_parent_class)->dispose (object);
}
static void
read_more_class_init (ReadMoreClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
widget_class->get_request_mode = read_more_get_request_mode;
widget_class->measure = read_more_measure;
widget_class->size_allocate = read_more_allocate;
object_class->dispose = read_more_dispose;
}
static void
read_more_clicked (GtkButton *button,
ReadMore *self)
{
self->show_more = TRUE;
gtk_widget_queue_resize (GTK_WIDGET (self));
}
static void
read_more_init (ReadMore *self)
{
GtkWidget *button;
self->label = gtk_label_new (NULL);
gtk_label_set_xalign (GTK_LABEL (self->label), 0.0);
gtk_label_set_yalign (GTK_LABEL (self->label), 0.0);
gtk_label_set_wrap (GTK_LABEL (self->label), TRUE);
gtk_label_set_width_chars (GTK_LABEL (self->label), 3);
gtk_label_set_max_width_chars (GTK_LABEL (self->label), 30);
gtk_widget_set_parent (self->label, GTK_WIDGET (self));
self->box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_vexpand (self->box, FALSE);
gtk_widget_set_parent (self->box, GTK_WIDGET (self));
self->inscription = gtk_inscription_new (NULL);
gtk_inscription_set_xalign (GTK_INSCRIPTION (self->inscription), 0.0);
gtk_inscription_set_yalign (GTK_INSCRIPTION (self->inscription), 0.0);
gtk_inscription_set_min_lines (GTK_INSCRIPTION (self->inscription), 3);
gtk_inscription_set_nat_chars (GTK_INSCRIPTION (self->inscription), 30);
gtk_widget_set_vexpand (self->inscription, TRUE);
gtk_box_append (GTK_BOX (self->box), self->inscription);
button = gtk_button_new_with_label ("Read More");
g_signal_connect (button, "clicked", G_CALLBACK (read_more_clicked), self);
gtk_box_append (GTK_BOX (self->box), button);
}
static void
read_more_set_text (ReadMore *self,
const char *text)
{
gtk_label_set_label (GTK_LABEL (self->label), text);
gtk_inscription_set_text (GTK_INSCRIPTION (self->inscription), text);
}
static GtkWidget *
read_more_new (const char *text)
{
ReadMore *self = g_object_new (READ_TYPE_MORE, NULL);
read_more_set_text (self, text);
return GTK_WIDGET (self);
}
GtkWidget *
do_read_more (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *readmore;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Read More");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
readmore = read_more_new (
"I'd just like to interject for a moment. What you're referring to as Linux, is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX.\n"
"\n"
"Many computer users run a modified version of the GNU system every day, without realizing it. Through a peculiar turn of events, the version of GNU which is widely used today is often called \"Linux\", and many of its users are not aware that it is basically the GNU system, developed by the GNU Project.\n"
"\n"
"There really is a Linux, and these people are using it, but it is just a part of the system they use. Linux is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Linux is normally used in combination with the GNU operating system: the whole system is basically GNU with Linux added, or GNU/Linux. All the so-called \"Linux\" distributions are really distributions of GNU/Linux.");
gtk_window_set_child (GTK_WINDOW (window), readmore);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}
+126 -95
View File
@@ -1,9 +1,9 @@
/* Pango/Rotated Text
/* Pango2/Rotated Text
*
* This demo shows how to use PangoCairo to draw rotated and transformed
* This demo shows how to use Pango2Cairo to draw rotated and transformed
* text. The right pane shows a rotated GtkLabel widget.
*
* In both cases, a custom PangoCairo shape renderer is installed to draw
* In both cases, a custom Pango2Cairo shape renderer is installed to draw
* a red heart using cairo drawing operations instead of the Unicode heart
* character.
*/
@@ -14,75 +14,118 @@
#define HEART "♥"
const char text[] = "I ♥ GTK";
static void
fancy_shape_renderer (cairo_t *cr,
PangoAttrShape *attr,
gboolean do_path,
gpointer data)
static gboolean
glyph_cb (Pango2UserFace *face,
hb_codepoint_t unicode,
hb_codepoint_t *glyph,
gpointer data)
{
double x, y;
cairo_get_current_point (cr, &x, &y);
cairo_translate (cr, x, y);
cairo_scale (cr,
(double) attr->ink_rect.width / PANGO_SCALE,
(double) attr->ink_rect.height / PANGO_SCALE);
if (GPOINTER_TO_UINT (attr->data) == 0x2665) /* U+2665 BLACK HEART SUIT */
if (unicode == 0x2665)
{
*glyph = 0x2665;
return TRUE;
}
return FALSE;
}
static gboolean
glyph_info_cb (Pango2UserFace *face,
int size,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
hb_position_t *h_advance,
hb_position_t *v_advance,
gboolean *is_color,
gpointer user_data)
{
if (glyph == 0x2665)
{
extents->x_bearing = 0;
extents->y_bearing = size;
extents->width = size;
extents->height = - size;
*h_advance = size;
*v_advance = size;
*is_color = TRUE;
return TRUE;
}
return FALSE;
}
static gboolean
font_info_cb (Pango2UserFace *face,
int size,
hb_font_extents_t *extents,
gpointer user_data)
{
extents->ascender = size;
extents->descender = 0;
extents->line_gap = 0;
return TRUE;
}
static gboolean
render_cb (Pango2UserFace *face,
int size,
hb_codepoint_t glyph,
gpointer user_data,
const char *backend_id,
gpointer backend_data)
{
cairo_t *cr;
if (strcmp (backend_id, "cairo") != 0)
{
g_warning ("Unsupported Pango2Renderer backend %s", backend_id);
return FALSE;
}
cr = backend_data;
if (glyph == 0x2665)
{
cairo_set_source_rgb (cr, 1., 0., 0.);
cairo_move_to (cr, .5, .0);
cairo_line_to (cr, .9, -.4);
cairo_curve_to (cr, 1.1, -.8, .5, -.9, .5, -.5);
cairo_curve_to (cr, .5, -.9, -.1, -.8, .1, -.4);
cairo_close_path (cr);
cairo_fill (cr);
return TRUE;
}
if (!do_path)
{
cairo_set_source_rgb (cr, 1., 0., 0.);
cairo_fill (cr);
}
return FALSE;
}
static PangoAttrList *
create_fancy_attr_list_for_layout (PangoLayout *layout)
static void
setup_fontmap (void)
{
PangoAttrList *attrs;
PangoFontMetrics *metrics;
int ascent;
PangoRectangle ink_rect, logical_rect;
const char *p;
Pango2FontMap *fontmap = pango2_font_map_get_default ();
Pango2FontDescription *desc;
Pango2UserFace *face;
/* Get font metrics and prepare fancy shape size */
metrics = pango_context_get_metrics (pango_layout_get_context (layout),
pango_layout_get_font_description (layout),
NULL);
ascent = pango_font_metrics_get_ascent (metrics);
logical_rect.x = 0;
logical_rect.width = ascent;
logical_rect.y = -ascent;
logical_rect.height = ascent;
ink_rect = logical_rect;
pango_font_metrics_unref (metrics);
desc = pango2_font_description_new ();
pango2_font_description_set_family (desc, "Bullets");
/* Set fancy shape attributes for all hearts */
attrs = pango_attr_list_new ();
for (p = text; (p = strstr (p, HEART)); p += strlen (HEART))
{
PangoAttribute *attr;
/* Create our fancy user font, "Bullets Black" */
face = pango2_user_face_new (font_info_cb,
glyph_cb,
glyph_info_cb,
NULL,
render_cb,
NULL, NULL, "Black", desc);
attr = pango_attr_shape_new_with_data (&ink_rect,
&logical_rect,
GUINT_TO_POINTER (g_utf8_get_char (p)),
NULL, NULL);
/* And add it to the default fontmap */
pango2_font_map_add_face (fontmap, PANGO2_FONT_FACE (face));
attr->start_index = p - text;
attr->end_index = attr->start_index + strlen (HEART);
pango_attr_list_insert (attrs, attr);
}
return attrs;
pango2_font_description_free (desc);
}
static void
@@ -94,16 +137,12 @@ rotated_text_draw (GtkDrawingArea *da,
{
#define RADIUS 150
#define N_WORDS 5
#define FONT "Serif 18"
PangoContext *context;
PangoLayout *layout;
PangoFontDescription *desc;
#define FONT "Bullets 18"
Pango2Context *context;
Pango2Layout *layout;
Pango2FontDescription *desc;
cairo_pattern_t *pattern;
PangoAttrList *attrs;
double device_radius;
int i;
@@ -123,40 +162,34 @@ rotated_text_draw (GtkDrawingArea *da,
cairo_pattern_add_color_stop_rgb (pattern, 1., .0, .0, .5);
cairo_set_source (cr, pattern);
/* Create a PangoContext and set up our shape renderer */
/* Create a Pango2Context and set up our shape renderer */
context = gtk_widget_create_pango_context (GTK_WIDGET (da));
pango_cairo_context_set_shape_renderer (context,
fancy_shape_renderer,
NULL, NULL);
/* Create a PangoLayout, set the text, font, and attributes */
layout = pango_layout_new (context);
pango_layout_set_text (layout, text, -1);
desc = pango_font_description_from_string (FONT);
pango_layout_set_font_description (layout, desc);
attrs = create_fancy_attr_list_for_layout (layout);
pango_layout_set_attributes (layout, attrs);
pango_attr_list_unref (attrs);
/* Create a Pango2Layout, set the text, font, and attributes */
layout = pango2_layout_new (context);
pango2_layout_set_text (layout, text, -1);
desc = pango2_font_description_from_string (FONT);
pango2_layout_set_font_description (layout, desc);
/* Draw the layout N_WORDS times in a circle */
for (i = 0; i < N_WORDS; i++)
{
int layout_width, layout_height;
Pango2Rectangle ext;
/* Inform Pango to re-layout the text with the new transformation matrix */
pango_cairo_update_layout (cr, layout);
/* Inform Pango2 to re-layout the text with the new transformation matrix */
pango2_cairo_update_layout (cr, layout);
pango_layout_get_pixel_size (layout, &layout_width, &layout_height);
cairo_move_to (cr, - layout_width / 2, - RADIUS * .9);
pango_cairo_show_layout (cr, layout);
pango2_lines_get_extents (pango2_layout_get_lines (layout), NULL, &ext);
pango2_extents_to_pixels (&ext, NULL);
cairo_move_to (cr, - ext.width / 2, - RADIUS * .9);
pango2_cairo_show_layout (cr, layout);
/* Rotate for the next turn */
cairo_rotate (cr, G_PI*2 / N_WORDS);
}
/* free the objects we created */
pango_font_description_free (desc);
pango2_font_description_free (desc);
g_object_unref (layout);
g_object_unref (context);
cairo_pattern_destroy (pattern);
@@ -172,8 +205,10 @@ do_rotated_text (GtkWidget *do_widget)
GtkWidget *box;
GtkWidget *drawing_area;
GtkWidget *label;
PangoLayout *layout;
PangoAttrList *attrs;
Pango2Attribute *attr;
Pango2AttrList *attrs;
setup_fontmap ();
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
@@ -197,16 +232,12 @@ do_rotated_text (GtkWidget *do_widget)
/* And a label */
label = gtk_label_new (text);
gtk_box_append (GTK_BOX (box), label);
/* Set up fancy stuff on the label */
layout = gtk_label_get_layout (GTK_LABEL (label));
pango_cairo_context_set_shape_renderer (pango_layout_get_context (layout),
fancy_shape_renderer,
NULL, NULL);
attrs = create_fancy_attr_list_for_layout (layout);
attrs = pango2_attr_list_new ();
attr = pango2_attr_font_desc_new (pango2_font_description_from_string (FONT));
pango2_attr_list_insert (attrs, attr);
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs);
pango2_attr_list_unref (attrs);
gtk_box_append (GTK_BOX (box), label);
}
if (!gtk_widget_get_visible (window))
+7 -7
View File
@@ -21,7 +21,7 @@ do_tabs (GtkWidget *do_widget)
GtkWidget *view;
GtkWidget *sw;
GtkTextBuffer *buffer;
PangoTabArray *tabs;
Pango2TabArray *tabs;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Tabs");
@@ -38,13 +38,13 @@ do_tabs (GtkWidget *do_widget)
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 20);
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view), 20);
tabs = pango_tab_array_new (3, TRUE);
pango_tab_array_set_tab (tabs, 0, PANGO_TAB_LEFT, 0);
pango_tab_array_set_tab (tabs, 1, PANGO_TAB_DECIMAL, 150);
pango_tab_array_set_decimal_point (tabs, 1, '.');
pango_tab_array_set_tab (tabs, 2, PANGO_TAB_RIGHT, 290);
tabs = pango2_tab_array_new (3, TRUE);
pango2_tab_array_set_tab (tabs, 0, PANGO2_TAB_LEFT, 0);
pango2_tab_array_set_tab (tabs, 1, PANGO2_TAB_DECIMAL, 150);
pango2_tab_array_set_decimal_point (tabs, 1, '.');
pango2_tab_array_set_tab (tabs, 2, PANGO2_TAB_RIGHT, 290);
gtk_text_view_set_tabs (GTK_TEXT_VIEW (view), tabs);
pango_tab_array_free (tabs);
pango2_tab_array_free (tabs);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
gtk_text_buffer_set_text (buffer, "one\t2.0\tthree\nfour\t5.555\tsix\nseven\t88.88\tnine", -1);
+7 -7
View File
@@ -1,6 +1,6 @@
/* Pango/Text Mask
*
* This demo shows how to use PangoCairo to draw text with more than
* This demo shows how to use Pango to draw text with more than
* just a single color.
*/
@@ -15,18 +15,18 @@ draw_text (GtkDrawingArea *da,
gpointer data)
{
cairo_pattern_t *pattern;
PangoLayout *layout;
PangoFontDescription *desc;
Pango2Layout *layout;
Pango2FontDescription *desc;
cairo_save (cr);
layout = gtk_widget_create_pango_layout (GTK_WIDGET (da), "Pango power!\nPango power!\nPango power!");
desc = pango_font_description_from_string ("sans bold 34");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
desc = pango2_font_description_from_string ("sans bold 34");
pango2_layout_set_font_description (layout, desc);
pango2_font_description_free (desc);
cairo_move_to (cr, 30, 20);
pango_cairo_layout_path (cr, layout);
pango2_cairo_layout_path (cr, layout);
g_object_unref (layout);
pattern = cairo_pattern_create_linear (0.0, 0.0, width, height);
+17 -18
View File
@@ -36,25 +36,25 @@ create_tags (GtkTextBuffer *buffer)
*/
gtk_text_buffer_create_tag (buffer, "heading",
"weight", PANGO_WEIGHT_BOLD,
"size", 15 * PANGO_SCALE,
"weight", PANGO2_WEIGHT_BOLD,
"size", 15 * PANGO2_SCALE,
NULL);
gtk_text_buffer_create_tag (buffer, "italic",
"style", PANGO_STYLE_ITALIC, NULL);
"style", PANGO2_STYLE_ITALIC, NULL);
gtk_text_buffer_create_tag (buffer, "bold",
"weight", PANGO_WEIGHT_BOLD, NULL);
"weight", PANGO2_WEIGHT_BOLD, NULL);
gtk_text_buffer_create_tag (buffer, "big",
/* points times the PANGO_SCALE factor */
"size", 20 * PANGO_SCALE, NULL);
/* points times the PANGO2_SCALE factor */
"size", 20 * PANGO2_SCALE, NULL);
gtk_text_buffer_create_tag (buffer, "xx-small",
"scale", PANGO_SCALE_XX_SMALL, NULL);
"scale", PANGO2_SCALE_XX_SMALL, NULL);
gtk_text_buffer_create_tag (buffer, "x-large",
"scale", PANGO_SCALE_X_LARGE, NULL);
"scale", PANGO2_SCALE_X_LARGE, NULL);
gtk_text_buffer_create_tag (buffer, "monospace",
"family", "monospace", NULL);
@@ -100,19 +100,19 @@ create_tags (GtkTextBuffer *buffer)
"strikethrough", TRUE, NULL);
gtk_text_buffer_create_tag (buffer, "underline",
"underline", PANGO_UNDERLINE_SINGLE, NULL);
"underline", PANGO2_LINE_STYLE_SOLID, NULL);
gtk_text_buffer_create_tag (buffer, "double_underline",
"underline", PANGO_UNDERLINE_DOUBLE, NULL);
"underline", PANGO2_LINE_STYLE_DOUBLE, NULL);
gtk_text_buffer_create_tag (buffer, "superscript",
"rise", 10 * PANGO_SCALE, /* 10 pixels */
"size", 8 * PANGO_SCALE, /* 8 points */
"rise", 10 * PANGO2_SCALE, /* 10 pixels */
"size", 8 * PANGO2_SCALE, /* 8 points */
NULL);
gtk_text_buffer_create_tag (buffer, "subscript",
"rise", -10 * PANGO_SCALE, /* 10 pixels */
"size", 8 * PANGO_SCALE, /* 8 points */
"rise", -10 * PANGO2_SCALE, /* 10 pixels */
"size", 8 * PANGO2_SCALE, /* 8 points */
NULL);
gtk_text_buffer_create_tag (buffer, "rtl_quote",
@@ -137,7 +137,7 @@ insert_text (GtkTextView *view)
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
icon = gtk_icon_theme_lookup_icon (icon_theme,
"face-cool",
"drive-harddisk",
NULL,
32, 1,
gtk_widget_get_direction (widget),
@@ -239,8 +239,6 @@ insert_text (GtkTextView *view)
gtk_text_buffer_insert (buffer, &iter, "The buffer can have images in it: ", -1);
gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (icon));
gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (icon));
gtk_text_buffer_insert_paintable (buffer, &iter, nuclear);
gtk_text_buffer_insert (buffer, &iter, " for example.\n\n", -1);
@@ -441,11 +439,12 @@ attach_widgets (GtkTextView *text_view)
{
widget = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, NULL);
gtk_range_set_range (GTK_RANGE (widget), 0, 100);
gtk_widget_set_size_request (widget, 70, -1);
gtk_widget_set_size_request (widget, 100, -1);
}
else if (i == 3)
{
widget = gtk_entry_new ();
gtk_editable_set_width_chars (GTK_EDITABLE (widget), 10);
}
else
{
+2 -2
View File
@@ -70,8 +70,8 @@ about_activated (GSimpleAction *action,
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (s, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (s, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
+1
View File
@@ -22,3 +22,4 @@ subdir('icon-browser')
subdir('node-editor')
subdir('widget-factory')
subdir('print-editor')
subdir('font-explorer')
+18 -6
View File
@@ -19,12 +19,24 @@ executable('gtk4-node-editor',
] + common_cflags,
win_subsystem: 'windows',
link_args: extra_demo_ldflags,
install: false,
install: true,
)
# icons, don't install them until we decide to install gtk4-node-editor
#icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
# icons
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
foreach size: ['scalable', 'symbolic']
install_subdir('data/' + size, install_dir: icontheme_dir)
endforeach
# desktop file
install_data('org.gtk.gtk4.NodeEditor.desktop', install_dir: gtk_applicationsdir)
# appdata
configure_file(
input: 'org.gtk.gtk4.NodeEditor.appdata.xml.in',
output: 'org.gtk.gtk4.NodeEditor.appdata.xml',
configuration: appdata_config,
install_dir: gtk_appdatadir
)
#foreach size: ['scalable', 'symbolic']
# install_subdir('data/' + size, install_dir: icontheme_dir)
#endforeach
+2 -2
View File
@@ -77,8 +77,8 @@ activate_about (GSimpleAction *action,
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (s, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (s, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
+26 -3
View File
@@ -57,6 +57,7 @@ struct _NodeEditorWindow
GtkWidget *testcase_cairo_checkbutton;
GtkWidget *testcase_name_entry;
GtkWidget *testcase_save_button;
GtkWidget *scale_scale;
GtkWidget *renderer_listbox;
GListStore *renderers;
@@ -171,6 +172,7 @@ text_changed (GtkTextBuffer *buffer,
GBytes *bytes;
GtkTextIter iter;
GtkTextIter start, end;
float scale;
g_array_remove_range (self->errors, 0, self->errors->len);
text = get_current_text (self->text_buffer);
@@ -181,6 +183,17 @@ text_changed (GtkTextBuffer *buffer,
/* If this is too slow, go fix the parser performance */
self->node = gsk_render_node_deserialize (bytes, deserialize_error_func, self);
scale = gtk_scale_button_get_value (GTK_SCALE_BUTTON (self->scale_scale));
if (self->node && scale != 1.0)
{
GskRenderNode *node;
node = gsk_transform_node_new (self->node, gsk_transform_scale (NULL, scale, scale));
gsk_render_node_unref (self->node);
self->node = node;
}
g_bytes_unref (bytes);
if (self->node)
{
@@ -277,6 +290,14 @@ text_changed (GtkTextBuffer *buffer,
&start, &end);
}
static void
scale_changed (GObject *object,
GParamSpec *pspec,
NodeEditorWindow *self)
{
text_changed (self->text_buffer, self);
}
static gboolean
text_view_query_tooltip_cb (GtkWidget *widget,
int x,
@@ -344,13 +365,13 @@ static void
load_error (NodeEditorWindow *self,
const char *error_message)
{
PangoLayout *layout;
Pango2Layout *layout;
GtkSnapshot *snapshot;
GskRenderNode *node;
GBytes *bytes;
layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), error_message);
pango_layout_set_width (layout, 300 * PANGO_SCALE);
pango2_layout_set_width (layout, 300 * PANGO2_SCALE);
snapshot = gtk_snapshot_new ();
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA) { 0.7, 0.13, 0.13, 1.0 });
node = gtk_snapshot_free_to_node (snapshot);
@@ -962,6 +983,7 @@ node_editor_window_class_init (NodeEditorWindowClass *class)
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, testcase_cairo_checkbutton);
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, testcase_name_entry);
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, testcase_save_button);
gtk_widget_class_bind_template_child (widget_class, NodeEditorWindow, scale_scale);
gtk_widget_class_bind_template_callback (widget_class, text_view_query_tooltip_cb);
gtk_widget_class_bind_template_callback (widget_class, open_cb);
@@ -1038,7 +1060,7 @@ node_editor_window_init (NodeEditorWindow *self)
gtk_text_tag_table_add (self->tag_table,
g_object_new (GTK_TYPE_TEXT_TAG,
"name", "error",
"underline", PANGO_UNDERLINE_ERROR,
"underline", PANGO2_LINE_STYLE_DOTTED,
NULL));
gtk_text_tag_table_add (self->tag_table,
g_object_new (GTK_TYPE_TEXT_TAG,
@@ -1068,6 +1090,7 @@ node_editor_window_init (NodeEditorWindow *self)
self->text_buffer = gtk_text_buffer_new (self->tag_table);
g_signal_connect (self->text_buffer, "changed", G_CALLBACK (text_changed), self);
g_signal_connect (self->scale_scale, "notify::value", G_CALLBACK (scale_changed), self);
gtk_text_view_set_buffer (GTK_TEXT_VIEW (self->text_view), self->text_buffer);
/* Default */
+17
View File
@@ -157,6 +157,23 @@
<signal name="notify::active" handler="dark_mode_cb" swapped="0"/>
</object>
</child>
<child type="end">
<object class="GtkScaleButton" id="scale_scale">
<property name="focus-on-click">0</property>
<property name="valign">center</property>
<property name="adjustment">
<object class="GtkAdjustment">
<property name="lower">1</property>
<property name="value">1</property>
<property name="upper">10</property>
<property name="step-increment">0.1</property>
<property name="page-increment">0.5</property>
</object>
</property>
<property name="icons">zoom-in-symbolic</property>
<property name="tooltip-text" translatable="yes">Scale the image</property>
</object>
</child>
</object>
</child>
<child>
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>org.gtk.gtk4.NodeEditor</id>
<launchable type="desktop-id">org.gtk.gtk4.NodeEditor.desktop</launchable>
<metadata_license>CC0-1.0</metadata_license>
<project_license>LGPL-2.1-or-later</project_license>
<name>GTK Node Editor</name>
<summary>Program to edit render node files</summary>
<description>
<p>
GTK Node Editor is a simple application to show and edit
render node files.
</p>
<p>
Render node files can e.g. be created by the GTK inspector.
</p>
</description>
<screenshots>
<screenshot>
<image>https://static.gnome.org/appdata/gtk4-node-editor/gtk4-node-editor.png</image>
<caption>Node Editor</caption>
</screenshot>
</screenshots>
<kudos>
<kudo>HiDpiIcon</kudo>
<kudo>ModernToolkit</kudo>
</kudos>
<url type="homepage">https://www.gtk.org</url>
<translation type="gettext">gtk-4.0</translation>
<update_contact>matthias.clasen_at_gmail.com</update_contact>
<developer_name>Matthias Clasen and others</developer_name>
<content_rating type="oars-1.1"/>
<releases>
<release version="@BUILD_VERSION@">
<description>
<p>A new build of GTK.</p>
</description>
</release>
</releases>
</component>
@@ -0,0 +1,9 @@
[Desktop Entry]
Name=Node Editor
Comment=An application that edits render nodes
Exec=gtk4-node-editor
Icon=org.gtk.gtk4.NodeEditor
Terminal=false
Type=Application
StartupNotify=true
Categories=Development;GTK;
+31 -29
View File
@@ -1,6 +1,6 @@
#include <config.h>
#include <math.h>
#include <pango/pangocairo.h>
#include <pango2/pangocairo.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
@@ -200,7 +200,7 @@ save_file (GFile *save_filename)
typedef struct {
char *text;
PangoLayout *layout;
Pango2Layout *layout;
GList *page_breaks;
GtkWidget *font_button;
char *font;
@@ -211,39 +211,41 @@ begin_print (GtkPrintOperation *operation,
GtkPrintContext *context,
PrintData *print_data)
{
PangoFontDescription *desc;
PangoLayoutLine *layout_line;
Pango2FontDescription *desc;
Pango2Lines *lines;
Pango2Line *line;
double width, height;
double page_height;
GList *page_breaks;
int num_lines;
int line;
int i;
width = gtk_print_context_get_width (context);
height = gtk_print_context_get_height (context);
print_data->layout = gtk_print_context_create_pango_layout (context);
desc = pango_font_description_from_string (print_data->font);
pango_layout_set_font_description (print_data->layout, desc);
pango_font_description_free (desc);
desc = pango2_font_description_from_string (print_data->font);
pango2_layout_set_font_description (print_data->layout, desc);
pango2_font_description_free (desc);
pango_layout_set_width (print_data->layout, width * PANGO_SCALE);
pango2_layout_set_width (print_data->layout, width * PANGO2_SCALE);
pango_layout_set_text (print_data->layout, print_data->text, -1);
pango2_layout_set_text (print_data->layout, print_data->text, -1);
num_lines = pango_layout_get_line_count (print_data->layout);
lines = pango2_layout_get_lines (print_data->layout);
num_lines = pango2_lines_get_line_count (lines);
page_breaks = NULL;
page_height = 0;
for (line = 0; line < num_lines; line++)
for (i = 0; i < num_lines; i++)
{
PangoRectangle ink_rect, logical_rect;
Pango2Rectangle logical_rect;
double line_height;
layout_line = pango_layout_get_line (print_data->layout, line);
pango_layout_line_get_extents (layout_line, &ink_rect, &logical_rect);
line = pango2_lines_get_lines (lines)[i];
pango2_line_get_extents (line, NULL, &logical_rect);
line_height = logical_rect.height / 1024.0;
@@ -271,7 +273,7 @@ draw_page (GtkPrintOperation *operation,
cairo_t *cr;
GList *pagebreak;
int start, end, i;
PangoLayoutIter *iter;
Pango2LineIter *iter;
double start_pos;
if (page_nr == 0)
@@ -284,7 +286,7 @@ draw_page (GtkPrintOperation *operation,
pagebreak = g_list_nth (print_data->page_breaks, page_nr);
if (pagebreak == NULL)
end = pango_layout_get_line_count (print_data->layout);
end = pango2_lines_get_line_count (pango2_layout_get_lines (print_data->layout));
else
end = GPOINTER_TO_INT (pagebreak->data);
@@ -294,33 +296,33 @@ draw_page (GtkPrintOperation *operation,
i = 0;
start_pos = 0;
iter = pango_layout_get_iter (print_data->layout);
iter = pango2_layout_get_iter (print_data->layout);
do
{
PangoRectangle logical_rect;
PangoLayoutLine *line;
int baseline;
Pango2Rectangle logical_rect;
Pango2Line *line;
int baseline;
if (i >= start)
{
line = pango_layout_iter_get_line (iter);
line = pango2_line_iter_get_line (iter);
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango_layout_iter_get_baseline (iter);
pango2_line_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango2_line_iter_get_line_baseline (iter);
if (i == start)
start_pos = logical_rect.y / 1024.0;
cairo_move_to (cr, logical_rect.x / 1024.0, baseline / 1024.0 - start_pos);
pango_cairo_show_layout_line (cr, line);
pango2_cairo_show_line (cr, line);
}
i++;
}
while (i < end &&
pango_layout_iter_next_line (iter));
pango2_line_iter_next_line (iter));
pango_layout_iter_free (iter);
pango2_line_iter_free (iter);
}
static void
@@ -626,8 +628,8 @@ activate_about (GSimpleAction *action,
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (sysinfo, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (sysinfo, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (sysinfo, "\tGTK \t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
+19 -22
View File
@@ -296,8 +296,8 @@ activate_about (GSimpleAction *action,
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (s, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (s, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
@@ -2081,26 +2081,23 @@ activate (GApplication *app)
builder = gtk_builder_new ();
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
"on_entry_icon_release", (GCallback)on_entry_icon_release,
"on_scale_button_value_changed", (GCallback)on_scale_button_value_changed,
"on_record_button_toggled", (GCallback)on_record_button_toggled,
"on_page_combo_changed", (GCallback)on_page_combo_changed,
"on_range_from_changed", (GCallback)on_range_from_changed,
"on_range_to_changed", (GCallback)on_range_to_changed,
"on_picture_drag_prepare", (GCallback)on_picture_drag_prepare,
"on_picture_drop", (GCallback)on_picture_drop,
"tab_close_cb", (GCallback)tab_close_cb,
"increase_icon_size", (GCallback)increase_icon_size,
"decrease_icon_size", (GCallback)decrease_icon_size,
"reset_icon_size", (GCallback)reset_icon_size,
"osd_frame_pressed", (GCallback)osd_frame_pressed,
"age_entry_changed", (GCallback)age_entry_changed,
"validate_more_details", (GCallback)validate_more_details,
"mode_switch_state_set", (GCallback)mode_switch_state_set,
"level_scale_value_changed", (GCallback)level_scale_value_changed,
"transition_speed_changed", (GCallback)transition_speed_changed,
NULL);
gtk_builder_cscope_add_callback (scope, on_entry_icon_release);
gtk_builder_cscope_add_callback (scope, on_scale_button_value_changed);
gtk_builder_cscope_add_callback (scope, on_record_button_toggled);
gtk_builder_cscope_add_callback (scope, on_page_combo_changed);
gtk_builder_cscope_add_callback (scope, on_range_from_changed);
gtk_builder_cscope_add_callback (scope, on_range_to_changed);
gtk_builder_cscope_add_callback (scope, on_picture_drag_prepare);
gtk_builder_cscope_add_callback (scope, on_picture_drop);
gtk_builder_cscope_add_callback (scope, tab_close_cb);
gtk_builder_cscope_add_callback (scope, increase_icon_size);
gtk_builder_cscope_add_callback (scope, decrease_icon_size);
gtk_builder_cscope_add_callback (scope, osd_frame_pressed);
gtk_builder_cscope_add_callback (scope, age_entry_changed);
gtk_builder_cscope_add_callback (scope, validate_more_details);
gtk_builder_cscope_add_callback (scope, mode_switch_state_set);
gtk_builder_cscope_add_callback (scope, level_scale_value_changed);
gtk_builder_cscope_add_callback (scope, transition_speed_changed);
gtk_builder_set_scope (builder, scope);
g_object_unref (scope);
if (!gtk_builder_add_from_resource (builder, "/org/gtk/WidgetFactory4/widget-factory.ui", &error))
+1 -1
View File
@@ -5,7 +5,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
website_url = "https://www.gtk.org"
authors = "GTK Development Team"
logo_url = "gtk-logo.svg"
license = "GPL-2.1-or-later"
license = "LGPL-2.1-or-later"
description = "The GTK toolkit"
devhelp = true
+1 -1
View File
@@ -5,7 +5,7 @@ repository_url = "https://gitlab.gnome.org/GNOME/gtk.git"
website_url = "https://www.gtk.org"
authors = "GTK Development Team"
logo_url = "gtk-logo.svg"
license = "GPL-2.1-or-later"
license = "LGPL-2.1-or-later"
description = "The GTK toolkit"
dependencies = ["Gdk-4.0"]
devhelp = true
+27
View File
@@ -0,0 +1,27 @@
.. _gtk4-node-editor(1):
=================
gtk4-node-editor
=================
-----------------
Editor render nodes
-----------------
SYNOPSIS
--------
| **gtk4-node-editor** [OPTIONS...]
DESCRIPTION
-----------
``gtk4-node-editor`` is a utility to show and edit render node files.
Such render node files can be obtained e.g. from the GTK inspector.
OPTIONS
-------
``-h, --help``
Show the application help.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 23 KiB

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

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

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

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

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

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 29 KiB

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

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

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

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