Compare commits

..

181 Commits

Author SHA1 Message Date
Matthias Clasen
f4f2c9e25e inspector: Use dropdowns in the visual page
Convert everything in the visual page to dropdowns.
2020-05-30 01:17:40 -04:00
Matthias Clasen
5d53d8edae inspector: Use a dropdown for size groups
Use a GtkDropDown for the modes of size groups.
2020-05-30 01:17:40 -04:00
Matthias Clasen
880ed01acc inspector: Use a dropdown for controllers
Use a GtkDropDown for the phases of event controllers.
2020-05-30 01:17:40 -04:00
Matthias Clasen
ef1993d3dc inspector: Use a dropdown for attribute mapping
Use a GtkDropDown for the attribute mapping editor.
2020-05-30 01:17:40 -04:00
Matthias Clasen
48448bf187 inspector: Use dropdowns in property editor
Replace combo boxes by dropdowns in the property editor.
2020-05-30 01:17:40 -04:00
Matthias Clasen
9af70cf4eb filechooser: Use a dropdown for choices 2020-05-30 01:17:40 -04:00
Matthias Clasen
26e7822ac1 filechooser: Use a dropdown for the filter combo
Replace an internal use of GtkComboBox with GtkDropDown.
2020-05-30 01:17:40 -04:00
Matthias Clasen
58a84b5b16 testsuite: Skip some GtkDropDown properties
The ::factory and ::selected properties need to
be skipped.
2020-05-30 01:17:40 -04:00
Matthias Clasen
e767217acd Add GtkDropDown
This is a simple drop down control using list models.
2020-05-30 01:17:40 -04:00
Matthias Clasen
3c581fe310 gtk-demo: Add a large grid demo
This is similar to the flowbox demo, but much bigger.
2020-05-30 01:17:40 -04:00
Matthias Clasen
a0b6d14862 docs: Add a listview overview section
Add a conceptual overview for all the listmodel-based
widgets.

Fixes: #2214
2020-05-30 01:17:40 -04:00
Matthias Clasen
98618506db listview: Fix keynav
What used to be can-focus is now focusable.
2020-05-30 01:17:40 -04:00
Matthias Clasen
977281d0f7 gtk-demo: Add filtering to the settings demo
A demo of filtering with lists was missing so far.
2020-05-30 01:17:40 -04:00
Matthias Clasen
1753091140 gtk-demo: Demo columnview sorting
Enhance the settings demo to have a sortable column.
2020-05-30 01:17:40 -04:00
Matthias Clasen
113e851ef5 gtk-demo: Cosmetic improvements to the listview demos
Set default sizes, window titles and add more
detail to the descriptions.
2020-05-30 01:13:17 -04:00
Benjamin Otte
1f99f51c19 xxx: isnanf() is some wtf 2020-05-29 19:46:32 -04:00
Matthias Clasen
65f075996a gtk-builder-tool: Minimally validate <binding>
Check that the toplevel property name is legit.
2020-05-29 19:46:32 -04:00
Benjamin Otte
3723b7f118 testsuite: Add tests for GtkTreeListSorter 2020-05-29 19:46:32 -04:00
Matthias Clasen
2d5595d03c Add GtkTreeListRowSorter
This is a special-purpose sorter that can
apply the sorting of another sorter to the
levels of a GtkTreeListModel.
2020-05-29 19:46:32 -04:00
Benjamin Otte
5d96b38984 testcolumnview: Add sorters 2020-05-29 19:46:32 -04:00
Matthias Clasen
affbbb8eb5 column view title: Show sort indicators 2020-05-29 19:46:32 -04:00
Matthias Clasen
7398455391 columnview: Add sorting
This is a somewhat large commit that:

- Adds GtkColumnViewSorter
This is a special-purpose, private sorter implementation which sorts
according to multiple sorters, allowing each individual sorter to be
inverted. This will be used with clickable column view headers.

- Adds a read-only GtkColumnView::sorter property
The GtkColumnView creates a GtkColumnViewSorter at startup that it uses
for this property.

- Adds a writable GtkColumnViewColumn::sorter property
This allows defining per-column sorters. Whenever an application sets a
sorter for a column, the header becomes clickable and whenever
a header is clicked, that column's sorter is prepended to the list of
sorters, unless it is already the first sorter, in which case we invert
its order. No column can be in the list more than once.
2020-05-29 19:46:32 -04:00
Matthias Clasen
7f0d18ed90 listview: Add single-click-activate
Add a single-click-activate property to GtkListView.
2020-05-29 19:46:32 -04:00
Matthias Clasen
9d538e612a listitemwidget: Add single-click-activate
Add a mode to GtkListItemWidget that activates on
single click and selects on hover. Make
GtkListItemManager set this on its items
when its own 'property' of the same name is set.
2020-05-29 19:46:32 -04:00
Matthias Clasen
fd9d407261 builder-tool: Pass through CDATA where it makes sense
This avoids a ton of escaping for
GtkBuilderListItemFactory::bytes.
2020-05-29 19:46:32 -04:00
Matthias Clasen
c753ba190c docs: Reorganize list widgets in their own chapter 2020-05-29 19:46:32 -04:00
Benjamin Otte
117176c0b6 fontchooserwidget: Port to listmodels
The port is kind of evil, in that it stores either a PangoFontFamily or a
PangoFontFace in the list, depending on if the fontchooser is configured
to select fonts or faces.
It also does not cache the font description anymore, so more calls to
pango_font_describe() may happen.

If both of these issues turn out problematic, the fontchooser would need
to resurrect GtkDelayedFontDescription again and put objects of that
type through the model.

These changes depend on Pango 1.46's introduction of listmodels and
various new getters, so the dependency has been upgraded.
2020-05-29 19:46:32 -04:00
Matthias Clasen
5f0f4e060d Add some tests for expression binding
In particular, test that expressios can deal with object == this.
2020-05-29 19:46:32 -04:00
Benjamin Otte
3d1cdff617 expression: Allow passing a this object to bind()
This gives a bit more control over the arguments passed to expressions.
2020-05-29 19:46:32 -04:00
Benjamin Otte
dbca2fcbaf gtk-demo: Add a Clocks demo
This demo is meant to showcase expressions.

It also needs the fixes in glib 2.64 to work properly.
2020-05-29 19:46:32 -04:00
Benjamin Otte
a652363429 xxx: Add a hack to make paintables transform to/from objects
See also: https://gitlab.gnome.org/GNOME/glib/merge_requests/1251
2020-05-29 19:46:32 -04:00
Benjamin Otte
dfa8de2fb2 inspector: Remove private struct for prop editor 2020-05-29 19:46:32 -04:00
Benjamin Otte
f48d81d78d inspector: Make Controller page a GtkWidget 2020-05-29 19:46:32 -04:00
Benjamin Otte
8c0b2d634b inspector: Remove private struct from controllers 2020-05-29 19:46:32 -04:00
Benjamin Otte
b2e7020b53 columnview: Add header
This uses a custom GtkColumnViewTitle widget. So far that widget is
pretty boring, but that will change once we added
resizing, reordering, dnd, sorting, hiding/showing of columns or
whatever UIs we want.
2020-05-29 19:46:32 -04:00
Benjamin Otte
e7a0858a15 tests: Add testcolumnview 2020-05-29 19:46:32 -04:00
Benjamin Otte
f4dbad4b8d columnview: Add a custom LayoutManager
The ColumnView now allocates column widths first and then the individual
rows use the new layout manager which looks at the column allocations to
allocate their children.
2020-05-29 19:46:32 -04:00
Benjamin Otte
94317e30c0 constraint-editor: Don't poke around in widget internals 2020-05-29 19:46:32 -04:00
Benjamin Otte
d56309e2a1 columnview: Fix styling with Adwaita
- Use "treeview" as the node name
- Add .view style class
2020-05-29 19:46:32 -04:00
Benjamin Otte
fbf1c98b23 inspector: Port object tree to GtkColumnView 2020-05-29 19:46:32 -04:00
Benjamin Otte
1c95f7e2d8 columnview: Add GtkColumnViewCell
It's a GtkListItemWidget subclass that tracks the column it belongs to
and allows the column to track it.

We also use this subclass to implement sizing support so columns share
the same size and get resized in sync.
2020-05-29 19:46:32 -04:00
Benjamin Otte
8f9c075069 widget: Add a hook for resizes
It's private, no APIs, we don't talk about it. But we will start using
it very soon, so we can do size request caching in columns and avoid
sizegroups...
2020-05-29 19:46:32 -04:00
Benjamin Otte
c65182af7c columnview: Implement GtkScrollable
Just forward it to the listview for now.
2020-05-29 19:46:32 -04:00
Benjamin Otte
df826ab495 columnview: Add listitems for the columns
They are not aligned in columns yet, but they do exist.
2020-05-29 19:46:32 -04:00
Benjamin Otte
6eea8b9e8b listitemwidget: Lazily create listitems
We only create them in root/unroot (they should be created in
appear/disappear, but that vfunc doesn't exist yet), that way we can
avoid expensive work while the widget isn't used for anything.
2020-05-29 19:46:32 -04:00
Benjamin Otte
755da397bc listitem: Move position/item/selected tracking to widget
This way, we can ensure it's always there when we need it (before the
item gets created) and gone when we don't (if some GC language holds on
to the item after we've destroyed the widget).
2020-05-29 19:46:32 -04:00
Benjamin Otte
e515e880e7 listitemwidget: Add a private struct
I had to rename the item property to list_item anyway, so I could just
do the next step with it.
2020-05-29 19:46:32 -04:00
Benjamin Otte
0730eb70e1 listitemfactory: Simplify
Instead of 6 vfuncs, we now have 3 and rely on the factory keeping track
of what it needs to do.

We're doing lots of dancing from one object to another here, but this
will hopefully get simpler with further commits.
2020-05-29 19:46:32 -04:00
Benjamin Otte
e0b7c82fac listitemfactory: Reorganize vfuncs
Instead of bind/rebind/update/unbind, we now just have update, and the
factories get to interpret that in the way they want.
2020-05-29 19:46:32 -04:00
Benjamin Otte
82e93d9b2e listitem: Make this a GObject
This splits GtkListItem into 2 parts:

1. GtkListItem
   This is purely a GObject with public API for developers who want to
   populate lists. There is no chance to cause conflict with GtkWidget
   properties that the list implementation assumed control over and
   defines a clear boundary.
2. GtkListItemWidget
   The widget part of the listitem. This is not only fully in control of
   the list machinery, the machinery can also use different widget
   implementations for different list widgets like I inted to for
   GtkColumnView.
2020-05-29 19:46:32 -04:00
Benjamin Otte
55dafea2e4 builder: Make gtk_builder_extend_with_template() work with objects
This will be relevant later when we introduce GtkListItem which is not a
GtkWidget.
2020-05-29 19:46:32 -04:00
Benjamin Otte
538897a055 gtk-demo: Add a Coverflow application launcher
This is roughly the simplest demo I could come up with.

But I documented it, so there's your tutorial.

Related: #2214
2020-05-29 19:46:32 -04:00
Benjamin Otte
fcab9e1c07 Add GtkSignalListItemFactory
So the poor Rust users can actually use this.

I would totally not use this ever!
2020-05-29 19:46:32 -04:00
Benjamin Otte
3e4d81417c columnview: Allow adding/removing columns
... and make that work in UI files via <child>, too.
2020-05-29 19:46:32 -04:00
Benjamin Otte
c9874ef736 gtk-demo: Add a minesweeper demo
The demo shows creating ones own listmodel and using it to fill a grid.

I am totally getting the hang of React btw:
500 lines of logic with no UI code and 100 lines of GtkBuilder XML and
I get a sweet UI.
2020-05-29 19:46:32 -04:00
Benjamin Otte
5e9abb956f Add GtkColumnView skeleton
It's just a copy/paste of the listview code with all the internals
gutted. The code doesn't do anything.
2020-05-29 19:46:32 -04:00
Benjamin Otte
930442f616 wip: Add GtkCoverFlow
The widget mostly works out of the box, but some tweaking may be
necessary (in particular in the theme) and the gtk-demo changes might
require removing before this is production-ready.
2020-05-29 19:46:32 -04:00
Benjamin Otte
fb1f719127 listbase: Take over anchor handling
With that, pretty much all code but allocating the widgets is gone from
the gridview and listview.
2020-05-29 19:46:32 -04:00
Benjamin Otte
f4150c6d64 listbase: Add vfuncs to convert positions to/from coordinates
... and use that to implement PageUp/PageDown.

With that, all keyboard handling has been moved to GtkListBase.
2020-05-29 19:46:32 -04:00
Benjamin Otte
045cea31e5 listbase: Move focus moving keybindings here
The focus tracker is not yet moved because that depends on scroll_to()
support and we don't have that yet.
Whoops.
So we use a hack.
2020-05-29 19:46:32 -04:00
Benjamin Otte
aa411acaa2 Remove gtk_selection_model_user_select_item() again
This reverts commit 6a164ab306dad9096bde736c907494c71086d3c4.

The function was awkward and we now have only one caller again, so we
can fold it back into it.
2020-05-29 19:46:32 -04:00
Benjamin Otte
a3b1e7872f listbase: Move orientable implementation here 2020-05-29 19:46:32 -04:00
Benjamin Otte
a6ff878e4c listbase: Move selection handling here 2020-05-29 19:46:32 -04:00
Benjamin Otte
9a3ef0435d listbase: Move item manager here
Nothing really changes, because both ListView and GridView still keep
self->item_manager around, but it's set up to point at the base's item
manager.

This way we can slowly move things to GtkListBase that need the item
manager (like trackers).
2020-05-29 19:46:32 -04:00
Benjamin Otte
a23dfc9861 listbase: Move GtkScrollable implementation
Shared code between GtkGridView and GtkListView.
2020-05-29 19:46:32 -04:00
Benjamin Otte
b7c04ff9a9 Add GtkListBase
This is a base item for GTK's list widgets so they can share some (read:
hopefully a lot of) code.
2020-05-29 19:46:32 -04:00
Benjamin Otte
de36e9d951 gridview: Simplify allocation code
It doesn't fix the bug I'm after, but it looks a lot better.
2020-05-29 19:46:32 -04:00
Benjamin Otte
1eabde4b6f listview: Port various gridview improvements
- Handle anchor as align + top/bottom
  This fixes behavior for cells that are higher than the view
- Add gtk_list_view_adjustment_is_flipped()
  This should fix RTL handling of horizontal lists
- Fix scrolling
  This should make scrolling more reliable, particularly on short lists
  that are only a few pages long.
2020-05-29 19:46:32 -04:00
Benjamin Otte
768b94ab90 demo: Add a file browser demo 2020-05-29 19:46:32 -04:00
Benjamin Otte
417072dd19 gridview: Add move keybindings 2020-05-29 19:46:31 -04:00
Benjamin Otte
3df388e176 gridview: Implement (un)select all
Adds listitem.select-all and listitem.unselect-all actions and installs
the same keybindings as the treeview for those actions.
2020-05-29 19:46:31 -04:00
Benjamin Otte
26065eb200 gridview: Add a focus tracker
... and use that to properly update selections when moving around with
the arrow keys.
2020-05-29 19:46:31 -04:00
Benjamin Otte
e9cc7e0917 gridview: Implement list.scroll-to action 2020-05-29 19:46:31 -04:00
Benjamin Otte
5008a11b57 gridview: Add activation 2020-05-29 19:46:31 -04:00
Benjamin Otte
5c48501961 gridview: Implement minimum row height
We only allocate a certain amount of widgets - and we don't want to run
out of them. So we make all widgets high enough for this to never
happen.
2020-05-29 19:46:31 -04:00
Benjamin Otte
97eb6c24ee gridview: Implement the list.select-item action 2020-05-29 19:46:31 -04:00
Benjamin Otte
c0a7639cbe selectionmodel: Add gtk_selection_model_user_select_item()
I'm not sure this should be public API because it's incredibly awkward.
But it should definitely be shared between list widget implementations.
2020-05-29 19:46:31 -04:00
Benjamin Otte
e795aff583 gridview: Implement anchors and scrolling 2020-05-29 19:46:31 -04:00
Benjamin Otte
5a087b5140 widget: Add gtk_widget_get_size()
A little bit of convenience.
2020-05-29 19:46:31 -04:00
Benjamin Otte
ece4958769 listitemmanager: Handle NULL factory
Just don't call it and create empty listitems.
2020-05-29 19:46:31 -04:00
Timm Bäder
b0b5c2a73f demo: Use a listview as sidebar 2020-05-29 19:46:31 -04:00
Benjamin Otte
4f2bd7331a gtk-demo: Introduce awards
We need a way to get a useful listbox, so here we go!
2020-05-29 19:46:31 -04:00
Benjamin Otte
53b6c7ee7b builder: Autofill scope property of listitemfactory
I couldn't come up with a better way to automatically inherit the scope
in the builder list item factory that didn't involve a magic
incantation in the XML file. And I do not want developers to know magic
incantations to do a thing that should pretty much always be done.
2020-05-29 19:46:31 -04:00
Benjamin Otte
3d1474fba8 builderlistitemfactory: Add scope argument
This way, the scope used when creating builder instances can be
influenced. This way, callbacks can be passed into the factory.
2020-05-29 19:46:31 -04:00
Benjamin Otte
8609ccd43e listitemfactory: Make the builder factory properly buildable
Turn the construct arguments into construct properties so that they can
be set from ui files.
2020-05-29 19:46:31 -04:00
Benjamin Otte
d816070c2a listview: Add move keybindings
My god, these are a lot.

And my god, these are complicated to get right.
2020-05-29 19:46:31 -04:00
Benjamin Otte
438df090e9 listview: Add gtk_list_view_get_position_at_y() 2020-05-29 19:46:31 -04:00
Benjamin Otte
69b57a73c7 listitem: Add "listitem.select" action and keybindings for it
In fact, grab space with all modifiers to toggle selection of the
current item.
2020-05-29 19:46:31 -04:00
Benjamin Otte
38a5f11e1b listview: Add a focus tracker
This ensures that the row with the input focus always stays available,
even when scrolled out of view.
2020-05-29 19:46:31 -04:00
Benjamin Otte
09c90683e1 listview: Implement (un)select all
Adds listitem.select-all and listitem.unselect-all actions and installs
the same keybindings as the treeview for those actions.
2020-05-29 19:46:31 -04:00
Benjamin Otte
e227855b68 listview: Track focus movements and update selection
When focus moves via tab/arrow, we need to select the new item.
2020-05-29 19:46:31 -04:00
Benjamin Otte
51a9d59c07 listview: Implement activation
- a GtkListview::activate signal
- a GtkListItem::activatable property
- activate list items on double clicks and <Enter> presses
2020-05-29 19:46:31 -04:00
Benjamin Otte
bf9f6bca41 treeexpander: Implement input support
This implements all the keybindings from GtkTreeView that can be
supported.

It does not implement expand-all, because supporting that means
causing the TreeListModel to emit lots of create_model vfuncs which in
turn would cause many items-changed signal which in turn would cause
many signal handlers to run which in turn would make "expand-all" very
reentrant, and I'm uneasy about supporting that.

For the mouse, just add a click gesture to the expander icon that toggles
expanded state.
2020-05-29 19:46:31 -04:00
Benjamin Otte
772d7e41f2 listitem: Change focus handling
Focus in the listitem now works like this:
1. If any child can take focus, do not ever attempt
   to take focus.
2. Otherwise, if this item is selectable or activatable,
   allow focusing this widget.

This makes sure every item in a list is focusable for
activation and selection handling, but no useless widgets
get focused and moving focus is as fast as possible.
2020-05-29 19:46:31 -04:00
Benjamin Otte
0e325c3208 inspector: Make the recorder node list use a ListView
It's quite a bit faster now, but the code is also a bit more awkward.

Pain points:

- GtkTreeListModel cannot be created in UI files because it needs
  a CreateModelFunc.
  Using a signal for this doesn't work because autoexpand wants to
  expand the model before the signal handler is connected.

- The list item factory usage is still awkward. It's bearable here
  because the list items are very simple, but still.
2020-05-29 19:46:31 -04:00
Benjamin Otte
9914982c4f inspector: Use a GtkTreeExpander in the object tree 2020-05-29 19:46:31 -04:00
Benjamin Otte
55ef30a322 inspector: Use a treeexpander in the recorder 2020-05-29 19:46:31 -04:00
Benjamin Otte
fe9ec3c742 demo: Add a GSettings tree demo
It is meant to look somewhat like dconf-editor when it is done.

So far, it's just a list.
2020-05-29 19:46:31 -04:00
Benjamin Otte
4ef2b241eb Add GtkTreeExpander
This is a container widget that takes over all the duties of tree
expanding and collapsing.
It has to be a container so it can capture keybindings while focus is
inside the listitem.

So far, this widget does not allow interacting with it, but it shows the
expander arrow in its correct state.

Also, testlistview uses this widget now instead of implementing
expanding itself.
2020-05-29 19:46:31 -04:00
Benjamin Otte
d4e2698cc1 gridview: Actually do something
Implement measuring and allocating items - which makes the items appear
when drawing and allows interacting with the items.

However, the gridview still does not allow any user interaction
(including scrolling).
2020-05-29 19:46:31 -04:00
Benjamin Otte
f80fa21326 listview: Pass the CSS name of listitems to the manager
... instead of hardcoding "row".
2020-05-29 19:46:31 -04:00
Benjamin Otte
8f4affba57 gridview: Implement GtkOrientable
Again, this is just the skeleton, because the Gridview does nothing yet.
2020-05-29 19:46:31 -04:00
Benjamin Otte
1e0f2d9266 gridview: Add factory handling
Just copy the listview APIs.

Code still doesn't do anything with it.
2020-05-29 19:46:31 -04:00
Benjamin Otte
cf6dcc4528 listview: Expose GtkListItemFactory APIs
Due to the many different ways to set factories, it makes sense to
expose them as custom objects.

This makes the actual APIs for the list widgets simpler, because they
can just have a regular "factory" property.

As a convenience function, gtk_list_view_new_with_factory() was added
to make this whole approach easy to use from C.
2020-05-29 19:46:31 -04:00
Benjamin Otte
c587db8420 gtk-demo: Add a rough start at a Weather demo
This demos a horizontal listview.
2020-05-29 19:46:31 -04:00
Benjamin Otte
ed2acc503c listview: Implement GtkOrientable 2020-05-29 19:46:31 -04:00
Benjamin Otte
6aac732e5b tests: Add a rough form of multiselection
Just store a "filechooser::selected" attribute in the GFileInfo if
the file is meant to be selected.
2020-05-29 19:46:31 -04:00
Benjamin Otte
7723bd7a5f listview: Implement extending selections
Shift-clicking to extend selections now also works, imitating the
behavior of normal clicking and Windows Explorer (but not treeview):

1. We track the last selected item (normally, not via extend-clicking).

2. When shift-selecting, we modify the range from the last selected item
   to this item the same way we modify the regular item when not using
   shift:

2a. If Ctrl is not pressed, we select the range and unselect everything
    else.

2b. If Ctrl is pressed, we make the range have the same selection state
    as the last selected item:
    - If the last selected item is selected, select the range.
    - If the last selected item is not selected, unselect the range.
2020-05-29 19:46:31 -04:00
Benjamin Otte
cf6daf8ed5 listview: Add list.scroll_to_item action
The action scrolls the given item into view.

Listitems activate this action when they gain focus.
2020-05-29 19:46:31 -04:00
Benjamin Otte
b6dc00797f testlistview: Load icons async
Speeds up loading by 4x, because out of view icons aren't loaded
anymore.
2020-05-29 19:46:31 -04:00
Benjamin Otte
2c2421f735 testlistview: Port to directory list 2020-05-29 19:46:31 -04:00
Benjamin Otte
a74ab8b908 listitemfactory: Add a factory for ui files
Reuse <template> magic to initialize GtkListItems. This feels
amazingly hacky, but it also amazingly worked on the first try.
2020-05-29 19:46:31 -04:00
Benjamin Otte
efd0b7ff44 listitemfactory: Split implementation out
.. into gtkfunctionslistitemfactory.c

Now we can add a different implmenetation.
2020-05-29 19:46:31 -04:00
Benjamin Otte
4669f172e4 listitemfactory: vfuncify
No functional changes other than a new indirection.
2020-05-29 19:46:31 -04:00
Benjamin Otte
a8e6439688 listitemfactory: Sanitize APIs
Make sure the APIs follow a predictable path:

setup
  bind
    rebind/update (0-N times)
  unbind
teardown

This is the first step towards providing multiple different factories.
2020-05-29 19:46:31 -04:00
Benjamin Otte
fd12785a71 listview: Add gtk_list_view_set_show_separators()
Do the same thing that GtkListBox does in commit
0249bd4f8a
2020-05-29 19:46:31 -04:00
Benjamin Otte
5674117168 listitemmanager: Add trackers
... and replace the anchor tracking with a tracker.

Trackers track an item through the list across changes and ensure that
this item (and potentially siblings before/after it) are always backed
by a GtkListItem and that if the item gets removed a replacement gets
chosen.

This is now used for tracking the anchor but can also be used to add
trackers for the cursor later.
2020-05-29 19:46:31 -04:00
Benjamin Otte
1585084238 listitemmanager: Simplify
Remove a bunch of API from the headers that isn't used anymore and then
refactor code to not call it anymore.

In particular, get rid of GtkListItemManagerChange and replace it with a
GHashTable.
2020-05-29 19:46:31 -04:00
Benjamin Otte
03c213ba11 gridview: Implement GtkScrollable
We can now scroll all the nothing we display.

We also clip it properly.
2020-05-29 19:46:31 -04:00
Benjamin Otte
d423560e3c listitemmanager: Move list of listitems here
All the listview infrastructure moved with it, so the next step is
moving that back...
2020-05-29 19:46:31 -04:00
Benjamin Otte
088d18c9da wayland: Remove function declaration for nonexisting function 2020-05-29 19:46:31 -04:00
Benjamin Otte
c6296b696a gridview: Add API for setting number of columns
The API isn't used yet.
2020-05-29 19:46:31 -04:00
Benjamin Otte
6bcb34ac27 gtk: Add a GtkGridView skeleton 2020-05-29 19:46:31 -04:00
Benjamin Otte
60a2df6bb5 listitem: Add a press gesture to select the item
This is implemented by using actions, which are a neat trick to get to
allow the ListItem to call functions on the ListView without actually
needing to be aware of it.
2020-05-29 19:46:31 -04:00
Benjamin Otte
5d3c7acae3 listview: Add initial support for displaying selections 2020-05-29 19:46:31 -04:00
Benjamin Otte
fb95d44f0d listview: Reset listitems' CSS animations when rebinding
This way, newly displayed rows don't play an unselect animation (text
fading in) when they are unselected, but the row was previously used for
a selected item.
2020-05-29 19:46:31 -04:00
Benjamin Otte
526acb79a4 listview: Add selection properties to ListItem
This just brings the infrastructure into place, we're not using the
properties yet.
2020-05-29 19:46:31 -04:00
Benjamin Otte
9fbc1f8c14 listview: Try to keep the list items in order when scrolling
Instead of just destroying all items and then recreating them (or even
hide()ing and then show()ing them again (or even even repositioning
them in the widget tree)), just try to reust them in the order they are.

This works surprisingly well when scrolling and most/all widgets
just moved.
2020-05-29 19:46:30 -04:00
Benjamin Otte
4d0db44a2b listlistmodel: Add gtk_list_list_model_item_moved()
Use it to fix a case that just said g_warning ("oops").

Apparently I had forgotten the case where a container moved a child
in the widget tree.
2020-05-29 19:46:30 -04:00
Benjamin Otte
a04085a3ff listitemmanager: Switch from "insert_before" to "insert_after" argumnet
We reorder widgets start to end, so when reusing a list item, we
correctly know the previous sibling for that list item, but not the
next sibling yet. We just know the widget it should ultimately be in
front of.
So we can do a more correct guess of the list item's place in the widget
tree if we think about where to place an item like this.

Actually using this change will come in the next commit.
2020-05-29 19:46:30 -04:00
Benjamin Otte
70cf9fca3a testlistview: Create widgets only once
Previously, we were recreating all widgets every time the list item was
rebound, which caused a lot of extra work every time we scrolled.

Now we keep the widgets around and only set their properties again when
the item changes.
2020-05-29 19:46:30 -04:00
Benjamin Otte
88770cae09 testlistview: Show the row number
Always show the current row. This is mostly useful for debugging, not
for beauty.
2020-05-29 19:46:30 -04:00
Benjamin Otte
fd7b833a3f listview: Only allocate necesary rows
This is the big one.

The listview only allocates 200 rows around the visible row now.
Everything else is kept in ListRow instances with row->widget == NULL.

For rows without a widget, we assign the median height of the child
widgets as the row's height and then do all calculations as if there
were widgets that had requested that height (like setting adjustment
values or reacting to adjustment value changes).

When the view is scrolled, we bind the 200 rows to the new visible area,
so that the part of the listview that can be seen is always allocated.
2020-05-29 19:46:30 -04:00
Benjamin Otte
93deba171e listview: Change anchor handling again
The anchor is now a tuple of { listitem, align }.

Using the actual list item allows keeping the anchor across changes
in position (ie when lists get resorted) while still being able to fall
back to positions (list items store their position) when an item gets
removed.

The align value is in the range [0..1] and defines where in the visible
area to do the alignment.
0.0 means to align the top of the row with the top of the visible area,
1.0 aligns the bottom of the widget with the visible area and 0.5 keeps
the center of the widget at the center of the visible area.
It works conceptually the same as percentages in CSS background-position
(where the background area and the background image's size are matched
the same way) or CSS transform-origin.
2020-05-29 19:46:30 -04:00
Benjamin Otte
1d1b69b359 listview: Change how binding is done
We now don't let the functions create widgets for the item from the
listmodel, instead we hand out a GtkListItem for them to add a widget
to.

GtkListItems are created in advance and can only be filled in by the
binding code by gtk_container_add()ing a widget.
However, they are GObjects, so they can provide properties that the
binding code can make use of - either via notify signals or GBinding.
2020-05-29 19:46:30 -04:00
Benjamin Otte
68272e773c listitem: Add gtk_list_item_get_position()
Also refactor the whole list item management yet again.

Now, list item APIs doesn't have bind/unbind functions anymore, but only
property setters.

The item factory is the only one doing the binding.
As before, the item manager manages when items need to be bound.
2020-05-29 19:46:30 -04:00
Benjamin Otte
b07338fc08 tests: Make animating listview do random resorts 2020-05-29 19:46:30 -04:00
Benjamin Otte
29a10cb829 listview: Change change management
Add a GtkListItemManagerChange object that tracks all removed list
rows during an item-changed signal so they can be added back later.
2020-05-29 19:46:30 -04:00
Benjamin Otte
67b824f33c listview: Make the listitemmanager stricter
Require that items created with the manager get destroyed via the
manager.

To that purpose, renamed create_list_item() to acquire_list_item() and
add a matching release_list_item() function.

This way, the manager can in the future keep track of all items and
cache information about them.
2020-05-29 19:46:30 -04:00
Benjamin Otte
a44780f602 listview: Add GtkListItem
GtkListItem is a generic row widget that is supposed to replace
GtkListBoxRow and GtkFlowBoxChild.
2020-05-29 19:46:30 -04:00
Benjamin Otte
6a52f19b18 listview: Add GtkListItemManager
It's all stubs for now, but here's the basic ideas about what
this object is supposed to do:

(1) It's supposed to be handling all the child GtkWidgets that are
    used by the listview, so that the listview can concern
    itself with how many items it needs and where to put them.
(2) It's meant to do the caching of widgets that are not (currently)
    used.
(3) It's meant to track items that remain in the model across
    items-changed emissions and just change position.
(2) It's code that can be shared between listview and potential
    other widgets like a GridView.

It's also free to assume that the number of items it's supposed to
manage doesn't grow too much, so it's free to use O(N) algorithms.
2020-05-29 19:46:30 -04:00
Benjamin Otte
ab432878f9 listview: Implement an anchor
The anchor selection is very basic: just anchor the top row.

That's vastly better than any other widget already though.
2020-05-29 19:46:30 -04:00
Benjamin Otte
74fbb6f428 tests: Add a test for a permanently changing listview
This is mostly for dealing with proper anchoring and can be used to
check that things don't scroll or that selection and focus handling
properly works.

For comparison purposes, a ListBox is provided next to it.
2020-05-29 19:46:30 -04:00
Benjamin Otte
a0f353ef3d listview: Implement GtkScrollable
Scrolling in a very basic form is also supported
2020-05-29 19:46:30 -04:00
Benjamin Otte
16a12f4733 listview: Make widget actually do something
The thing we're actually doing is create and maintain a widget for every
row. That's it.

Also add a testcase using this. The testcase quickly allocates too many
rows though and then becomes unresponsive though. You have been warned.
2020-05-29 19:46:30 -04:00
Benjamin Otte
7859781abc listview: Introduce GtkListItemFactory
Thisis the abstraction I intend to use for creating widgets and binding
them to the item out of the listview.

For now this is a very dumb wrapper around the functions that exist in
the API.

But it leaves the freedom to turn this into public API, make an
interface out of it and most of all write different implementations, in
particular one that uses GtkBuilder.
2020-05-29 19:46:30 -04:00
Benjamin Otte
3f1c02cb42 gtk: Add a GtkListView skeleton 2020-05-29 19:46:30 -04:00
Benjamin Otte
28a274149d builder: Add <binding> tag
The tag contains an expression that it then gtk_expression_bind()s to
the object it is contained in.
2020-05-29 19:46:30 -04:00
Benjamin Otte
e99c499158 builder: Allow text content in <lookup>
<lookup>foo</lookup>
is now short for
  <lookup>
    <constant>foo</constant>
  </lookup>
ie it looks up the object with the given name so it can then do a
property lookup with it.

This is the most common operation, so it's a nice shortcut.
2020-05-29 19:46:30 -04:00
Benjamin Otte
4905647f0e builder: Allow <constant> without a type
A constant without a type is assumed to be an object. This is the most
common case and allows
  <constant>foo</constant>
without requiring updates to the type whenever the foo object changes.
2020-05-29 19:46:30 -04:00
Benjamin Otte
0c8daa10db builder: Make <lookup> type optional
If no type is set, use the type of the expression.
2020-05-29 19:46:30 -04:00
Benjamin Otte
d39011b59d gtk-demo: Make fishbowl info text use bindings
It's a good demo for how bindings can format multiple properties into an
informative string with 1 line of code (and 5 lines of XML).
2020-05-29 19:46:30 -04:00
Matthias Clasen
c0fb606bf8 sorter: Add tests
Some basic tests for GtkSorter.
2020-05-29 19:46:30 -04:00
Benjamin Otte
b493322a99 sortlistmodel: Make sort stable
The sort of the sortlistmodel is now stable with respect to the original
list model.

That means that if the sorter compares items as equal, the model
will make sure those items keep the order they were in in the original
model.

Or in other words: The model guarantees a total order based on the
item's position in the original model.
2020-05-29 19:46:30 -04:00
Benjamin Otte
0bac3ca807 sortlistmodel: Redo the way we store the items
We need to keep this data around for changes in future commits where we
make the sorting stable.

An important part of the new data handling is that the unsorted list
needs to always be dealt with before the sorted list - upon creation we
rely on the unsorted iter and upon destruction, the sorted sequence
frees the entry leaving the unsorted sequence pointer invalid.

This change does not do any behavioral changes.
2020-05-29 19:46:30 -04:00
Matthias Clasen
d104d874a9 Redo sort list model with GtkSorter
Reshuffle the api to take full advantage
of GtkSorter. Update all callers.
2020-05-29 19:46:30 -04:00
Matthias Clasen
dc2bb3e22a Add GtkNumericSorter
This sorter compares numbers obtained from items
by evaluating an expression.
2020-05-29 19:46:30 -04:00
Matthias Clasen
a596779064 Add GtkMultiSorter
This is a sorter that tries multiple sorters in turn.
2020-05-29 19:46:30 -04:00
Matthias Clasen
e160941d48 Add GtkStringSorter
This is a GtkSorter implementation collating strings
2020-05-29 19:46:30 -04:00
Matthias Clasen
a2581c3f01 Add GtkCustomSorter
This is a GtkSorter implementation which uses a GCompareDataFunc.
2020-05-29 19:46:30 -04:00
Matthias Clasen
76494d2a5d Add GtkSorter
This is a helper object for sorting, similar to GtkFilter.
2020-05-29 19:46:30 -04:00
Benjamin Otte
a9b19db81d Add GtkOrdering
This is an enum that we're gonna use soon and it's worth introducing as a
separate commit.

The intention is to have meaningful names for return values in
comparison functions.
2020-05-29 19:46:30 -04:00
Matthias Clasen
0178dd9a94 More expression tests
Test type mismatches, and the this pointer
during evaluation.
2020-05-29 19:46:30 -04:00
Benjamin Otte
6762d7f1d6 expression: Invalidate bindings before destroying them
Use a weak ref to invalidate bindings. Make sure that this happens
before creating any watches, so that notifies from the
watched expression about changes will not trigger set_property() calls
during dispose()/finalize().

Invalidating also ensures that the watches aren't removed, which can
trigger warnings if the watches are watching the object itself, and the
weak refs cannot be removed anymore.
2020-05-29 19:46:30 -04:00
Benjamin Otte
f493b22421 expression: Add gtk_expression_bind()
Add a simple way to bind expressions to object properties. This is
essentially the thing to replace g_object_bind_property().
2020-05-29 19:46:30 -04:00
Benjamin Otte
b4479ea118 testsuite: Add expression tests 2020-05-29 19:46:30 -04:00
Benjamin Otte
7751d54e98 expression: Add the ability to watch an expression 2020-05-29 19:46:30 -04:00
Benjamin Otte
037106c27d builder: Add support for parsing expressions 2020-05-29 19:46:30 -04:00
Benjamin Otte
4730d50968 filter: Add tests
Some basic tests for GtkFilter
2020-05-29 19:46:30 -04:00
Benjamin Otte
a541d89d8c Add GtkMultiFilter, GtkAnyFilter, GtkEveryFilter
GtkMultiFilter is the abstract base class for managing multiple child
filter.
GtkAnyFilter and GtkEveryFilter are the actual implementations.
2020-05-29 19:46:30 -04:00
Benjamin Otte
9cc97fd678 filter: Add GtkStringFilter
Users provide a search filter and an expression that evaluates the items
to a string and then the filter goes and matches those strings to the
search term.
2020-05-29 19:46:30 -04:00
Benjamin Otte
9c34fc9d21 expression: Make property expression allow subexpressions 2020-05-29 19:46:30 -04:00
Benjamin Otte
da3ae70b78 expression: Add GtkObjectExpression
Weak refs break cycles...
2020-05-29 19:46:30 -04:00
Benjamin Otte
e4d0ee3fd9 Add GtkExpression
GtkExpressions allow looking up values from objects.

There are a few simple expressions, but the main one is the closure
expression that just calls a user-provided closure.
2020-05-29 19:46:30 -04:00
Benjamin Otte
d665a8bf51 filterlistmodel: Rewrite to use GtkFilter 2020-05-29 19:46:30 -04:00
Benjamin Otte
1266f76dc0 tests: Remove testtreemodel test
testlistview does everything this test does.
2020-05-29 19:46:30 -04:00
Benjamin Otte
f4ec02ef40 Add GtkCustomFilter 2020-05-29 19:46:30 -04:00
Benjamin Otte
eecc27c330 Add GtkFilter 2020-05-29 19:46:30 -04:00
Benjamin Otte
34cce1dea6 Add GtkDirectoryList
Adds a new listmodel called GtkDirectoryList that lists the children of
a GFile as GFileInfos.

This is supposed to be used by the filechooser.
2020-05-29 19:46:30 -04:00
Benjamin Otte
c56cb1e89b builder: Allow <property bind /> for objects
Previously, object properties had to always be set to a value.
This now works without it.
2020-05-29 19:46:30 -04:00
Benjamin Otte
b800053911 eventcontrollermotion: Remove mode argument
It's not used and nobody has documented how it's meant to work anyway.
2020-05-29 19:46:30 -04:00
6039 changed files with 1540997 additions and 848125 deletions

View File

@@ -1,10 +1,9 @@
# See https://www.apertis.org/policies/coding_conventions/#code-formatting
# See https://wiki.apertis.org/Guidelines/Coding_conventions#Code_formatting
BasedOnStyle: GNU
AlwaysBreakAfterDefinitionReturnType: All
BreakBeforeBinaryOperators: None
BinPackParameters: false
SpaceAfterCStyleCast: true
PointerAlignment: Right
# Our column limit is actually 80, but setting that results in clang-format
# making a lot of dubious hanging-indent choices; disable it and assume the
# developer will line wrap appropriately. clang-format will still check

View File

@@ -1,32 +0,0 @@
# SPDX-FileCopyrightText: 2021 The GTK Authors
# SPDX-License-Identifier: CC0-1.0
root = true
[*]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
[*.[ch]]
indent_size = 2
indent_style = space
insert_final_newline = true
# For the legacy tabs which still exist in the code:
tab_width = 8
[*.ui]
indent_size = 2
indent_style = space
insert_final_newline = true
[*.xml]
indent_size = 2
indent_style = space
[meson.build]
indent_size = 2
indent_style = space
[*.md]
max_line_length = 80

View File

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

1
.gitignore vendored
View File

@@ -1,2 +1 @@
/subprojects/*/
.flatpak-builder/

View File

@@ -1,14 +1,8 @@
include:
- project: 'gnome/citemplates'
file: 'flatpak/flatpak_ci_initiative.yml'
stages:
- check
- build
- analysis
- docs
- flatpak
- publish
- deploy
.cache-paths: &cache-paths
@@ -22,52 +16,31 @@ stages:
# Common variables
variables:
COMMON_MESON_FLAGS: "-Dwerror=true -Dcairo:werror=false -Dgi-docgen:werror=false -Dgraphene:werror=false -Dlibepoxy:werror=false -Dlibsass:werror=false -Dpango:werror=false -Dsassc:werror=false -Dgdk-pixbuf:werror=false -Dglib:werror=false -Dlibcloudproviders:werror=false -Dlibpng:werror=false -Dlibtiff:werror=false -Dsysprof:werror=false -Dwayland-protocols:werror=false -Dharfbuzz:werror=false -Dfreetype2:werror=false -Dfontconfig:werror=false -Dfribidi:werror=false -Dlibffi:werror=false -Dlibjpeg-turbo:werror=false -Dmutest:werror=false -Dpixman:werror=false -Dproxy-libintl:werror=false"
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled -Dbuild-testsuite=true -Dintrospection=enabled"
MESON_TEST_TIMEOUT_MULTIPLIER: 3
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v49"
COMMON_MESON_FLAGS: "--fatal-meson-warnings --werror"
MESON_TEST_TIMEOUT_MULTIPLIER: 2
workflow:
rules:
# run merge request pipelines
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# do not run branch pipelines if corresponding merge requests exist...
# (this avoids duplicate pipelines)
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
# ...but otherwise run branch pipelines
- if: $CI_COMMIT_BRANCH
# run tag pipelines
- if: $CI_COMMIT_TAG
default:
retry:
max: 2
when:
- 'runner_system_failure'
- 'stuck_or_timeout_failure'
- 'scheduler_failure'
- 'api_failure'
interruptible: true
.only-default:
only:
- branches
except:
- tags
style-check-diff:
image: $FEDORA_IMAGE
stage: check
when: manual
extends: .only-default
image: registry.gitlab.gnome.org/gnome/gtk/fedora:v17
stage: .pre
allow_failure: true
script:
- .gitlab-ci/run-style-check-diff.sh
.build-fedora-default:
image: $FEDORA_IMAGE
image: registry.gitlab.gnome.org/gnome/gtk/fedora:v17
artifacts:
when: always
reports:
junit:
- "${CI_PROJECT_DIR}/_build/report-x11.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gl.xml"
- "${CI_PROJECT_DIR}/_build/report-wayland_gles2.xml"
- "${CI_PROJECT_DIR}/_build/report-broadway.xml"
name: "gtk-${CI_COMMIT_REF_NAME}"
paths:
@@ -75,111 +48,50 @@ 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/gsk/compare/*/*/*.node"
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
- "${CI_PROJECT_DIR}/_build/testsuite/headless/*/*.log"
- "${CI_PROJECT_DIR}/_build_hello/meson-logs"
cache:
key: "$CI_JOB_NAME"
paths:
- _ccache/
- subprojects/gdk-pixbuf/
- subprojects/glib/
- subprojects/graphene/
- subprojects/libepoxy/
- subprojects/pango/
fedora-x86_64:
extends: .build-fedora-default
stage: build
needs: []
variables:
EXTRA_MESON_FLAGS: "--buildtype=debug --default-library=both"
script:
- .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH"
- meson subprojects download
- meson subprojects update --reset
- meson setup
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
${BACKEND_FLAGS}
${FEATURE_FLAGS}
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS}
-Dx11-backend=true
-Dwayland-backend=true
-Dbroadway-backend=true
-Dvulkan=yes
-Dprofiler=true
_build
- meson compile -C _build
- .gitlab-ci/run-tests.sh _build x11 gtk
# only repeat test runs that are likely affected by test setups
- .gitlab-ci/run-tests.sh _build wayland_gl gtk:gdk,gtk:gsk-gl
- ninja -C _build
- .gitlab-ci/run-tests.sh _build x11
- .gitlab-ci/run-tests.sh _build wayland
- .gitlab-ci/run-tests.sh _build broadway
release-build:
extends: .build-fedora-default
stage: build
needs: []
variables:
EXTRA_MESON_FLAGS: "--buildtype=release"
script:
- .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH"
- meson subprojects download
- meson subprojects update --reset
- mkdir _install
- meson setup
--prefix=${CI_PROJECT_DIR}/_install
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
${BACKEND_FLAGS}
${FEATURE_FLAGS}
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS}
-Dx11-backend=true
-Dwayland-backend=true
-Dbroadway-backend=true
-Dvulkan=yes
_build
- meson compile -C _build
- meson install -C _build
- PKG_CONFIG_PATH=${CI_PROJECT_DIR}/_install/lib64/pkgconfig:${CI_PROJECT_DIR}/_install/share/pkgconfig meson setup _build_hello examples/hello
- LD_LIBRARY_PATH=${CI_PROJECT_DIR}/_install/lib64 meson compile -C _build_hello
- .gitlab-ci/run-tests.sh _build wayland gtk
# only repeat test runs that are likely affected by test setups
- .gitlab-ci/run-tests.sh _build wayland_gles2 gtk:gdk,gtk:gsk-gl
fedora-clang:
extends: .build-fedora-default
stage: build
needs: []
variables:
EXTRA_MESON_FLAGS: "--buildtype=release"
script:
- .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH"
- export CC=clang
- meson subprojects download
- meson subprojects update --reset
- meson setup
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
${BACKEND_FLAGS}
${FEATURE_FLAGS}
_build
- meson compile -C _build
fedora-mingw64:
extends: .build-fedora-default
stage: build
needs: []
before_script:
- sudo dnf install -y
mingw64-filesystem
mingw64-gcc
mingw64-binutils
mingw64-cairo
mingw64-gdk-pixbuf
mingw64-gstreamer1-plugins-bad-free
mingw64-glib2
mingw64-libepoxy
mingw64-pango
# mingw64-graphene (rawhide)
script:
- .gitlab-ci/show-info-linux.sh
- export PATH="$HOME/.local/bin:$PATH"
- pip3 install --user meson~=1.0
- meson subprojects download
- meson subprojects update --reset
- meson -Dintrospection=disabled -Dgraphene:introspection=disabled _build
- meson compile -C _build
- ninja -C _build
- .gitlab-ci/run-tests.sh _build x11
.mingw-defaults:
stage: build
@@ -198,90 +110,14 @@ fedora-mingw64:
- subprojects/libepoxy/
- subprojects/pango/
msys2-mingw64:
msys2-mingw32:
extends: .mingw-defaults
needs: []
variables:
MSYSTEM: "MINGW64"
MSYSTEM: "MINGW32"
CHERE_INVOKING: "yes"
artifacts:
when: always
expose_as: 'Windows_DLL_MSYS2_64_bit_toolchain'
paths:
- "${CI_PROJECT_DIR}/_build/gtkdll.tar.gz"
macos:
rules:
# Do not run in forks as the runner is not available there.
# (except for dehesselle who maintains the runner)
- if: $CI_PROJECT_NAMESPACE != "GNOME" && $CI_PROJECT_NAMESPACE != "dehesselle"
when: never
- if: $RUNNER == "macosintel"
variables:
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
NINJA_PKG: $CI_API_V4_URL/projects/30745/packages/generic/ninja_macos/v1.11.1.1+9/ninja-1.11.1.1-cp38-cp38-macosx_11_0_x86_64.whl
when: manual
allow_failure: true
- if: $RUNNER == "macosarm"
variables:
SDKROOT: /opt/sdks/MacOSX11.3.sdk
NINJA_PKG: ninja==1.11.1.1
stage: build
parallel:
matrix:
- RUNNER: [ "macosintel", "macosarm" ]
tags:
- ${RUNNER}
needs: []
variables:
EXTRA_MESON_FLAGS: ""
BACKEND_FLAGS: "-Dx11-backend=false -Dbroadway-backend=true"
FEATURE_FLAGS: "-Dmedia-gstreamer=disabled -Dintrospection=enabled -Dgobject-introspection:werror=false"
TMPDIR: /Users/Shared/work/tmp
PIP_CACHE_DIR: /Users/Shared/build/cache
PIPENV_CACHE_DIR: $PIP_CACHE_DIR
PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR
before_script:
- .gitlab-ci/show-info-macos.sh
- python3 -m venv .venv
# Building the introspection feature requires pkg-config and bison.
- curl -L $CI_API_V4_URL/projects/30437/packages/generic/pkgconfig/v0.29.2+10/pkg-config-0.29.2+10_$(uname -m).tar.xz | tar -C .venv -xJ
- curl -L $CI_API_V4_URL/projects/30438/packages/generic/bison/v3.8.2+3/bison-3.8.2+3_$(uname -m).tar.xz | tar -C .venv -xJ
- source .venv/bin/activate
- pip3 install meson==1.3.2 $NINJA_PKG
# We're not setting up ccache here on purpose as it accelerates the build
# so much that it triggers race conditions in the gobject-introspection
# subproject.
script:
- meson setup
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
${BACKEND_FLAGS}
${FEATURE_FLAGS}
_build
- meson compile -C _build
artifacts:
when: always
paths:
- "${CI_PROJECT_DIR}/_build/meson-logs"
vs2017-x64:
# TODO: Uncomment this when ready to merge.
# rules:
# - if: $CI_PROJECT_NAMESPACE == "GNOME"
stage: build
tags:
- win32-ps
needs: []
script:
- .gitlab-ci/test-msvc.bat
artifacts:
when: always
paths:
- "${CI_PROJECT_DIR}/_build/meson-logs"
.flatpak-defaults:
image: "quay.io/gnome_infrastructure/gnome-runtime-images:gnome-master"
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master
stage: flatpak
allow_failure: true
tags:
@@ -289,195 +125,86 @@ vs2017-x64:
artifacts:
paths:
- "${APPID}-dev.flatpak"
- 'repo.tar'
expire_in: 1 day
rules:
# Only build Flatpak bundles automatically on main
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_BRANCH != "main"
when: "manual"
script:
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
flatpak:demo:
extends: '.flatpak-defaults'
needs: []
# Manual jobs, for branches and MRs
.flatpak-manual:
extends: .flatpak-defaults
when: manual
# Only build Flatpak bundles automatically on master
.flatpak-master:
extends: .flatpak-defaults
only:
- master
flatpak-manual:demo:
extends: .flatpak-manual
variables:
APPID: org.gtk.Demo4
flatpak:demo:aarch64:
extends: '.flatpak-defaults'
needs: []
tags:
- flatpak-aarch64
flatpak-master:demo:
extends: .flatpak-master
variables:
APPID: org.gtk.Demo4
flatpak:widget-factory:
extends: '.flatpak-defaults'
needs: []
flatpak-manual:widget-factory:
extends: .flatpak-manual
variables:
APPID: org.gtk.WidgetFactory4
flatpak:widget-factory:aarch64:
extends: '.flatpak-defaults'
needs: []
tags:
- flatpak-aarch64
flatpak-master:widget-factory:
extends: .flatpak-master
variables:
APPID: org.gtk.WidgetFactory4
flatpak:icon-browser:
extends: '.flatpak-defaults'
needs: []
flatpak-manual:icon-browser:
extends: .flatpak-manual
variables:
APPID: org.gtk.IconBrowser4
flatpak:icon-browser:aarch64:
extends: '.flatpak-defaults'
needs: []
tags:
- flatpak-aarch64
flatpak-master:icon-browser:
extends: .flatpak-master
variables:
APPID: org.gtk.IconBrowser4
flatpak:node-editor:
extends: '.flatpak-defaults'
needs: []
variables:
APPID: org.gtk.gtk4.NodeEditor
flatpak:node-editor:aarch64:
extends: '.flatpak-defaults'
needs: []
tags:
- flatpak-aarch64
variables:
APPID: org.gtk.gtk4.NodeEditor
# Publish the demo apps to the GNOME Nightly repo
# https://wiki.gnome.org/Apps/Nightly
# https://gitlab.gnome.org/GNOME/Initiatives/-/wikis/DevOps-with-Flatpak
nightly demo:
extends: '.publish_nightly'
needs: ['flatpak:demo']
nightly demo aarch64:
extends: '.publish_nightly'
needs: ['flatpak:demo:aarch64']
nightly factory:
extends: '.publish_nightly'
needs: ['flatpak:widget-factory']
nightly factory aarch64:
extends: '.publish_nightly'
needs: ['flatpak:widget-factory:aarch64']
nightly icon-browser:
extends: '.publish_nightly'
needs: ['flatpak:icon-browser']
nightly icon-browser aarch64:
extends: '.publish_nightly'
needs: ['flatpak:icon-browser:aarch64']
nightly node-editor:
extends: '.publish_nightly'
needs: ['flatpak:node-editor']
nightly node-editor aarch64:
extends: '.publish_nightly'
needs: ['flatpak:node-editor:aarch64']
static-scan:
image: $FEDORA_IMAGE
image: registry.gitlab.gnome.org/gnome/gtk/fedora:v16
stage: analysis
needs: []
variables:
EXTRA_MESON_FLAGS: "--buildtype=debug"
script:
- export PATH="$HOME/.local/bin:$PATH"
- meson setup
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
${BACKEND_FLAGS}
${FEATURE_FLAGS}
_scan_build
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} _scan_build
- ninja -C _scan_build scan-build
artifacts:
paths:
- _scan_build/meson-logs
allow_failure: true
# Run tests with the address sanitizer. We need to turn off introspection
# and f16c, since they are incompatible with asan
asan-build:
image: $FEDORA_IMAGE
tags: [ asan ]
stage: analysis
needs: []
variables:
script:
- export PATH="$HOME/.local/bin:$PATH"
- CC=clang meson setup
--buildtype=debugoptimized
-Db_sanitize=address
-Db_lundef=false
-Dbuild-demos=false
-Dbuild-tests=false
-Dbuild-examples=false
-Dintrospection=disabled
-Df16c=disabled
_build
- ninja -C _build
- .gitlab-ci/run-tests.sh _build wayland gtk
reference:
image: $FEDORA_IMAGE
image: registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v19
stage: docs
needs: []
variables:
EXTRA_MESON_FLAGS: "--buildtype=release"
script:
- export PATH="$HOME/.local/bin:$PATH"
- meson setup
${COMMON_MESON_FLAGS}
--buildtype=release
--force-fallback-for=gdk-pixbuf,pango
-Dintrospection=enabled
-Ddocumentation=true
-Dgdk-pixbuf:gtk_doc=true
-Dpango:documentation=true
-Dbuild-demos=false
-Dbuild-examples=false
-Dbuild-tests=false
-Dbuild-testsuite=false
_build
- meson compile -C _build
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} -Dgtk_doc=true _build
- ninja -C _build gdk4-doc gsk4-doc gtk4-doc
- mkdir -p _reference/
- mv _build/docs/reference/gdk/gdk4/ _reference/gdk4/
- mv _build/docs/reference/gdk/gdk4-x11/ _reference/gdk4-x11/
- mv _build/docs/reference/gdk/gdk4-wayland/ _reference/gdk4-wayland/
- mv _build/docs/reference/gsk/gsk4/ _reference/gsk4/
- mv _build/docs/reference/gtk/gtk4/ _reference/gtk4/
- mv _build/subprojects/pango/docs/Pango/ _reference/Pango/
- mv _build/subprojects/pango/docs/PangoCairo/ _reference/PangoCairo/
- mv _build/subprojects/pango/docs/PangoFc/ _reference/PangoFc/
- mv _build/subprojects/pango/docs/PangoFT2/ _reference/PangoFT2/
- mv _build/subprojects/pango/docs/PangoOT/ _reference/PangoOT/
- mv _build/subprojects/pango/docs/PangoXft/ _reference/PangoXft/
- mv _build/subprojects/gdk-pixbuf/docs/gdk-pixbuf/ _reference/gdk-pixbuf/
- mv _build/subprojects/gdk-pixbuf/docs/gdk-pixdata/ _reference/gdk-pixdata/
- mv _build/docs/reference/gdk/html/ _reference/gdk/
- mv _build/docs/reference/gsk/html/ _reference/gsk/
- mv _build/docs/reference/gtk/html/ _reference/gtk/
artifacts:
paths:
- _reference
publish-docs:
image: fedora:latest
stage: publish
interruptible: false
needs: ['reference']
pages:
stage: deploy
script:
- "curl -X POST -F token=${PAGES_TRIGGER_TOKEN} -F ref=docs-gtk-org https://gitlab.gnome.org/api/v4/projects/665/trigger/pipeline"
rules:
- if: $CI_COMMIT_REF_NAME == "main"
- mv _reference/ public/
artifacts:
paths:
- public
only:
- master

View File

@@ -14,14 +14,11 @@ 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
- [ ] Run `./run-docker.sh build --base ${image} --version ${number}`
- [ ] Run `./run-docker.sh push --base ${image} --version ${number}`
- [ ] Run `./run-docker.sh build --base ${image} --base-version ${number}`
- [ ] Run `./run-docker.sh push --base ${image} --base-version ${number}`
once the Docker image is built; you may need to log in by using
`docker login` or `podman login`
- [ ] Update the `image` keys in the `.gitlab-ci.yml` file with the new
@@ -33,18 +30,9 @@ recently uploaded image in the registry.
- [ ] Write a new `${image}.Dockerfile` with the instructions to set up
a build environment
- [ ] Add the `pip3 install meson` incantation
- [ ] Run `./run-docker.sh build --base ${image} --version ${number}`
- [ ] Run `./run-docker.sh push --base ${image} --version ${number}`
- [ ] Run `./run-docker.sh build --base ${image} --base-version ${number}`
- [ ] Run `./run-docker.sh push --base ${image} --base-version ${number}`
- [ ] Add the new job to `.gitlab-ci.yml` referencing the image
- [ ] Open a merge request with your changes and let it run
### Checklist for Adding a new dependency to a CI image
Our images are layered, and the base (called fedora-base) contains
all the rpm payload. Therefore, adding a new dependency is a 2-step
process:
1. [ ] Build and upload fedora-base:$version+1
1. [ ] Build and upload fedora:$version+1 based on fedora-base:version+1
[registry]: https://gitlab.gnome.org/GNOME/gtk/container_registry

View File

@@ -0,0 +1,88 @@
FROM fedora:31
RUN dnf -y install \
adwaita-icon-theme \
atk-devel \
at-spi2-atk-devel \
avahi-gobject-devel \
cairo-devel \
cairo-gobject-devel \
ccache \
clang \
clang-analyzer \
colord-devel \
cups-devel \
dbus-daemon \
dbus-x11 \
dejavu-sans-mono-fonts \
desktop-file-utils \
diffutils \
elfutils-libelf-devel \
fribidi-devel \
gcc \
gcc-c++ \
gdk-pixbuf2-devel \
gdk-pixbuf2-modules \
gettext \
git \
glib2-devel \
glib2-static \
glibc-devel \
glibc-headers \
gobject-introspection-devel \
graphene-devel \
gstreamer1-devel \
gstreamer1-plugins-good \
gstreamer1-plugins-bad-free-devel \
gstreamer1-plugins-base-devel \
gtk-doc \
hicolor-icon-theme \
iso-codes \
itstool \
json-glib-devel \
lcov \
libattr-devel \
libepoxy-devel \
libffi-devel \
libmount-devel \
librsvg2 \
libselinux-devel \
libXcomposite-devel \
libXcursor-devel \
libXcursor-devel \
libXdamage-devel \
libXfixes-devel \
libXi-devel \
libXinerama-devel \
libxkbcommon-devel \
libXrandr-devel \
libXrender-devel \
libXtst-devel \
libxslt \
mesa-dri-drivers \
mesa-libEGL-devel \
mesa-libwayland-egl-devel \
ninja-build \
pango-devel \
pcre-devel \
pcre-static \
python3 \
python3-jinja2 \
python3-pip \
python3-pygments \
python3-wheel \
redhat-rpm-config \
sassc \
sysprof-devel \
systemtap-sdt-devel \
vulkan-devel \
wayland-devel \
wayland-protocols-devel \
weston \
weston-libs \
which \
xorg-x11-server-Xvfb \
&& dnf clean all
RUN pip3 install meson==0.53.1

View File

@@ -0,0 +1,12 @@
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v19
RUN dnf -y install pandoc
ARG HOST_USER_ID=5555
ENV HOST_USER_ID ${HOST_USER_ID}
RUN useradd -u $HOST_USER_ID -ms /bin/bash user
USER user
WORKDIR /home/user
ENV LANG C.UTF-8

View File

@@ -1,112 +1,8 @@
FROM fedora:39
RUN dnf -y install \
adwaita-icon-theme \
avahi-gobject-devel \
cairo-devel \
cairo-gobject-devel \
ccache \
clang \
clang-analyzer \
clang-tools-extra \
colord-devel \
cups-devel \
dbus-daemon \
dbus-x11 \
dejavu-sans-mono-fonts \
desktop-file-utils \
diffutils \
elfutils-libelf-devel \
expat-devel \
fribidi-devel \
gcc \
gcc-c++ \
gdk-pixbuf2-devel \
gdk-pixbuf2-modules \
gettext \
git \
glib2-devel \
glib2-static \
glibc-devel \
glibc-headers \
glslc \
gnupg2 \
gobject-introspection-devel \
graphene-devel \
graphviz \
gstreamer1-devel \
gstreamer1-plugins-good \
gstreamer1-plugins-bad-free-devel \
gstreamer1-plugins-base-devel \
hicolor-icon-theme \
iso-codes \
itstool \
json-glib-devel \
lcov \
libasan \
libattr-devel \
libcloudproviders-devel \
libepoxy-devel \
libffi-devel \
libjpeg-turbo-devel \
libmount-devel \
libpng-devel \
librsvg2 \
libselinux-devel \
libtiff-devel \
libubsan \
libXcomposite-devel \
libXcursor-devel \
libXcursor-devel \
libXdamage-devel \
libXfixes-devel \
libXi-devel \
libXinerama-devel \
libxkbcommon-devel \
libXrandr-devel \
libXrender-devel \
libXtst-devel \
libxslt \
mesa-dri-drivers \
mesa-libEGL-devel \
mesa-libGLES-devel \
meson \
mutter \
ninja-build \
pango-devel \
pcre-devel \
pcre-static \
pipewire \
pipewire-gstreamer \
python3 \
python3-docutils \
python3-gobject \
python3-jinja2 \
python3-markdown \
python3-packaging \
python3-pip \
python3-pydbus \
python3-pygments \
python3-typogrify \
python3-wheel \
redhat-rpm-config \
sassc \
vulkan-devel \
wayland-devel \
wayland-protocols-devel \
weston \
weston-libs \
which \
wireplumber \
xorg-x11-server-Xvfb \
&& dnf clean all
# Enable sudo for wheel users
RUN sed -i -e 's/# %wheel/%wheel/' -e '0,/%wheel/{s/%wheel/# %wheel/}' /etc/sudoers
FROM registry.gitlab.gnome.org/gnome/gtk/fedora-base:v19
ARG HOST_USER_ID=5555
ENV HOST_USER_ID ${HOST_USER_ID}
RUN useradd -u $HOST_USER_ID -G wheel -ms /bin/bash user
RUN useradd -u $HOST_USER_ID -ms /bin/bash user
USER user
WORKDIR /home/user

View File

@@ -16,18 +16,17 @@ flatpak-builder \
flatpak build ${builddir} meson \
--prefix=/app \
--libdir=/app/lib \
--buildtype=debugoptimized \
--buildtype=release \
-Dx11-backend=true \
-Dwayland-backend=true \
-Dprint-backends=file \
-Dbuild-tests=false \
-Dbuild-testsuite=false \
-Dbuild-examples=false \
-Dintrospection=disabled \
-Dbuild-demos=true \
-Dprofile=devel \
-Dintrospection=false \
-Ddemos=true \
_flatpak_build
flatpak build --env=CI_COMMIT_SHORT_SHA=$CI_COMMIT_SHORT_SHA ${builddir} ninja -C _flatpak_build install
flatpak build ${builddir} ninja -C _flatpak_build install
flatpak-builder \
--user --disable-rofiles-fuse \
@@ -41,8 +40,3 @@ flatpak build-bundle \
${appid}-dev.flatpak \
--runtime-repo=https://nightly.gnome.org/gnome-nightly.flatpakrepo \
${appid}
# to be consumed by the nightly publish jobs
if [[ $CI_COMMIT_BRANCH == main ]]; then
tar cf repo.tar ${repodir}
fi

View File

@@ -185,8 +185,6 @@ ul.images li {
<li><img alt="ref" src="{{ failure.image_data.ref }}" /></li>
<li><img alt="out" src="{{ failure.image_data.out }}" /></li>
<li><img alt="diff" src="{{ failure.image_data.diff }}" /></li>
<li><a href="{{ failure.image_data.refnode }}">ref node</a></li>
<li><a href="{{ failure.image_data.outnode }}">out node</a></li>
</ul>
{% endif %}
</li>
@@ -270,7 +268,7 @@ aparser.add_argument('--job-id', metavar='ID',
default=None)
aparser.add_argument('--branch', metavar='NAME',
help='Branch of the project being tested',
default='main')
default='master')
aparser.add_argument('--output', metavar='FILE',
help='The output HTML file, stdout by default',
type=argparse.FileType('w', encoding='UTF-8'),
@@ -313,8 +311,6 @@ for line in args.infile:
image_data = {
'ref': os.path.join(args.reftest_output_dir, '{}.ref.png'.format(basename)),
'out': os.path.join(args.reftest_output_dir, '{}.out.png'.format(basename)),
'refnode': os.path.join(args.reftest_output_dir, '{}.ref.node'.format(basename)),
'outnode': os.path.join(args.reftest_output_dir, '{}.out.node'.format(basename)),
'diff': os.path.join(args.reftest_output_dir, '{}.diff.png'.format(basename)),
}
@@ -324,7 +320,7 @@ for line in args.infile:
units.append(unit)
report = {}
report['date'] = datetime.datetime.now(datetime.UTC)
report['date'] = datetime.datetime.utcnow()
report['locale_date'] = report['date'].strftime("%c")
report['project_name'] = args.project_name
report['backend'] = args.backend

View File

@@ -27,7 +27,7 @@ aparser.add_argument('--job-id', metavar='ID',
default='Unknown')
aparser.add_argument('--branch', metavar='NAME',
help='Branch of the project being tested',
default='main')
default='master')
aparser.add_argument('--output', metavar='FILE',
help='The output file, stdout by default',
type=argparse.FileType('w', encoding='UTF-8'),
@@ -44,7 +44,7 @@ outfile = args.output
testsuites = ET.Element('testsuites')
testsuites.set('id', '{}/{}'.format(args.job_id, args.branch))
testsuites.set('package', args.project_name)
testsuites.set('timestamp', datetime.datetime.now(datetime.UTC).isoformat(timespec='minutes'))
testsuites.set('timestamp', datetime.datetime.utcnow().isoformat(timespec='minutes'))
suites = {}
for line in args.infile:

View File

@@ -1,154 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021 GNOME Foundation
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
/**
* RedHat Fonts taken from https://github.com/RedHatOfficial/RedHatFont
* License: SIL Open Font License 1.1 http://scripts.sil.org/OFL
*/
@import url('https://fonts.googleapis.com/css2?family=Noto+Serif:ital,wght@0,400;0,700;1,400;1,700&family=Red+Hat+Display:ital,wght@0,400;0,500;0,700;0,900;1,400;1,500;1,700;1,900&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Noto+Serif:ital,wght@0,400;0,700;1,400;1,700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600&display=swap');
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-Regular.woff2") format("woff2"),
url("RedHatDisplay-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
font-display: fallback;
}
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-RegularItalic.woff2") format("woff2"),
url("RedHatDisplay-RegularItalic.woff") format("woff");
font-style: italic;
font-weight: 400;
font-display: fallback;
}
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-Medium.woff2") format("woff2"),
url("RedHatDisplay-Medium.woff") format("woff");
font-style: normal;
font-weight: 500;
font-display: fallback;
}
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-MediumItalic.woff2") format("woff2"),
url("RedHatDisplay-MediumItalic.woff") format("woff");
font-style: italic;
font-weight: 500;
font-display: fallback;
}
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-Bold.woff2") format("woff2"),
url("RedHatDisplay-Bold.woff") format("woff");
font-style: normal;
font-weight: 700;
font-display: fallback;
}
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-BoldItalic.woff2") format("woff2"),
url("RedHatDisplay-BoldItalic.woff") format("woff");
font-style: italic;
font-weight: 700;
font-display: fallback;
}
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-Black.woff2") format("woff2"),
url("RedHatDisplay-Black.woff") format("woff");
font-style: normal;
font-weight: 900;
font-display: fallback;
}
@font-face {
font-family: "RedHatDisplayWeb";
src: local('RedHatDisplayWeb'),
url("RedHatDisplay-BlackItalic.woff2") format("woff2"),
url("RedHatDisplay-BlackItalic.woff") format("woff");
font-style: italic;
font-weight: 900;
font-display: fallback;
}
@font-face {
font-family: "RedHatTextWeb";
src: local('RedHatTextWeb'),
url("RedHatText-Regular.woff2") format("woff2"),
url("RedHatText-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
font-display: fallback;
}
@font-face {
font-family: "RedHatTextWeb";
src: local('RedHatTextWeb'),
url("RedHatText-RegularItalic.woff2") format("woff2"),
url("RedHatText-RegularItalic.woff") format("woff");
font-style: italic;
font-weight: 400;
font-display: fallback;
}
@font-face {
font-family: "RedHatTextWeb";
src: local('RedHatTextWeb'),
url("RedHatText-Medium.woff2") format("woff2"),
url("RedHatText-Medium.woff") format("woff");
font-style: normal;
font-weight: 700;
font-display: fallback;
}
@font-face {
font-family: "RedHatTextWeb";
src: local('RedHatTextWeb'),
url("RedHatText-MediumItalic.woff2") format("woff2"),
url("RedHatText-MediumItalic.woff") format("woff");
font-style: italic;
font-weight: 700;
font-display: fallback;
}
@font-face {
font-family: "RedHatTextWeb";
src: local('RedHatTextWeb'),
url("RedHatText-Bold.woff2") format("woff2"),
url("RedHatText-Bold.woff") format("woff");
font-style: normal;
font-weight: 900;
font-display: fallback;
}
@font-face {
font-family: "RedHatTextWeb";
src: local('RedHatTextWeb'),
url("RedHatText-BoldItalic.woff2") format("woff2"),
url("RedHatText-BoldItalic.woff") format("woff");
font-style: italic;
font-weight: 900;
font-display: fallback;
}

View File

@@ -1,138 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128"
height="128"
id="svg6843"
sodipodi:version="0.32"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
version="1.0"
sodipodi:docname="gtk-logo.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
inkscape:export-filename="/home/ebassi/Pictures/gtk-logo-256.png"
inkscape:export-xdpi="192"
inkscape:export-ydpi="192">
<defs
id="defs6845">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="-50 : 600 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="700 : 600 : 1"
inkscape:persp3d-origin="300 : 400 : 1"
id="perspective13" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="2.8284271"
inkscape:cx="69.874353"
inkscape:cy="64.313526"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:document-units="px"
inkscape:grid-bbox="true"
width="128px"
height="128px"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid7947" />
</sodipodi:namedview>
<metadata
id="metadata6848">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:date />
<dc:creator>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:publisher>
<dc:identifier />
<dc:source />
<dc:relation />
<dc:language />
<dc:subject>
<rdf:Bag />
</dc:subject>
<dc:coverage />
<dc:description />
<dc:contributor>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:contributor>
<cc:license
rdf:resource="" />
</cc:Work>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
sodipodi:nodetypes="ccccc"
id="path6976"
d="M 20.88413,30.82696 L 53.816977,55.527708 L 107.33282,39.060543 L 70.587303,17.177763 L 20.88413,30.82696 z"
style="fill:#729fcf;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" />
<path
id="path6978"
d="M 22.94243,82.287118 L 20.88413,30.82696 L 53.816977,55.527708 L 53.816977,111.10486 L 22.94243,82.287118 z"
style="fill:#e40000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" />
<path
id="path6980"
d="M 53.816977,111.10486 L 103.21619,90.5207 L 107.33282,39.060543 L 53.816977,55.527708 L 53.816977,111.10486 z"
style="fill:#7fe719;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline" />
<path
sodipodi:nodetypes="ccc"
id="path6982"
d="M 23.216626,81.319479 L 70.48573,67.361442 L 103.38422,90.444516"
style="opacity:1;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
id="path6984"
d="M 70.434539,17.875593 L 70.434539,66.984877"
style="opacity:1;fill:#babdb6;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -1,149 +0,0 @@
<!--
SPDX-FileCopyrightText: 2021 GNOME Foundation
SPDX-License-Identifier: LGPL-2.1-or-later
-->
<!DOCTYPE html>
<html lang="en">
<head>
<title>GTK Documentation</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8" />
<meta property="og:site_name" content="https://docs.gtk.org"/>
<meta property="og:title" content="GTK Documentation"/>
<meta property="og:url" content="https://docs.gtk.org"/>
<meta property="og:type" content="website"/>
<meta property="og:description" content="API reference for GTK"/>
<meta name="twitter:title" content="GTK Documentation"/>
<meta name="twitter:url" content="https://docs.gtk.org"/>
<meta name="twitter:card" content="summary"/>
<link rel="canonical" href="https://docs.gtk.org"/>
<link rel="stylesheet" href="style.css" type="text/css" />
<script src="main.js"></script>
<!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
</head>
<body>
<div id="body-wrapper" tabindex="-1">
<nav class="sidebar">
<div class="section">
<img src="gtk-logo.svg" class="logo"/>
</div>
<div class="section">
<h5>Sections</h5>
<div class="links">
<a href="#user-interface">User interface</a>
<a href="#core-libraries">Core libraries</a>
</div>
</div>
</nav>
<button id="btn-to-top" class="hidden"><span class="up-arrow"></span></button>
<section id="main" class="content">
<header>
<h1>GTK Documentation</h1>
</header>
<div class="toggle-wrapper">
<h4 id="user-interface">
User interface
<a href="#user-interface" class="anchor"></a>
</h4>
<div class="docblock">
<h5 id="gdk">GTK</h5>
<p>GTK is the primary library used to construct user interfaces. It
provides user interface controls and signal callbacks to respond to
user actions.</p>
<p><a href="https://docs.gtk.org/gtk4/">GTK API reference</a></p>
</div>
<div class="docblock">
<h5 id="gdk">GSK</h5>
<p>An intermediate layer which provides a rendering API implemented using Cairo, OpenGL or Vulkan.</p>
<p><a href="https://docs.gtk.org/gsk4/">GSK API reference</a></p>
</div>
<div class="docblock">
<h5 id="gdk">GDK</h5>
<p>An intermediate layer which isolates GTK from the details of the windowing system.</p>
<p><a href="https://docs.gtk.org/gdk4/">GDK API reference</a></p>
</div>
<div class="docblock">
<h5 id="pango">Pango</h5>
<p>Pango is the core text and font handling library used in GTK
applications. It has extensive support for the different writing
systems used throughout the world.</p>
<p><a href="https://docs.gtk.org/Pango/">Pango API reference</a></p>
</div>
<div class="docblock">
<h5 id="gdk-pixbuf">GdkPixbuf</h5>
<p>GdkPixbuf is a library for image loading and manipulation.</p>
<p><a href="https://docs.gtk.org/gdk-pixbuf/">GdkPixbuf API reference</a></p>
</div>
<div class="docblock">
<h5 id="cairo">Cairo</h5>
<p>Cairo is a 2D graphics library with support for multiple output
devices. It is designed to produce consistent, high quality output
on all media.</p>
<p><a href="https://www.cairographics.org/manual/" class="external">Cairo API reference</a></p>
</div>
</div>
<div class="toggle-wrapper">
<h4 id="core-libraries" style="display:flex;">
Core libraries
<a href="#core-libraries" class="anchor"></a>
</h4>
<div class="docblock">
<h5 id="glib">GLib</h5>
<p>GLib provides the core application building blocks for libraries
and applications written in C. It provides common data types
used in GTK, the main loop implementation, and a large set of
utility functions for strings and general portability across
different platforms.</p>
<p><a href="https://developer.gnome.org/glib/" class="external">GLib API reference</a></p>
</div>
<div class="docblock">
<h5 id="gobject">GObject</h5>
<p>GObject provides the object system used by GTK.</p>
<p><a href="https://developer.gnome.org/gobject/" class="external">GObject API reference</a></p>
</div>
<div class="docblock">
<h5 id="gio">GIO</h5>
<p>GIO provides a portable, modern and easy-to-use file system
abstraction API for accessing local and remote files; a set of
low and high level abstractions over the <a href="https://www.freedesktop.org/wiki/Software/dbus/" class="external">DBus</a>
IPC specification; an application settings API; portable networking
abstractions; and additional utilities for writing asynchronous
operations without blocking the user interface of your application.</p>
<p><a href="https://developer.gnome.org/gio/" class="external">GIO API reference</a></p>
</div>
</div>
</section>
<footer>
</footer>
</div>
</body>
</html>

View File

@@ -1,140 +0,0 @@
// SPDX-FileCopyrightText: 2021 GNOME Foundation
//
// SPDX-License-Identifier: LGPL-2.1-or-later
// eslint-disable-next-line no-unused-vars
function hasClass(elem, className) {
return elem && elem.classList && elem.classList.contains(className);
}
// eslint-disable-next-line no-unused-vars
function addClass(elem, className) {
if (!elem || !elem.classList) {
return;
}
elem.classList.add(className);
}
// eslint-disable-next-line no-unused-vars
function removeClass(elem, className) {
if (!elem || !elem.classList) {
return;
}
elem.classList.remove(className);
}
function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
function onEach(arr, func, reversed) {
if (arr && arr.length > 0 && func) {
var length = arr.length;
var i;
if (reversed !== true) {
for (i = 0; i < length; ++i) {
if (func(arr[i]) === true) {
return true;
}
}
} else {
for (i = length - 1; i >= 0; --i) {
if (func(arr[i]) === true) {
return true;
}
}
}
}
return false;
}
function onEachLazy(lazyArray, func, reversed) {
return onEach(
Array.prototype.slice.call(lazyArray),
func,
reversed);
}
// eslint-disable-next-line no-unused-vars
function hasOwnProperty(obj, property) {
return Object.prototype.hasOwnProperty.call(obj, property);
}
window.addEventListener("load", function() {
"use strict;"
var main = document.getElementById("main");
var btnToTop = document.getElementById("btn-to-top");
function labelForToggleButton(isCollapsed) {
if (isCollapsed) {
return "+";
}
return "\u2212";
}
function createToggle(isCollapsed) {
var toggle = document.createElement("a");
toggle.href = "javascript:void(0)";
toggle.className = "collapse-toggle";
toggle.innerHTML = "[<span class=\"inner\">"
+ labelForToggleButton(isCollapsed)
+ "</span>]";
return toggle;
}
function toggleClicked() {
if (hasClass(this, "collapsed")) {
removeClass(this, "collapsed");
this.innerHTML = "[<span class=\"inner\">"
+ labelForToggleButton(false)
+ "</span>]";
onEachLazy(this.parentNode.getElementsByClassName("docblock"), function(e) {
removeClass(e, "hidden");
});
} else {
addClass(this, "collapsed");
this.innerHTML = "[<span class=\"inner\">"
+ labelForToggleButton(true)
+ "</span>]";
onEachLazy(this.parentNode.getElementsByClassName("docblock"), function(e) {
addClass(e, "hidden");
});
}
}
onEachLazy(document.getElementsByClassName("toggle-wrapper"), function(e) {
let sectionHeader = e.querySelector(".section-header");
let fragmentMatches = sectionHeader !== null && location.hash === "#" + sectionHeader.getAttribute('id');
collapsedByDefault = hasClass(e, "default-hide") && !fragmentMatches;
var toggle = createToggle(collapsedByDefault);
toggle.onclick = toggleClicked;
e.insertBefore(toggle, e.firstChild);
if (collapsedByDefault) {
addClass(toggle, "collapsed");
onEachLazy(e.getElementsByClassName("docblock"), function(d) {
addClass(d, "hidden");
});
}
});
function scrollBackTop(e) {
e.preventDefault();
window.scroll({
top: 0,
behavior: 'smooth',
});
}
function toggleScrollButton() {
if (window.scrollY < 400) {
addClass(btnToTop, "hidden");
} else {
removeClass(btnToTop, "hidden");
}
}
window.onscroll = toggleScrollButton;
btnToTop.onclick = scrollBackTop;
}, false);

View File

@@ -1,747 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021 GNOME Foundation
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
@import url("fonts.css");
/*********************************
* LIGHT THEME
*********************************/
:root {
/* colors */
--text-color: #333;
--text-color-muted: #999;
--primary: rgb(28, 118, 228);
--body-bg: #fff;
--sidebar-primary: rgb(144, 194, 255);
--sidebar-bg: #151515;
--sidebar-selected-bg: var(--primary);
--sidebar-text-color: #fafafa;
--sidebar-padding: 1.5em;
/* boxes, e.g. code blocks */
--box-bg: rgba(135, 135, 135, 0.085);
--box-radius: 0.35rem;
--box-padding: 0.75rem;
--box-margin: 0.75rem 0;
--box-text-color: #111;
/* typography */
--body-font-family: "Noto Serif",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
--body-font-scale: 0.95;
--body-font-size: calc(var(--body-font-scale) * clamp(16px, 1vw, 20px));
--body-font-weight: normal;
--monospace-font-family: "Source Code Pro", monospace;
--monospace-font-size: calc(0.86 * var(--body-font-size)); /* Monospace fonts are very different in terms of font-sizes. Adjust this value to scale it */
--heading-font-family: "Red Hat Display", var(--body-font-family);
--heading-weight: 900;
--heading-font-scale: 1.05;
--heading-small-font-family: var(--heading-font-family);
--heading-small-weight: 600;
--heading-small-font-scale: 1;
--heading-table-font-family: var(--heading-font-family);
--heading-table-weight: 600;
--heading-docblock-color: #6d6d6d; /* docblocks have headings from source comments. we want them to differ.*/
--heading-docblock-scale: 0.9; /* docblocks have headings from source comments. we want them to differ.*/
--symbol-font-family: var(--heading-font-family);
--symbol-font-weight: 500;
--symbol-font-scale: 1;
--table-font-size: 0.92em; /* Tables often contain lots information. It's better to scale them down a big to get more sutff fitted inside */
/* misc */
--prefered-content-width: 90ch; /* The preferred width for the readable content */
--anchor-sign: "#";
}
/*********************************
* DARK THEME (overrides)
*********************************/
@media (prefers-color-scheme: dark) {
:root {
--primary: rgb(144, 194, 255);
--text-color: #f6f6f6;
--text-color-muted: #686868;
--body-bg: #121212;
--sidebar-primary: rgb(144, 194, 255);
--sidebar-bg: #1e1e1e;
--sidebar-selected-bg: rgb(17, 112, 228);
--sidebar-text-color: #fafafa;
--box-bg: rgba(135, 135, 135, 0.1);
--box-text-color: #fff;
--heading-docblock-color: #b7b7b7;
}
/* fix dark theme syntax highlighting with a filter (for now) */
.highlight pre span {
filter: brightness(6);
}
}
/*********************************
* GENERAL STYLING
*********************************/
*,
*:before,
*:after {
box-sizing: border-box;
}
::-moz-selection {
color: white;
background: var(--primary);
}
::selection {
color: white;
background: var(--primary);
}
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background: rgba(128, 128, 128, 0.6);
}
::-webkit-scrollbar-thumb:hover {
background: rgba(128, 128, 128, 1);
}
::-webkit-scrollbar-track {
background: rgba(128, 128, 128, 0.15);
}
* {
scrollbar-width: initial;
}
body {
font: 16px/1.5 var(--body-font-family);
font-weight: var(--body-font-weight);
font-size: var(--body-font-size);
margin: 0;
padding: 0;
position: relative;
-webkit-font-feature-settings: "kern", "liga";
-moz-font-feature-settings: "kern", "liga";
font-feature-settings: "kern", "liga";
color: var(--text-color);
background: var(--body-bg);
}
h1, h2, h3, h4, h5, h6 {
font-family: var(--heading-font-family);
font-weight: var(--heading-weight);
margin: 1.75em 0 0.75em 0;
display: flex;
align-items: center;
}
h1 {
font-size: calc(1.75em * var(--heading-font-scale));
}
header h1 {
margin-top: 0;
}
h2 {
font-size: calc(1.4em * var(--heading-font-scale));
}
h3 {
font-size: calc(1.2em * var(--heading-font-scale));
}
header h3 {
color: var(--text-color-muted);
margin-bottom: 0;
}
h4, h5 {
font-size: calc(1em * var(--heading-font-scale));
}
h6 {
font-size: calc(1em * var(--heading-small-font-scale));
font-family: var(--heading-small-font-family);
font-weight: var(--heading-small-weight);
}
ol, ul {
padding-left: 1rem;
}
ul ul, ol ul, ul ol, ol ol {
margin-bottom: .6em;
}
p {
margin: 0 0 .6em 0;
}
a {
color: var(--primary);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
summary {
outline: none;
}
blockquote {
border-left: 3px solid var(--primary);
background: var(--box-bg);
padding: var(--box-padding);
border-radius: var(--box-radius);
margin: var(--box--margin);
}
code,
pre {
font-family: var(--monospace-font-family);
font-size: var(--monospace-font-size);
color: var(--box-text-color);
}
pre {
background: var(--box-bg);
padding: var(--box-padding);
border-radius: var(--box-radius);
overflow: auto;
}
code {
background: var(--box-bg);
padding: 0 0.35em;
border-radius: 0.35rem;
word-break: break-word;
}
a > code {
color: var(--primary);
}
pre pre,
pre code {
padding: 0;
margin: 0;
font-size: 1em;
background: none;
color: inherit;
}
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
font-family: inherit;
font-weight: inherit;
font-size: 0.85em;
}
strong, b {
font-weight: 600;
}
/* fix unwanted margins in tables, code, lists and blockquotes */
li > *:first-child,
li > *:first-child > *:first-child,
li > *:first-child > *:first-child > *:first-child,
td > *:first-child,
td > *:first-child > *:first-child,
td > *:first-child > *:first-child > *:first-child,
pre > *:first-child,
pre > *:first-child > *:first-child,
pre > *:first-child > *:first-child > *:first-child,
blockquote > *:first-child,
blockquote > *:first-child > *:first-child,
blockquote > *:first-child > *:first-child > *:first-child {
margin-top: 0;
}
li > *:last-child,
li > *:last-child > *:last-child,
li > *:last-child > *:last-child > *:last-child,
td > *:last-child,
td > *:last-child > *:last-child,
td > *:last-child > *:last-child > *:last-child,
pre > *:last-child,
pre > *:last-child > *:last-child,
pre > *:last-child > *:last-child > *:last-child,
blockquote > *:last-child,
blockquote > *:last-child > *:last-child,
blockquote > *:last-child > *:last-child > *:last-child {
margin-bottom: 0;
}
/*********************************
* PAGE STRUCTURE
*********************************/
#body-wrapper {
display: flex;
flex-wrap: nowrap;
flex-direction: row;
}
#body-wrapper:focus {
outline: none;
}
#main {
position: relative;
flex-grow: 1;
min-width: 0;
box-shadow: 0 0 134px rgba(0, 0, 0, 0.1);
}
footer {
width: 100%;
display: none;
}
/*********************************
* Button
*********************************/
#btn-to-top {
position: fixed;
bottom: 12px;
right: 32px;
z-index: 1000;
border-radius: 50%;
width: 42px;
height: 42px;
border: 1px solid var(--primary);
background: var(--box-bg);
color: var(--text-color);
cursor: pointer;
text-transform: none;
}
#btn-to-top > .up-arrow:after {
content: "🡅"
}
/*********************************
* SIDEBAR
*********************************/
.sidebar {
scrollbar-width: thin;
background: var(--sidebar-bg);
border-right: 1px solid var(--sidebar-bg);
min-width: 40ch;
padding: var(--sidebar-padding);
color: var(--sidebar-text-color);
position: sticky;
top: 0;
z-index: 2;
height: 100vh;
overflow-y: auto;
}
.sidebar a,
.sidebar a:hover {
text-decoration: none;
}
.sidebar .logo {
display: block;
margin: 2rem auto 0 auto;
width: 70%;
}
.sidebar .section > ul > li {
margin-right: -10px;
}
.sidebar .section h3, .sidebar .section h5 {
text-align: left;
padding-left: 0.5rem;
padding-right: 0.5rem;
font-weight: var(--heading-weight);
}
.sidebar .section h5 {
font-size: 1em;
margin-bottom: 0.5em;
}
.sidebar .namespace > h3 {
margin-bottom: 0;
padding: 0;
font-size: 1.5em;
text-transform: uppercase;
font-weight: 900;
}
.sidebar .namespace > p {
font-size: 0.9em;
opacity: 0.8;
padding-left: 0.5rem;
}
.sidebar .section {
padding-left: 0.5rem;
padding-right: 0.5rem;
}
.sidebar .links {
margin-bottom: 1rem;
}
.sidebar .section a {
display: block;
text-overflow: ellipsis;
overflow: hidden;
transition: background-color 150ms ease;
color: var(--sidebar-primary);
border-radius: var(--box-radius);
padding: 0.2rem 0.5rem;
margin-bottom: 0.15rem;
}
.sidebar .section a:hover {
background-color: rgba(127, 127, 127, 0.2);
color: var(--sidebar-text-color);
}
.sidebar .section a.current {
background-color: var(--sidebar-selected-bg);
color: white;
}
.sidebar .search {
box-sizing: border-box;
text-align: center;
}
.sidebar .search input[type="text"] {
border-color: transparent;
width: 100%;
border: 1px solid #ccc;
border-radius: 50px;
padding: 6px 12px;
display: inline-block;
font-size: 80%;
box-shadow: inset 0 1px 3px #ddd;
transition: border .3s linear;
}
/*********************************
* ANCHORS & TOGGLERS
*********************************/
.anchor,
.md-anchor {
position: relative;
z-index: 1;
text-decoration: none;
padding: 0 0.5em;
color: var(--text-color-muted);
}
.anchor:hover,
.md-anchor:hover {
color: var(--primary);
}
.anchor:not([href]),
.md-anchor:not([href]) {
display: none;
}
.anchor:before,
.md-anchor:before {
content: var(--anchor-sign); /*'§'*/
}
.toggle-wrapper {
position: relative;
}
.collapse-toggle {
position: absolute;
right: 0;
left: -2em;
white-space: nowrap;
text-decoration: none;
font-size: 0.8em;
color: transparent;
}
.collapse-toggle > .inner {
width: 1rem;
height: 1rem;
border-radius: calc(0.75 * var(--box-radius));
display: inline-flex;
justify-content: center;
align-items: center;
text-align: center;
vertical-align: middle;
color: var(--box-text-color);
position: relative;
left: -0.25rem;
font-family: monospace;
font-size: 0.7rem;
font-weight: bold;
background: var(--box-bg);
}
/*********************************
* UTILITY
*********************************/
.deprecated > h6 > a {
opacity: 0.65;
}
.hidden {
display: none !important;
}
/*********************************
* CONTENT STYLING
*********************************/
.content {
padding: 2em 4em;
overflow: visible;
max-width: calc(var(--prefered-content-width) + 8em);
}
.content table:not(.table-display) {
border-spacing: 0 0.25rem;
}
.content td {
vertical-align: top;
}
.content td:first-child {
padding-right: 1rem;
}
.content td p:first-child {
margin-top: 0;
}
.content td h1, .content td h2 {
margin-left: 0;
font-size: 1.1em;
}
.content tr:first-child td {
border-top: 0;
}
kbd {
display: inline-block;
padding: 3px 5px;
font: 15px monospace;
line-height: 10px;
vertical-align: middle;
border: solid 1px;
border-radius: 3px;
box-shadow: inset 0 -1px 0;
cursor: default;
}
.content tr:first-child {
border-bottom: 1px solid rgba(0, 0, 0, 0.35);
}
.content td {
vertical-align: top;
}
.content td:first-child {
padding-right: 1rem;
}
.content td p:first-child {
margin-top: 0;
}
.content td h4, .content td h5 {
margin-left: 0;
font-size: 1.1em;
}
.content tr:first-child td {
border-top: 0;
}
.srclink {
color: var(--text-color-muted);
font-size: 1rem;
font-weight: var(--body-font-weight);
flex-grow: 0;
text-decoration: none;
margin-left: auto;
position: relative;
z-index: 1;
}
.meta tr > td:not(:first-child) {
width: 100%;
}
.meta tr > td:first-child {
white-space: nowrap;
}
/*********************************
* DOCBLOCK STYLING
*********************************/
.docblock {
position: relative;
text-align: left;
}
.docblock h1 {
font-size: calc(1.3em * var(--heading-docblock-scale) * var(--heading-font-scale));
}
.docblock h2 {
font-size: calc(1.2em * var(--heading-docblock-scale) * var(--heading-font-scale));
}
.docblock h3 {
font-size: calc(1.1em * var(--heading-docblock-scale) * var(--heading-font-scale));
}
.docblock h4 {
font-size: calc(1.05em * var(--heading-docblock-scale) * var(--heading-font-scale));
}
.docblock h1,
.docblock h2,
.docblock h3,
.docblock h4,
.docblock h5,
.docblock h6 {
color: var(--heading-docblock-color)
}
.docblock table {
margin: .25em 0;
max-width: 100%;
font-size: var(--table-font-size);
}
.docblock table td {
padding: .25em;
}
.docblock table th {
padding: .25em;
text-align: left;
font-family: var(--heading-table-font-family);
font-weight: var(--heading-table-weight);
}
.docblock table tr th:first-child,
.docblock table tr td:first-child {
padding-left: 0;
}
.docblock table tr th:last-child,
.docblock table tr td:last-child {
padding-right: 0;
}
table.enum-members,
table.results {
border-radius: var(--box-radius);
border: 1px solid var(--text-color-muted);
border-spacing: 0 0 !important;
font-size: 80%;
}
table.enum-members tr th,
table.results tr th {
border-top-color: var(--body-bg);
background-color: var(--box-bg);
border-bottom: 1px solid var(--text-color-muted);
}
table.enum-members tr th:first-child,
table.enum-members tr td:first-child {
min-width: 25em;
padding-left: .5em;
}
table.results tr th:first-child,
table.results tr td:first-child {
padding-left: .5em;
}
table.enum-members tr th:last-child,
table.enum-members tr td:last-child,
table.results tr th:last-child,
table.results tr td:last-child {
max-width: 35em;
padding-right: .5em;
}
table.results tr td code {
font-size: 100%;
}
.docblock ul li,
.docblock ol li {
padding-top: 0.15rem;
padding-bottom: 0.15rem;
}
.docblock ul.type {
list-style: none;
}
.docblock ul.type li::before {
content: "»";
color: var(--text-color);
display: inline-block;
width: 1em;
margin-left: -1em;
}
/**************************
RESPONSIVENESS
**************************/
@media (max-width: 700px) {
body {
padding-top: 0px;
}
#body-wrapper {
flex-direction: column;
overflow: hidden;
}
#main {
width: 100%;
padding: 2rem;
}
.sidebar {
position: static;
height: initial;
order: 1;
}
}

View File

@@ -23,7 +23,6 @@ push=0
list=0
print_help=0
no_login=0
no_cache=0
while (($# > 0)); do
case "${1%%=*}" in
@@ -33,9 +32,8 @@ while (($# > 0)); do
list) list=1;;
help) print_help=1;;
--base|-b) read_arg base "$@" || shift;;
--version|-v) read_arg base_version "$@" || shift;;
--base-version) read_arg base_version "$@" || shift;;
--no-login) no_login=1;;
--no-cache) no_cache=1;;
*) echo -e "\e[1;31mERROR\e[0m: Unknown option '$1'"; exit 1;;
esac
shift
@@ -105,21 +103,11 @@ TAG="${REGISTRY}/gnome/gtk/${base}:${base_version}"
if [ $build == 1 ]; then
echo -e "\e[1;32mBUILDING\e[0m: ${base} as ${TAG}"
if [ $no_cache == 0 ]; then
${CMD} build \
${format} \
--build-arg HOST_USER_ID="$UID" \
--tag "${TAG}" \
--file "${base}.Dockerfile" .
else
${CMD} build \
${format} \
--no-cache \
--build-arg HOST_USER_ID="$UID" \
--tag "${TAG}" \
--file "${base}.Dockerfile" .
fi
${CMD} build \
${format} \
--build-arg HOST_USER_ID="$UID" \
--tag "${TAG}" \
--file "${base}.Dockerfile" .
exit $?
fi
@@ -138,8 +126,7 @@ if [ $run == 1 ]; then
echo -e "\e[1;32mRUNNING\e[0m: ${base} as ${TAG}"
${CMD} run \
--rm \
--userns=keep-id \
--volume "$(pwd)/..:/home/user/app:rw,z" \
--volume "$(pwd)/..:/home/user/app" \
--workdir "/home/user/app" \
--tty \
--interactive "${TAG}" \

View File

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

View File

@@ -2,43 +2,18 @@
set -e
ancestor_horizon=31 # days (one month)
# Recently, git is picky about directory ownership. Tell it not to worry.
git config --global --add safe.directory "$PWD"
# We need to add a new remote for the upstream target branch, since this script
# could be running in a personal fork of the repository which has out of date
# branches.
#
# Limit the fetch to a certain date horizon to limit the amount of data we get.
# If the branch was forked from origin/main before this horizon, it should
# probably be rebased.
if ! git ls-remote --exit-code upstream >/dev/null 2>&1 ; then
git remote add upstream https://gitlab.gnome.org/GNOME/gtk.git
fi
# We need to add a new remote for the upstream master, since this script could
# be running in a personal fork of the repository which has out of date branches.
git remote add upstream https://gitlab.gnome.org/GNOME/gtk.git
git fetch upstream
# Work out the newest common ancestor between the detached HEAD that this CI job
# has checked out, and the upstream target branch (which will typically be
# `upstream/main` or `upstream/glib-2-62`).
# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` or `${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}`
# are only defined if were running in a merge request pipeline,
# fall back to `${CI_DEFAULT_BRANCH}` or `${CI_COMMIT_BRANCH}` respectively
# otherwise.
source_branch="${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:-${CI_COMMIT_BRANCH}}"
target_branch="${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}"
git fetch --shallow-since="$(date --date="${ancestor_horizon} days ago" +%Y-%m-%d)" origin "${source_branch}"
git fetch --shallow-since="$(date --date="${ancestor_horizon} days ago" +%Y-%m-%d)" upstream "${target_branch}"
newest_common_ancestor_sha=$(git merge-base upstream/${target_branch} origin/${source_branch})
if [ -z "${newest_common_ancestor_sha}" ]; then
echo "Couldnt find common ancestor with upstream main branch. This typically"
echo "happens if you branched from main a long time ago. Please update"
echo "your clone, rebase, and re-push your branch."
exit 1
fi
# `upstream/master` or `upstream/gtk-3-24`).
#
# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` is only defined if were running in
# a merge request pipeline; fall back to `${CI_DEFAULT_BRANCH}` otherwise.
newest_common_ancestor_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "upstream/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}") <(git rev-list --first-parent HEAD) | head -1)
git diff -U0 --no-color "${newest_common_ancestor_sha}" | .gitlab-ci/clang-format-diff.py -binary "clang-format" -p1
exit_status=$?
@@ -54,7 +29,7 @@ exit_status=$?
echo ""
echo "Note that clang-format output is advisory and cannot always match the"
echo "GTK coding style, documented at:"
echo " https://gitlab.gnome.org/GNOME/gtk/blob/main/docs/CODING-STYLE.md"
echo " https://gitlab.gnome.org/GNOME/gtk/blob/master/docs/CODING-STYLE"
echo "Warnings from this tool can be ignored in favour of the documented "
echo "coding style, or in favour of matching the style of existing"
echo "surrounding code."

View File

@@ -1,31 +1,20 @@
#!/bin/bash
set -x
set +x
set +e
srcdir=$( pwd )
builddir=$1
setup=$2
suite=$3
multiplier=${MESON_TEST_TIMEOUT_MULTIPLIER:-1}
backend=$2
# Ignore memory leaks lower in dependencies
export LSAN_OPTIONS=suppressions=$srcdir/lsan.supp:print_suppressions=0:detect_leaks=0:allocator_may_return_null=1
export G_SLICE=always-malloc
case "${setup}" in
x11*)
xvfb-run -a -s "-screen 0 1024x768x24 -noreset" \
case "${backend}" in
x11)
xvfb-run -a -s "-screen 0 1024x768x24" \
meson test -C ${builddir} \
--quiet \
--timeout-multiplier "${multiplier}" \
--print-errorlogs \
--setup=${setup} \
--suite=${suite//,/ --suite=} \
--no-suite=failing \
--no-suite=${setup}_failing \
--no-suite=flaky \
--no-suite=headless \
--setup=${backend} \
--suite=gtk \
--no-suite=gtk:a11y \
--no-suite=gsk-compare-broadway
# Store the exit code for the CI run, but always
@@ -33,7 +22,7 @@ case "${setup}" in
exit_code=$?
;;
wayland*)
wayland)
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
weston --backend=headless-backend.so --socket=wayland-5 --idle-time=0 &
@@ -41,22 +30,17 @@ case "${setup}" in
export WAYLAND_DISPLAY=wayland-5
meson test -C ${builddir} \
--quiet \
--timeout-multiplier "${multiplier}" \
--print-errorlogs \
--setup=${setup} \
--suite=${suite//,/ --suite=} \
--no-suite=failing \
--no-suite=${setup}_failing \
--no-suite=flaky \
--no-suite=headless \
--setup=${backend} \
--suite=gtk \
--no-suite=gtk:a11y \
--no-suite=gsk-compare-broadway
exit_code=$?
exit_code=$?
kill ${compositor}
;;
broadway*)
broadway)
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
${builddir}/gdk/broadway/gtk4-broadwayd :5 &
@@ -64,42 +48,32 @@ case "${setup}" in
export BROADWAY_DISPLAY=:5
meson test -C ${builddir} \
--quiet \
--timeout-multiplier "${multiplier}" \
--print-errorlogs \
--setup=${setup} \
--suite=${suite//,/ --suite=} \
--no-suite=failing \
--no-suite=${setup}_failing \
--no-suite=flaky \
--no-suite=headless \
--setup=${backend} \
--suite=gtk \
--no-suite=gtk:a11y \
--no-suite=gsk-compare-opengl
# don't let Broadway failures fail the run, for now
exit_code=0
kill ${server}
;;
*)
echo "Failed to add ${setup} to .gitlab-ci/run-tests.sh"
exit 1
;;
esac
cd ${builddir}
$srcdir/.gitlab-ci/meson-junit-report.py \
--project-name=gtk \
--backend="${setup}" \
--job-id="${CI_JOB_NAME}" \
--output="report-${setup}.xml" \
"meson-logs/testlog-${setup}.json"
--project-name=gtk \
--backend=${backend} \
--job-id="${CI_JOB_NAME}" \
--output=report-${backend}.xml \
meson-logs/testlog-${backend}.json
$srcdir/.gitlab-ci/meson-html-report.py \
--project-name=gtk \
--backend="${setup}" \
--job-id="${CI_JOB_NAME}" \
--reftest-output-dir="testsuite/reftests/output/${setup}" \
--output="report-${setup}.html" \
"meson-logs/testlog-${setup}.json"
--project-name=gtk \
--backend=${backend} \
--job-id="${CI_JOB_NAME}" \
--reftest-output-dir="testsuite/reftests/output/${backend}" \
--output=report-${backend}.html \
meson-logs/testlog-${backend}.json
exit $exit_code

View File

@@ -1,5 +0,0 @@
#! /bin/sh
. /etc/os-release
echo $PRETTY_NAME

View File

@@ -1,13 +0,0 @@
#!/bin/bash
set -eux -o pipefail
xcodebuild -version || :
if [ -z "$SDKROOT" ]; then
xcodebuild -showsdks || :
else
echo "SDKROOT = $SDKROOT"
fi
system_profiler SPSoftwareDataType || :

View File

@@ -15,7 +15,7 @@ meson \
-Dx11-backend=true \
-Dwayland-backend=true \
-Dbroadway-backend=true \
-Dvulkan=enabled \
-Dvulkan=yes \
-Dprofiler=true \
--werror \
${EXTRA_MESON_FLAGS:-} \

View File

@@ -1,14 +0,0 @@
@echo on
:: vcvarsall.bat sets various env vars like PATH, INCLUDE, LIB, LIBPATH for the
:: specified build architecture
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x64
@echo on
:: FIXME: make warnings fatal
pip3 install --upgrade --user meson~=0.64 || goto :error
meson setup -Dbackend_max_links=1 -Ddebug=false -Dmedia-gstreamer=disabled -Dvulkan=disabled _build || goto :error
ninja -C _build || goto :error
goto :EOF
:error
exit /b 1

View File

@@ -15,9 +15,9 @@ pacman --noconfirm -Suy
pacman --noconfirm -S --needed \
base-devel \
git \
mingw-w64-$MSYS2_ARCH-cc \
mingw-w64-$MSYS2_ARCH-toolchain \
mingw-w64-$MSYS2_ARCH-ccache \
mingw-w64-$MSYS2_ARCH-pkgconf \
mingw-w64-$MSYS2_ARCH-pkg-config \
mingw-w64-$MSYS2_ARCH-gobject-introspection \
mingw-w64-$MSYS2_ARCH-meson \
mingw-w64-$MSYS2_ARCH-adwaita-icon-theme \
@@ -30,12 +30,15 @@ pacman --noconfirm -S --needed \
mingw-w64-$MSYS2_ARCH-libepoxy \
mingw-w64-$MSYS2_ARCH-pango \
mingw-w64-$MSYS2_ARCH-fribidi \
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
mingw-w64-$MSYS2_ARCH-shared-mime-info \
mingw-w64-$MSYS2_ARCH-python-gobject \
mingw-w64-$MSYS2_ARCH-shaderc \
mingw-w64-$MSYS2_ARCH-vulkan \
mingw-w64-$MSYS2_ARCH-vulkan-headers
mingw-w64-$MSYS2_ARCH-gst-plugins-bad \
mingw-w64-$MSYS2_ARCH-shared-mime-info
# https://gitlab.gnome.org/GNOME/gtk/issues/2243
wget "https://gitlab.gnome.org/creiter/gitlab-ci-win32-runner-v2/raw/master/pango/mingw-w64-$MSYS2_ARCH-pango-1.44.7-1-any.pkg.tar.xz"
pacman --noconfirm -U "mingw-w64-$MSYS2_ARCH-pango-1.44.7-1-any.pkg.tar.xz"
# https://github.com/msys2/MINGW-packages/pull/6465
pacman --noconfirm -S --needed mingw-w64-$MSYS2_ARCH-brotli
mkdir -p _ccache
export CCACHE_BASEDIR="$(pwd)"
@@ -45,16 +48,17 @@ export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
ccache --zero-stats
ccache --show-stats
export CCACHE_DISABLE=true
meson setup \
# FIXME: introspection disabled for now because of
# https://gitlab.gnome.org/GNOME/gobject-introspection/-/issues/340
meson \
-Dx11-backend=false \
-Dwayland-backend=false \
-Dwin32-backend=true \
-Dintrospection=enabled \
-Dgtk:werror=true \
-Dvulkan=no \
-Dintrospection=false \
--werror \
_build
unset CCACHE_DISABLE
ninja -C _build
ccache --show-stats
tar zcf _build/gtkdll.tar.gz _build/gtk/libgtk*.dll

View File

@@ -1,13 +1,4 @@
<!--
Please, read the CONTRIBUTING.md guide on how to file a new issue.
https://gitlab.gnome.org/GNOME/gtk/-/blob/main/CONTRIBUTING.md
-->
## Steps to reproduce
<!--
Please, explain the sequence of actions necessary to reproduce the
bug
-->
1. ...
2. ...
@@ -41,8 +32,5 @@
## Additional information
<!--
- Screenshots or screen recordings are useful for visual errors
- Attaching a screenshot or a video without explaining the current
behavior and the actions necessary to reproduce the bug will lead
to the bug being closed
- Please report any warning or message printed on the terminal
-->

View File

@@ -1,14 +1,4 @@
<!--
Please, read the CONTRIBUTING.md guide on how to file a new issue.
https://gitlab.gnome.org/GNOME/gtk/-/blob/main/CONTRIBUTING.md
-->
## Steps to reproduce
<!--
Please, explain the sequence of actions necessary to reproduce the
crash
-->
1. ...
2. ...

57
AUTHORS
View File

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

View File

@@ -21,7 +21,7 @@ many things that we value:
Please, do not use the issue tracker for support questions. If you have
questions on how to use GTK effectively, you can use:
- the `gtk` [room on matrix](https://matrix.to/#/#gtk:gnome.org)
- the `#gtk` IRC channel on irc.gnome.org
- the [gtk tag on the GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
You can also look at the GTK tag on [Stack
@@ -35,7 +35,8 @@ The issue tracker is meant to be used for actionable issues only.
You should not open a new issue for security related questions.
When in doubt, follow the process for [GNOME security issues](https://security.gnome.org/).
When in doubt, send an email to the [security](mailto:security@gnome.org)
mailing list.
### Bug reports
@@ -43,7 +44,6 @@ If you're reporting a bug make sure to list:
0. which version of GTK are you using?
0. which operating system are you using?
0. what display and graphics driver are you using?
0. the necessary steps to reproduce the issue
0. the expected outcome
0. a description of the behavior; screenshots are also welcome
@@ -56,12 +56,6 @@ If the issue includes a crash, you should also include:
0. the eventual warnings printed on the terminal
0. a backtrace, obtained with tools such as GDB or LLDB
It is fine to include screenshots of screen recordings to demonstrate
an issue that is best to understand visually, but please don't just
dump screen recordings without further details into issues. It is
essential that the problem is described in enough detail to reproduce
it without watching a video.
For small issues, such as:
- spelling/grammar fixes in the documentation
@@ -144,28 +138,33 @@ $ git clone https://gitlab.gnome.org/yourusername/gtk.git
$ cd gtk
```
**Note**: if you plan to push changes to back to the main repository and
have a GNOME account, you can skip the fork, and use the following instead:
```sh
$ git clone git@gitlab.gnome.org:GNOME/gtk.git
$ cd gtk
```
To compile the Git version of GTK on your system, you will need to
configure your build using Meson:
```sh
$ meson setup _builddir .
$ meson compile -C _builddir
$ meson _builddir .
$ cd _builddir
$ ninja
```
Typically, you should work on your own branch:
```sh
$ git switch -C your-branch
$ git checkout -b your-branch
```
Once you've finished working on the bug fix or feature, push the branch
to the Git repository and open a new merge request, to let the GTK
maintainers review your contribution.
**Important**: Do **not** attach a diff or a patch file to a GitLab issue.
Patches cannot be reviewed, and do not not go through the CI pipeline. If
you wish to submit your changes to GTK, always use a merge request.
### Code reviews
Each contribution is reviewed by the core developers of the GTK project.
@@ -208,7 +207,7 @@ Closes #1234
`git commit -a --author "Joe Coder <joe@coder.org>"` and `--signoff`.
- If your commit is addressing an issue, use the
[GitLab syntax](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
[GitLab syntax](https://docs.gitlab.com/ce/user/project/issues/automatic_issue_closing.html)
to automatically close the issue when merging the commit with the upstream
repository:
@@ -238,18 +237,20 @@ people committing to GTK to follow a few rules:
code, you should always ask. If your change is minor and you've been
working on GTK for a while it probably isn't necessary to ask. But when
in doubt, ask. Even if your change is correct, somebody may know a
better way to do things.
The `gtk` [room on matrix](https://matrix.to/#/#gtk:gnome.org) is also a
good place to find GTK developers to discuss changes, but if you live
outside of the EU/US time zones, the [gtk tag on the GNOME Discourse instance](https://discourse.gnome.org/tag/gtk)
is the most certain and preferred method.
better way to do things. If you are making changes to GTK, you should
be subscribed to the [gtk-devel](https://mail.gnome.org/mailman/listinfo/gtk-devel-list)
mailing list; this is a good place to ask about intended changes.
The `#gtk` IRC channel on irc.gnome.org is also a good place to find GTK
developers to discuss changes, but if you live outside of the EU/US time
zones, an email to the gtk-devel mailing list is the most certain and
preferred method.
0. Ask _first_.
0. Always write a meaningful commit message. Changes without a sufficient
commit message will be reverted.
0. Never push to the `main` branch, or any stable branches, directly; you
0. Never push to the `master` branch, or any stable branches, directly; you
should always go through a merge request, to ensure that the code is
tested on the CI infrastructure at the very least. A merge request is
also the proper place to get a comprehensive code review from the core
@@ -257,4 +258,4 @@ people committing to GTK to follow a few rules:
If you have been contributing to GTK for a while and you don't have commit
access to the repository, you may ask to obtain it following the [GNOME account
process](https://handbook.gnome.org/infrastructure/developer-access.html).
process](https://wiki.gnome.org/AccountsTeam/NewAccounts).

11442
NEWS

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
GTK — The GTK toolkit
=====================
[![Build status](https://gitlab.gnome.org/GNOME/gtk/badges/main/pipeline.svg)](https://gitlab.gnome.org/GNOME/gtk/-/commits/main)
[![Build Status](https://gitlab.gnome.org/GNOME/gtk/badges/master/build.svg)](https://gitlab.gnome.org/GNOME/gtk/pipelines)
General information
-------------------
@@ -10,16 +10,14 @@ GTK is a multi-platform toolkit for creating graphical user interfaces.
Offering a complete set of widgets, GTK is suitable for projects ranging
from small one-off projects to complete application suites.
GTK is a free and open-source software project. The licensing terms
for GTK, the GNU LGPL, allow it to be used by all developers, including those
developing proprietary software, without any license fees or royalties.
GTK is hosted by the GNOME project (thanks!) and used by a wide variety
of applications and projects.
GTK is free software and part of the GNU Project. However, the
licensing terms for GTK, the GNU LGPL, allow it to be used by all
developers, including those developing proprietary software, without any
license fees or royalties.
The official download location
- https://download.gnome.org/sources/gtk/
- https://download.gnome.org/sources/gtk+
The official web site
@@ -34,16 +32,9 @@ Discussion forum
- https://discourse.gnome.org/c/platform/core/
Nightly documentation can be found at
- Gtk: https://gnome.pages.gitlab.gnome.org/gtk/gtk4/
- Gdk: https://gnome.pages.gitlab.gnome.org/gtk/gdk4/
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk4/
Nightly flatpaks of our demos can be installed from the
[GNOME Nightly](https://wiki.gnome.org/Apps/Nightly) repository:
- `flatpak remote-add --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo`
- `flatpak install gnome-nightly org.gtk.Demo4`
- `flatpak install gnome-nightly org.gtk.WidgetFactory4`
- `flatpak install gnome-nightly org.gtk.IconBrowser4`
- Gtk: https://gnome.pages.gitlab.gnome.org/gtk/gtk/
- Gdk: https://gnome.pages.gitlab.gnome.org/gtk/gdk/
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk/
Building and installing
-----------------------
@@ -58,22 +49,16 @@ In order to build GTK you will need:
You will also need various dependencies, based on the platform you are
building for:
- [GLib](https://download.gnome.org/sources/glib/)
- [GdkPixbuf](https://download.gnome.org/sources/gdk-pixbuf/)
- [GObject-Introspection](https://download.gnome.org/sources/gobject-introspection/)
- [Cairo](https://www.cairographics.org/)
- [Pango](https://download.gnome.org/sources/pango/)
- [GLib](https://download.gnome.org/sources/glib)
- [GdkPixbuf](https://download.gnome.org/sources/gdk-pixbuf)
- [GObject-Introspection](https://download.gnome.org/sources/gobject-introspection)
- [Cairo](https://www.cairographics.org)
- [Pango](https://download.gnome.org/sources/pango)
- [Epoxy](https://github.com/anholt/libepoxy)
- [Graphene](https://github.com/ebassi/graphene)
- [ATK](https://download.gnome.org/sources/atk)
- [Xkb-common](https://github.com/xkbcommon/libxkbcommon)
If you are building the Wayland backend, you will also need:
- Wayland-client
- Wayland-protocols
- Wayland-cursor
- Wayland-EGL
If you are building the X11 backend, you will also need:
- Xlib, and the following X extensions:
@@ -85,47 +70,49 @@ If you are building the X11 backend, you will also need:
- xcursor
- xdamage
- xcomposite
- [atk-bridge-2.0](https://download.gnome.org/sources/at-spi2-atk)
If you are building the Wayland backend, you will also need:
- Wayland-client
- Wayland-protocols
- Wayland-cursor
- Wayland-EGL
Once you have all the necessary dependencies, you can build GTK by using
Meson:
```sh
$ meson setup _build
$ meson compile -C_build
$ meson _build .
$ cd _build
$ ninja
```
You can run the test suite using:
```sh
$ meson test -C_build
$ meson test
```
And, finally, you can install GTK using:
```
$ sudo meson install -C_build
$ sudo ninja install
```
Complete information about installing GTK and related libraries
Complete information about installing GTK+ and related libraries
can be found in the file:
```
docs/reference/gtk/html/gtk-building.html
```
Or [online](https://docs.gtk.org/gtk4/building.html)
Building from git
-----------------
The GTK sources are hosted on [gitlab.gnome.org](http://gitlab.gnome.org). The main
development branch is called `main`, and stable branches are named after their minor
version, for example `gtk-4-10`.
Or [online](https://developer.gnome.org/gtk4/stable/gtk-building.html)
How to report bugs
------------------
Bugs should be reported on the [issues page](https://gitlab.gnome.org/GNOME/gtk/issues/).
Bugs should be reported on the [issues page](https://gitlab.gnome.org/GNOME/gtk/issues/new).
In the bug report please include:
@@ -159,17 +146,14 @@ Contributing to GTK
Please, follow the [contribution guide](./CONTRIBUTING.md) to know how to
start contributing to GTK.
If you want to support GTK financially, please consider donating to
the GNOME project, which runs the infrastructure hosting GTK.
Release notes
-------------
The release notes for GTK are part of the migration guide in the API
reference. See:
- [3.x release notes](https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html)
- [4.x release notes](https://docs.gtk.org/gtk4/migrating-3to4.html)
- [3.x release notes](https://developer.gnome.org/gtk3/unstable/gtk-migrating-2-to-3.html)
- [4.x release notes](https://developer.gnome.org/gtk4/unstable/gtk-migrating-3-to-4.html)
Licensing terms
---------------
@@ -179,7 +163,3 @@ version 2.1 or, at your option, any later version, as published by the Free
Software Foundation.
Please, see the [`COPYING`](./COPYING) file for further information.
GTK includes a small number of source files under the Apache license:
- A fork of the roaring bitmaps implementation in [gtk/roaring](./gtk/roaring)
- An adaptation of timsort from python in [gtk/timsort](./gtk/timsort)

View File

@@ -1,43 +0,0 @@
diff -ur lua-5.1.4/src/Makefile lua-5.1.4-new/src/Makefile
--- lua-5.1.4/src/Makefile 2008-01-19 20:37:58.000000000 +0100
+++ lua-5.1.4-new/src/Makefile 2012-02-23 18:26:43.000000000 +0100
@@ -23,6 +23,7 @@
PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris
LUA_A= liblua.a
+LUA_SO= liblua.so
CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
lundump.o lvm.o lzio.o
@@ -36,7 +37,7 @@
LUAC_O= luac.o print.o
ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O)
-ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
+ALL_T= $(LUA_A) $(LUA_SO) $(LUA_T) $(LUAC_T)
ALL_A= $(LUA_A)
default: $(PLAT)
@@ -51,6 +52,11 @@
$(AR) $@ $?
$(RANLIB) $@
+$(LUA_SO): $(CORE_O) $(LIB_O)
+ $(CC) -shared -ldl -Wl,-soname,$(LUA_SO).$(V) -o $@.$(R) $? -lm $(MYLDFLAGS)
+ ln -sf $(LUA_SO).$(R) $(LUA_SO).$(V)
+ ln -sf $(LUA_SO).$(R) $(LUA_SO)
+
$(LUA_T): $(LUA_O) $(LUA_A)
$(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
--- lua-5.1.4/Makefile 2008-08-12 02:40:48.000000000 +0200
+++ lua-5.1.4-new/Makefile 2012-02-23 19:06:32.000000000 +0100
@@ -53,7 +53,7 @@
all: $(PLAT)
$(PLATS) clean:
- cd src && $(MAKE) $@
+ cd src && $(MAKE) $@ V=$(V) R=$(R)
test: dummy
src/lua test/hello.lua

View File

@@ -1,65 +1,56 @@
{
"app-id" : "org.gtk.Demo4",
"runtime" : "org.gnome.Platform",
"runtime-version" : "master",
"sdk" : "org.gnome.Sdk",
"command" : "gtk4-demo",
"tags" : [
"devel",
"development",
"nightly"
],
"desktop-file-name-prefix" : "(Development) ",
"finish-args" : [
"app-id": "org.gtk.Demo4",
"runtime": "org.gnome.Platform",
"runtime-version": "master",
"sdk": "org.gnome.Sdk",
"command": "gtk4-demo",
"tags": ["devel", "development", "nightly"],
"desktop-file-name-prefix": "(Development) ",
"finish-args": [
"--device=dri",
"--share=ipc",
"--socket=fallback-x11",
"--socket=wayland",
"--talk-name=org.gtk.vfs",
"--talk-name=org.gtk.vfs.*"
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*"
],
"cleanup" : [
"cleanup": [
"/include",
"/lib/pkgconfig",
"/share/pkgconfig",
"/lib/pkgconfig", "/share/pkgconfig",
"/share/aclocal",
"/man",
"/share/man",
"/share/gtk-doc",
"*.la",
".a",
"/man", "/share/man", "/share/gtk-doc",
"*.la", ".a",
"/lib/girepository-1.0",
"/share/gir-1.0",
"/share/doc"
],
"modules" : [
"modules": [
{
"name" : "wayland",
"buildsystem" : "meson",
"buildsystem" : "autotools",
"builddir" : true,
"config-opts" : [
"-Ddocumentation=false"
"--disable-documentation"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
"branch" : "main"
"url" : "https://github.com/wayland-project/wayland.git"
}
]
},
{
"name" : "graphene",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"name": "graphene",
"buildsystem": "meson",
"builddir": true,
"config-opts": [
"--libdir=/app/lib",
"-Dtests=false"
"-Dtests=false",
"-Dbenchmarks=false"
],
"sources" : [
"sources": [
{
"type" : "git",
"url" : "https://github.com/ebassi/graphene.git"
"type": "git",
"url": "https://github.com/ebassi/graphene.git"
}
]
},
@@ -67,7 +58,7 @@
"name" : "libsass",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"config-opts": [
"--libdir=/app/lib"
],
"sources" : [
@@ -82,7 +73,7 @@
"name" : "sassc",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"config-opts": [
"--libdir=/app/lib"
],
"sources" : [
@@ -94,112 +85,18 @@
]
},
{
"name": "boost",
"buildsystem": "simple",
"build-commands": [
"./bootstrap.sh --prefix=/app --with-libraries=date_time,filesystem,iostreams,locale,regex,system,thread,python,program_options,test,serialization",
"./b2 --build-type=minimal link=shared -j $FLATPAK_BUILDER_N_JOBS",
"./b2 --build-type=minimal link=shared install"
],
"sources": [
{
"type": "archive",
"url": "https://boostorg.jfrog.io/artifactory/main/release/1.79.0/source/boost_1_79_0.tar.bz2",
"sha256": "475d589d51a7f8b3ba2ba4eda022b170e562ca3b760ee922c146b6c65856ef39"
}
]
},
{
"name": "lua-5.1",
"buildsystem": "simple",
"build-commands": [
"make -j $FLATPAK_BUILDER_N_JOBS CFLAGS=\"$CFLAGS -fPIC -DLUA_USE_LINUX\" linux",
"make INSTALL_TOP=$FLATPAK_DEST TO_LIB='liblua.a liblua.so.5.1.5' install",
"ln -sf liblua.so.5.1.5 $FLATPAK_DEST/lib/liblua.so",
"ln -sf liblua.so.5.1.5 $FLATPAK_DEST/lib/liblua.so.5.1",
"install -Dm0644 etc/lua.pc $FLATPAK_DEST/lib/pkgconfig/lua.pc",
"ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua51.pc",
"ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua5.1.pc",
"ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua-5.1.pc"
"name": "gtk",
"buildsystem": "meson",
"builddir": true,
"config-opts": [
"--libdir=/app/lib"
],
"sources": [
{
"type": "archive",
"url": "https://www.lua.org/ftp/lua-5.1.5.tar.gz",
"sha256": "2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333"
},
{
"type": "patch",
"path": "lua-5.1.5-so.patch"
},
{
"type": "shell",
"commands": [
"sed -i \"s|/usr/local|$FLATPAK_DEST|\" etc/lua.pc src/luaconf.h"
]
}
],
"cleanup": [
"*.a",
"/bin",
"/include",
"/lib/pkgconfig",
"/man"
]
},
{
"name" : "highlight",
"buildsystem" : "simple",
"builddir" : true,
"build-commands" : [
"sed -i -e 's#^PREFIX = /usr#PREFIX = /app#' makefile",
"make",
"make install"
],
"sources" : [
{
"type" : "archive",
"url" : "http://www.andre-simon.de/zip/highlight-4.0.tar.bz2",
"sha256" : "f40dcba26e011a2c67df874f4d9b0238c2c6b065163ce8de3d8371b9dfce864d"
}
]
},
{
"name" : "pango",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/pango.git",
"branch" : "main"
}
]
},
{
"name" : "gtk",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Dbuildtype=debugoptimized",
"-Dprofile=devel"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/gtk.git",
"branch" : "main"
"type": "git",
"url": "https://gitlab.gnome.org/GNOME/gtk.git"
}
]
}
],
"build-options" : {
"env" : {
"GSK_RENDERER" : "opengl"
}
}
]
}

View File

@@ -1,65 +1,56 @@
{
"app-id" : "org.gtk.IconBrowser4",
"runtime" : "org.gnome.Platform",
"runtime-version" : "master",
"sdk" : "org.gnome.Sdk",
"command" : "gtk4-icon-browser",
"tags" : [
"devel",
"development",
"nightly"
],
"desktop-file-name-prefix" : "(Development) ",
"finish-args" : [
"app-id": "org.gtk.IconBrowser4",
"runtime": "org.gnome.Platform",
"runtime-version": "master",
"sdk": "org.gnome.Sdk",
"command": "gtk4-icon-browser",
"tags": ["devel", "development", "nightly"],
"desktop-file-name-prefix": "(Development) ",
"finish-args": [
"--device=dri",
"--share=ipc",
"--socket=fallback-x11",
"--socket=wayland",
"--talk-name=org.gtk.vfs",
"--talk-name=org.gtk.vfs.*"
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*"
],
"cleanup" : [
"cleanup": [
"/include",
"/lib/pkgconfig",
"/share/pkgconfig",
"/lib/pkgconfig", "/share/pkgconfig",
"/share/aclocal",
"/man",
"/share/man",
"/share/gtk-doc",
"*.la",
".a",
"/man", "/share/man", "/share/gtk-doc",
"*.la", ".a",
"/lib/girepository-1.0",
"/share/gir-1.0",
"/share/doc"
],
"modules" : [
"modules": [
{
"name" : "wayland",
"buildsystem" : "meson",
"buildsystem" : "autotools",
"builddir" : true,
"config-opts" : [
"-Ddocumentation=false"
"--disable-documentation"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
"branch" : "main"
"url" : "https://github.com/wayland-project/wayland.git"
}
]
},
{
"name" : "graphene",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"name": "graphene",
"buildsystem": "meson",
"builddir": true,
"config-opts": [
"--libdir=/app/lib",
"-Dtests=false"
"-Dtests=false",
"-Dbenchmarks=false"
],
"sources" : [
"sources": [
{
"type" : "git",
"url" : "https://github.com/ebassi/graphene.git"
"type": "git",
"url": "https://github.com/ebassi/graphene.git"
}
]
},
@@ -67,7 +58,7 @@
"name" : "libsass",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"config-opts": [
"--libdir=/app/lib"
],
"sources" : [
@@ -82,7 +73,7 @@
"name" : "sassc",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"config-opts": [
"--libdir=/app/lib"
],
"sources" : [
@@ -94,40 +85,18 @@
]
},
{
"name" : "pango",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"name": "gtk",
"buildsystem": "meson",
"builddir": true,
"config-opts": [
"--libdir=/app/lib"
],
"sources" : [
"sources": [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/pango.git",
"branch" : "main"
}
]
},
{
"name" : "gtk",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Dbuildtype=debugoptimized",
"-Dprofile=devel"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/gtk.git",
"branch" : "main"
"type": "git",
"url": "https://gitlab.gnome.org/GNOME/gtk.git"
}
]
}
],
"build-options" : {
"env" : {
}
}
]
}

View File

@@ -1,65 +1,56 @@
{
"app-id" : "org.gtk.WidgetFactory4",
"runtime" : "org.gnome.Platform",
"runtime-version" : "master",
"sdk" : "org.gnome.Sdk",
"command" : "gtk4-widget-factory",
"tags" : [
"devel",
"development",
"nightly"
],
"desktop-file-name-prefix" : "(Development) ",
"finish-args" : [
"app-id": "org.gtk.WidgetFactory4",
"runtime": "org.gnome.Platform",
"runtime-version": "master",
"sdk": "org.gnome.Sdk",
"command": "gtk4-widget-factory",
"tags": ["devel", "development", "nightly"],
"desktop-file-name-prefix": "(Development) ",
"finish-args": [
"--device=dri",
"--share=ipc",
"--socket=fallback-x11",
"--socket=wayland",
"--talk-name=org.gtk.vfs",
"--talk-name=org.gtk.vfs.*"
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*"
],
"cleanup" : [
"cleanup": [
"/include",
"/lib/pkgconfig",
"/share/pkgconfig",
"/lib/pkgconfig", "/share/pkgconfig",
"/share/aclocal",
"/man",
"/share/man",
"/share/gtk-doc",
"*.la",
".a",
"/man", "/share/man", "/share/gtk-doc",
"*.la", ".a",
"/lib/girepository-1.0",
"/share/gir-1.0",
"/share/doc"
],
"modules" : [
"modules": [
{
"name" : "wayland",
"buildsystem" : "meson",
"buildsystem" : "autotools",
"builddir" : true,
"config-opts" : [
"-Ddocumentation=false"
"--disable-documentation"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
"branch" : "main"
"url" : "https://github.com/wayland-project/wayland.git"
}
]
},
{
"name" : "graphene",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"name": "graphene",
"buildsystem": "meson",
"builddir": true,
"config-opts": [
"--libdir=/app/lib",
"-Dtests=false"
"-Dtests=false",
"-Dbenchmarks=false"
],
"sources" : [
"sources": [
{
"type" : "git",
"url" : "https://github.com/ebassi/graphene.git"
"type": "git",
"url": "https://github.com/ebassi/graphene.git"
}
]
},
@@ -67,7 +58,7 @@
"name" : "libsass",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"config-opts": [
"--libdir=/app/lib"
],
"sources" : [
@@ -82,7 +73,7 @@
"name" : "sassc",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"config-opts": [
"--libdir=/app/lib"
],
"sources" : [
@@ -94,43 +85,18 @@
]
},
{
"name" : "pango",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"name": "gtk",
"buildsystem": "meson",
"builddir": true,
"config-opts": [
"--libdir=/app/lib"
],
"sources" : [
"sources": [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/pango.git",
"branch" : "main"
}
]
},
{
"name" : "gtk",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Dbuildtype=debugoptimized",
"-Dprofile=devel"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/gtk.git",
"branch" : "main"
"type": "git",
"url": "https://gitlab.gnome.org/GNOME/gtk.git"
}
]
}
],
"build-options" : {
"env" : {
"DBUS_SESSION_BUS_ADDRESS" : "''",
"GSK_RENDERER" : "opengl",
"G_ENABLE_DEBUG" : "true"
}
}
]
}

View File

@@ -1,136 +0,0 @@
{
"app-id" : "org.gtk.gtk4.NodeEditor",
"runtime" : "org.gnome.Platform",
"runtime-version" : "master",
"sdk" : "org.gnome.Sdk",
"command" : "gtk4-node-editor",
"tags" : [
"devel",
"development",
"nightly"
],
"desktop-file-name-prefix" : "(Development) ",
"finish-args" : [
"--device=dri",
"--share=ipc",
"--socket=fallback-x11",
"--socket=wayland",
"--talk-name=org.gtk.vfs",
"--talk-name=org.gtk.vfs.*"
],
"cleanup" : [
"/include",
"/lib/pkgconfig",
"/share/pkgconfig",
"/share/aclocal",
"/man",
"/share/man",
"/share/gtk-doc",
"*.la",
".a",
"/lib/girepository-1.0",
"/share/gir-1.0",
"/share/doc"
],
"modules" : [
{
"name" : "wayland",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"-Ddocumentation=false"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.freedesktop.org/wayland/wayland.git",
"branch" : "main"
}
]
},
{
"name" : "graphene",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Dtests=false"
],
"sources" : [
{
"type" : "git",
"url" : "https://github.com/ebassi/graphene.git"
}
]
},
{
"name" : "libsass",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib"
],
"sources" : [
{
"type" : "git",
"url" : "https://github.com/lazka/libsass.git",
"branch" : "meson"
}
]
},
{
"name" : "sassc",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib"
],
"sources" : [
{
"type" : "git",
"url" : "https://github.com/lazka/sassc.git",
"branch" : "meson"
}
]
},
{
"name" : "pango",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/pango.git",
"branch" : "main"
}
]
},
{
"name" : "gtk",
"buildsystem" : "meson",
"builddir" : true,
"config-opts" : [
"--libdir=/app/lib",
"-Dbuildtype=debugoptimized",
"-Dprofile=devel"
],
"sources" : [
{
"type" : "git",
"url" : "https://gitlab.gnome.org/GNOME/gtk.git",
"branch" : "main"
}
]
}
],
"build-options" : {
"env" : {
"DBUS_SESSION_BUS_ADDRESS" : "''",
"GSK_RENDERER" : "opengl",
"G_ENABLE_DEBUG" : "true"
}
}
}

View File

@@ -1,39 +0,0 @@
#!/usr/bin/env python3
import os
import shutil
import subprocess
from pathlib import PurePath
stylesheets = [
'gtk/theme/Default/Default-light.css',
'gtk/theme/Default/Default-dark.css',
'gtk/theme/Default/Default-hc.css',
'gtk/theme/Default/Default-hc-dark.css',
]
references = [
'docs/reference/gtk/gtk4',
'docs/reference/gsk/gsk4',
'docs/reference/gdk/gdk4',
'docs/reference/gdk/gdk4-wayland',
'docs/reference/gdk/gdk4-x11',
]
sourceroot = os.environ.get('MESON_SOURCE_ROOT')
buildroot = os.environ.get('MESON_BUILD_ROOT')
distroot = os.environ.get('MESON_DIST_ROOT')
for stylesheet in stylesheets:
stylesheet_path = PurePath(stylesheet)
src = PurePath(sourceroot, stylesheet_path.with_suffix('.scss'))
dst = PurePath(distroot, stylesheet_path)
subprocess.call(['sassc', '-a', '-M', '-t', 'compact', src, dst])
for reference in references:
src_path = os.path.join(buildroot, reference)
if os.path.isdir(src_path):
dst_path = os.path.join(distroot, reference)
shutil.copytree(src_path, dst_path)

View File

@@ -1,26 +0,0 @@
#!/usr/bin/env python3
import os
import subprocess
import sys
repodir = sys.argv[1]
profile = sys.argv[2]
sys.stdout.write("/* This file is auto-generated. Do not edit. */\n")
sys.stdout.write("#pragma once\n")
sys.stdout.write("\n")
sys.stdout.write(f"#define PROFILE \"{profile}\"\n")
short_sha = os.environ.get('CI_COMMIT_SHORT_SHA')
if short_sha is None:
cmd = ["git", "-C", repodir, "rev-parse", "--short", "HEAD"]
try:
with subprocess.Popen(cmd, stdout=subprocess.PIPE) as p:
short_sha = p.stdout.read().decode('utf-8').rstrip("\n")
except FileNotFoundError:
short_sha = ''
if profile != 'default':
short_sha = 'devel'
sys.stdout.write(f"#define VCS_TAG \"{short_sha}\"\n")

View File

@@ -1,201 +0,0 @@
#!/usr/bin/env python3
#
# SPDX-FileCopyrightText: 2022 Collabora Inc.
# 2023 Emmanuele Bassi
#
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# Original author: Xavier Claessens <xclaesse@gmail.com>
import argparse
import textwrap
from pathlib import Path
# Disable line length warnings as wrapping the C code templates would be hard
# flake8: noqa: E501
def gen_versions_macros(args, current_major_version, current_minor_version, current_micro_version):
with args.out_path.open("w", encoding="utf-8") as ofile, args.in_path.open(
"r", encoding="utf-8"
) as ifile:
for line in ifile.readlines():
if "@GDK_VERSIONS@" in line:
ofile.write(
textwrap.dedent(
f"""\
/**
* GDK_MAJOR_VERSION:
*
* The major version component of the library's version, e.g. "1" for "1.2.3".
*/
#define GDK_MAJOR_VERSION ({current_major_version})
/**
* GDK_MINOR_VERSION:
*
* The minor version component of the library's version, e.g. "2" for "1.2.3".
*/
#define GDK_MINOR_VERSION ({current_minor_version})
/**
* GDK_MICRO_VERSION:
*
* The micro version component of the library's version, e.g. "3" for "1.2.3".
*/
#define GDK_MICRO_VERSION ({current_micro_version})
"""
)
)
for minor in range(0, current_minor_version + 2, 2):
ofile.write(
textwrap.dedent(
f"""\
/**
* GDK_VERSION_{current_major_version}_{minor}:
*
* A macro that evaluates to the {current_major_version}.{minor} version of GTK, in a format
* that can be used by the C pre-processor.
*
* Since: {current_major_version}.{minor}
*/
#define GDK_VERSION_{current_major_version}_{minor} (G_ENCODE_VERSION ({current_major_version}, {minor}))
"""
)
)
else:
ofile.write(line)
def gen_visibility_macros(args, current_major_version, current_minor_version, current_micro_version):
"""
Generates a set of macros for each minor stable version of GTK
- GDK_DEPRECATED
- GDK_DEPRECATED_IN_…
- GDK_DEPRECATED_MACRO_IN_…
- GDK_DEPRECATED_ENUMERATOR_IN_…
- GDK_DEPRECATED_TYPE_IN_…
- GDK_AVAILABLE_IN_ALL
- GDK_AVAILABLE_IN_…
- GDK_AVAILABLE_STATIC_INLINE_IN_…
- GDK_AVAILABLE_MACRO_IN_…
- GDK_AVAILABLE_ENUMERATOR_IN_…
- GDK_AVAILABLE_TYPE_IN_…
- GDK_UNAVAILABLE(maj,min)
- GDK_UNAVAILABLE_STATIC_INLINE(maj,min)
"""
ns = args.namespace
with args.out_path.open("w", encoding="utf-8") as f:
f.write(
textwrap.dedent(
f"""\
#pragma once
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined({ns}_STATIC_COMPILATION)
# define _{ns}_EXPORT __declspec(dllexport)
# define _{ns}_IMPORT __declspec(dllimport)
#elif __GNUC__ >= 4
# define _{ns}_EXPORT __attribute__((visibility("default")))
# define _{ns}_IMPORT
#else
# define _{ns}_EXPORT
# define _{ns}_IMPORT
#endif
#ifdef GTK_COMPILATION
# define _{ns}_API _{ns}_EXPORT
#else
# define _{ns}_API _{ns}_IMPORT
#endif
#define _{ns}_EXTERN _{ns}_API extern
#define {ns}_VAR _{ns}_EXTERN
#define {ns}_AVAILABLE_IN_ALL _{ns}_EXTERN
#ifdef GDK_DISABLE_DEPRECATION_WARNINGS
#define {ns}_DEPRECATED _{ns}_EXTERN
#define {ns}_DEPRECATED_FOR(f) _{ns}_EXTERN
#define {ns}_UNAVAILABLE(maj,min) _{ns}_EXTERN
#define {ns}_UNAVAILABLE_STATIC_INLINE(maj,min)
#else
#define {ns}_DEPRECATED G_DEPRECATED _{ns}_EXTERN
#define {ns}_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) _{ns}_EXTERN
#define {ns}_UNAVAILABLE(maj,min) G_UNAVAILABLE(maj,min) _{ns}_EXTERN
#define {ns}_UNAVAILABLE_STATIC_INLINE(maj,min) G_UNAVAILABLE(maj,min)
#endif
"""
)
)
for minor in range(0, current_minor_version + 2, 2):
f.write(
textwrap.dedent(
f"""
#if GDK_VERSION_MIN_REQUIRED >= GDK_VERSION_4_{minor}
#define {ns}_DEPRECATED_IN_{current_major_version}_{minor} {ns}_DEPRECATED
#define {ns}_DEPRECATED_IN_{current_major_version}_{minor}_FOR(f) {ns}_DEPRECATED_FOR (f)
#define {ns}_DEPRECATED_MACRO_IN_{current_major_version}_{minor} GDK_DEPRECATED_MACRO
#define {ns}_DEPRECATED_MACRO_IN_{current_major_version}_{minor}_FOR(f) GDK_DEPRECATED_MACRO_FOR (f)
#define {ns}_DEPRECATED_ENUMERATOR_IN_{current_major_version}_{minor} GDK_DEPRECATED_ENUMERATOR
#define {ns}_DEPRECATED_ENUMERATOR_IN_{current_major_version}_{minor}_FOR(f) GDK_DEPRECATED_ENUMERATOR_FOR (f)
#define {ns}_DEPRECATED_TYPE_IN_{current_major_version}_{minor} GDK_DEPRECATED_TYPE
#define {ns}_DEPRECATED_TYPE_IN_{current_major_version}_{minor}_FOR(f) GDK_DEPRECATED_TYPE_FOR (f)
#else
#define {ns}_DEPRECATED_IN_{current_major_version}_{minor} _{ns}_EXTERN
#define {ns}_DEPRECATED_IN_{current_major_version}_{minor}_FOR(f) _{ns}_EXTERN
#define {ns}_DEPRECATED_MACRO_IN_{current_major_version}_{minor}
#define {ns}_DEPRECATED_MACRO_IN_{current_major_version}_{minor}_FOR(f)
#define {ns}_DEPRECATED_ENUMERATOR_IN_{current_major_version}_{minor}
#define {ns}_DEPRECATED_ENUMERATOR_IN_{current_major_version}_{minor}_FOR(f)
#define {ns}_DEPRECATED_TYPE_IN_{current_major_version}_{minor}
#define {ns}_DEPRECATED_TYPE_IN_{current_major_version}_{minor}_FOR(f)
#endif
#if GDK_VERSION_MAX_ALLOWED < GDK_VERSION_{current_major_version}_{minor}
#define {ns}_AVAILABLE_IN_{current_major_version}_{minor} {ns}_UNAVAILABLE ({current_major_version}, {minor})
#define {ns}_AVAILABLE_STATIC_INLINE_IN_{current_major_version}_{minor} GDK_UNAVAILABLE_STATIC_INLINE ({current_major_version}, {minor})
#define {ns}_AVAILABLE_MACRO_IN_{current_major_version}_{minor} GDK_UNAVAILABLE_MACRO ({current_major_version}, {minor})
#define {ns}_AVAILABLE_ENUMERATOR_IN_{current_major_version}_{minor} GDK_UNAVAILABLE_ENUMERATOR ({current_major_version}, {minor})
#define {ns}_AVAILABLE_TYPE_IN_{current_major_version}_{minor} GDK_UNAVAILABLE_TYPE ({current_major_version}, {minor})
#else
#define {ns}_AVAILABLE_IN_{current_major_version}_{minor} _{ns}_EXTERN
#define {ns}_AVAILABLE_STATIC_INLINE_IN_{current_major_version}_{minor}
#define {ns}_AVAILABLE_MACRO_IN_{current_major_version}_{minor}
#define {ns}_AVAILABLE_ENUMERATOR_IN_{current_major_version}_{minor}
#define {ns}_AVAILABLE_TYPE_IN_{current_major_version}_{minor}
#endif
"""
)
)
def main():
parser = argparse.ArgumentParser()
parser.add_argument("gtk_version", help="Current GLib version")
subparsers = parser.add_subparsers()
versions_parser = subparsers.add_parser(
"versions-macros", help="Generate versions macros"
)
versions_parser.add_argument("in_path", help="input file", type=Path)
versions_parser.add_argument("out_path", help="output file", type=Path)
versions_parser.set_defaults(func=gen_versions_macros)
visibility_parser = subparsers.add_parser(
"visibility-macros", help="Generate visibility macros"
)
visibility_parser.add_argument("namespace", help="Macro namespace")
visibility_parser.add_argument("out_path", help="output file", type=Path)
visibility_parser.set_defaults(func=gen_visibility_macros)
args = parser.parse_args()
version = [int(i) for i in args.gtk_version.split(".")]
args.func(args, version[0], version[1], version[2])
if __name__ == "__main__":
main()

View File

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

View File

@@ -1,41 +0,0 @@
#ifndef _MSC_VER
#pragma error "This header is for Microsoft VC or clang-cl only."
#endif /* _MSC_VER */
/* Make MSVC more pedantic, this is a recommended pragma list
* from _Win32_Programming_ by Rector and Newcomer.
*/
#ifndef __clang__
#pragma warning(error:4002) /* too many actual parameters for macro */
#pragma warning(error:4003) /* not enough actual parameters for macro */
#pragma warning(1:4010) /* single-line comment contains line-continuation character */
#pragma warning(error:4013) /* 'function' undefined; assuming extern returning int */
#pragma warning(1:4016) /* no function return type; using int as default */
#pragma warning(error:4020) /* too many actual parameters */
#pragma warning(error:4021) /* too few actual parameters */
#pragma warning(error:4027) /* function declared without formal parameter list */
#pragma warning(error:4029) /* declared formal parameter list different from definition */
#pragma warning(error:4033) /* 'function' must return a value */
#pragma warning(error:4035) /* 'function' : no return value */
#pragma warning(error:4045) /* array bounds overflow */
#pragma warning(error:4047) /* different levels of indirection */
#pragma warning(error:4049) /* terminating line number emission */
#pragma warning(error:4053) /* An expression of type void was used as an operand */
#pragma warning(error:4071) /* no function prototype given */
#pragma warning(disable:4101) /* unreferenced local variable */
#pragma warning(error:4150)
/* G_NORETURN */
#pragma warning(error:4646) /* function declared with __declspec(noreturn) has non-void return type */
#pragma warning(error:4715) /* 'function': not all control paths return a value */
#pragma warning(error:4098) /* 'void' function returning a value */
#pragma warning(disable:4244) /* No possible loss of data warnings */
#pragma warning(disable:4305) /* No truncation from int to char warnings */
#pragma warning(error:4819) /* The file contains a character that cannot be represented in the current code page */
#endif /* __clang__ */
/* work around Microsoft's premature attempt to deprecate the C-Library */
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NONSTDC_NO_WARNINGS

301
config.h.meson Normal file
View File

@@ -0,0 +1,301 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* always defined to indicate that i18n is enabled */
#define ENABLE_NLS 1
/* The prefix for our gettext translation domains. */
#mesondefine GETTEXT_PACKAGE
/* Disable deprecation warnings from glib */
#mesondefine GLIB_DISABLE_DEPRECATION_WARNINGS
/* Define the location where the catalogs will be installed */
#mesondefine GTK_LOCALEDIR
/* Define to 1 if you have the `bind_textdomain_codeset' function. */
#mesondefine HAVE_BIND_TEXTDOMAIN_CODESET
/* Have the cloudproviders library */
#mesondefine HAVE_CLOUDPROVIDERS
/* define if we have colord */
#mesondefine HAVE_COLORD
/* Define to 1 if you have the <crt_externs.h> header file. */
#mesondefine HAVE_CRT_EXTERNS_H
/* Define to 1 if you have the `dcgettext' function. */
#mesondefine HAVE_DCGETTEXT
/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
*/
#mesondefine HAVE_DECL_ISINF
/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't.
*/
#mesondefine HAVE_DECL_ISNAN
/* Define to 1 if you have the declaration of `isnanf', and to 0 if you don't.
*/
#mesondefine HAVE_DECL_ISNANF
/* Define to 1 if you have the <dlfcn.h> header file. */
#mesondefine HAVE_DLFCN_H
/* Have the ffmpeg library */
#mesondefine HAVE_FFMPEG
/* Define to 1 if you have the <ftw.h> header file. */
#mesondefine HAVE_FTW_H
/* Define to 1 if you have the `getpagesize' function. */
#mesondefine HAVE_GETPAGESIZE
/* Define to 1 if you have the `getresuid' function. */
#mesondefine HAVE_GETRESUID
/* Define if gio-unix is available */
#mesondefine HAVE_GIO_UNIX
/* Define if GStreamer support is available */
#mesondefine HAVE_GSTREAMER
/* Define to 1 if you have the <inttypes.h> header file. */
#mesondefine HAVE_INTTYPES_H
/* Define to 1 if the system has the type `IPrintDialogCallback'. */
#mesondefine HAVE_IPRINTDIALOGCALLBACK
/* Define to 1 if you have the <locale.h> header file. */
#mesondefine HAVE_LOCALE_H
/* Define to 1 if you have the `lstat' function. */
#mesondefine HAVE_LSTAT
/* Define to 1 if you have the `mallinfo' function. */
#mesondefine HAVE_MALLINFO
/* Define to 1 if you have the <memory.h> header file. */
#mesondefine HAVE_MEMORY_H
/* Define to 1 if you have the `mkstemp' function. */
#mesondefine HAVE_MKSTEMP
/* Define to 1 if you have a working `mmap' system call. */
#mesondefine HAVE_MMAP
/* Define to 1 if you have the `nearbyint' function. */
#mesondefine HAVE_NEARBYINT
/* Define to 1 if you have the `posix_fallocate' function. */
#mesondefine HAVE_POSIX_FALLOCATE
/* Have the Xrandr extension library */
#mesondefine HAVE_RANDR
/* Have the Xrandr 1.5 extension library */
#mesondefine HAVE_RANDR15
/* Define to 1 if you have the `rint' function. */
#mesondefine HAVE_RINT
/* Define to 1 if you have the `round' function. */
#mesondefine HAVE_ROUND
/* Define to 1 if you have the `sincos' function. */
#mesondefine HAVE_SINCOS
/* Define to 1 if you have the `log2` function */
#mesondefine HAVE_LOG2
/* Define to 1 if you ahve the `exp2` function */
#mesondefine HAVE_EXP2
/* Define to 1 if you have the <stdint.h> header file. */
#mesondefine HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#mesondefine HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#mesondefine HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#mesondefine HAVE_STRING_H
/* Define to 1 if you have the <sys/mman.h> header file. */
#mesondefine HAVE_SYS_MMAN_H
/* Define to 1 if you have the <sys/param.h> header file. */
#mesondefine HAVE_SYS_PARAM_H
/* Have the sysprof-capture library */
#mesondefine HAVE_SYSPROF_CAPTURE
/* Define to 1 if you have the <sys/stat.h> header file. */
#mesondefine HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#mesondefine HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#mesondefine HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#mesondefine HAVE_UNISTD_H
/* Have the XCOMPOSITE X extension */
#mesondefine HAVE_XCOMPOSITE
/* Have the Xcursor library */
#mesondefine HAVE_XCURSOR
/* Have the XFIXES X extension */
#mesondefine HAVE_XFIXES
/* Define to 1 if XFree Xinerama is available */
#mesondefine HAVE_XFREE_XINERAMA
/* Have XGenericEvent */
#mesondefine HAVE_XGENERICEVENTS
/* Define to use XKB extension */
#mesondefine HAVE_XKB
/* Have the SYNC extension library */
#mesondefine HAVE_XSYNC
/* Define to 1 if you have the `_lock_file' function */
#mesondefine HAVE__LOCK_FILE
/* Define to 1 if you have the `flockfile' function */
#mesondefine HAVE_FLOCKFILE
/* Define if _NL_MEASUREMENT_MEASUREMENT is available */
#mesondefine HAVE__NL_MEASUREMENT_MEASUREMENT
/* Define if _NL_PAPER_HEIGHT is available */
#mesondefine HAVE__NL_PAPER_HEIGHT
/* Define if _NL_PAPER_WIDTH is available */
#mesondefine HAVE__NL_PAPER_WIDTH
/* Define if _NL_TIME_FIRST_WEEKDAY is available */
#mesondefine HAVE__NL_TIME_FIRST_WEEKDAY
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#mesondefine LT_OBJDIR
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
#mesondefine NO_MINUS_C_MINUS_O
/* Define to the address where bug reports for this package should be sent. */
#mesondefine PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#mesondefine PACKAGE_NAME
/* Define to the full name and version of this package. */
#mesondefine PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#mesondefine PACKAGE_TARNAME
/* Define to the home page for this package. */
#mesondefine PACKAGE_URL
/* Define to the version of this package. */
#mesondefine PACKAGE_VERSION
/* Use NSBundle functions to determine load paths for libraries, translations,
etc. */
#mesondefine QUARTZ_RELOCATION
/* Define to 1 if you have the ANSI C header files. */
#mesondefine STDC_HEADERS
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
/* Define to 1 if XInput 2.2 is available */
#mesondefine XINPUT_2_2
/* Define to 1 if the X Window System is missing or not being used. */
#mesondefine X_DISPLAY_MISSING
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#mesondefine _FILE_OFFSET_BITS
/* defines how to decorate public symbols while building */
#mesondefine _GDK_EXTERN
/* Define for large files, on AIX-style hosts. */
#mesondefine _LARGE_FILES
/* Define to 1 if on MINIX. */
#mesondefine _MINIX
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#mesondefine _POSIX_1_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#mesondefine _POSIX_SOURCE
/* Define to `int' if <sys/types.h> doesn't define. */
#mesondefine gid_t
/* Define to `int' if <sys/types.h> doesn't define. */
#mesondefine uid_t
/* Define to 1 if linux/memfd.h exists */
#mesondefine HAVE_LINUX_MEMFD_H
#mesondefine HAVE_LINUX_INPUT_H
#mesondefine HAVE_DEV_EVDEV_INPUT_H
#mesondefine GTK_SYSCONFDIR
#mesondefine GTK_LOCALEDIR
#mesondefine GTK_DATADIR
#mesondefine GTK_LIBDIR
#mesondefine GTK_PRINT_BACKENDS
#mesondefine HAVE_CAIRO_SCRIPT_INTERPRETER
#mesondefine HAVE_HARFBUZZ
#mesondefine HAVE_PANGOFT
#mesondefine ISO_CODES_PREFIX
/* Define if tracker3 is available */
#mesondefine HAVE_TRACKER3

View File

@@ -81,11 +81,11 @@ constraint_editor_application_activate (GApplication *app)
static void
constraint_editor_application_open (GApplication *app,
GFile **files,
int n_files,
const char *hint)
gint n_files,
const gchar *hint)
{
ConstraintEditorWindow *win;
int i;
gint i;
for (i = 0; i < n_files; i++)
{

View File

@@ -36,7 +36,7 @@ struct _ConstraintEditorWindow
G_DEFINE_TYPE(ConstraintEditorWindow, constraint_editor_window, GTK_TYPE_APPLICATION_WINDOW);
static GtkConstraintTarget *
find_target (GListModel *model,
find_target (GListModel *model,
GtkConstraintTarget *orig)
{
const char *name;
@@ -163,30 +163,20 @@ constraint_editor_window_load (ConstraintEditorWindow *self,
GtkConstraint *clone;
GtkConstraintTarget *target;
GtkConstraintTarget *source;
GtkConstraintAttribute source_attr;
item = g_list_model_get_item (list, i);
constraint = GTK_CONSTRAINT (item);
target = gtk_constraint_get_target (constraint);
source = gtk_constraint_get_source (constraint);
source_attr = gtk_constraint_get_source_attribute (constraint);
if (source == NULL && source_attr == GTK_CONSTRAINT_ATTRIBUTE_NONE)
clone = gtk_constraint_new_constant (find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), target),
clone = gtk_constraint_new (find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), target),
gtk_constraint_get_target_attribute (constraint),
gtk_constraint_get_relation (constraint),
find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), source),
gtk_constraint_get_target_attribute (constraint),
gtk_constraint_get_multiplier (constraint),
gtk_constraint_get_constant (constraint),
gtk_constraint_get_strength (constraint));
else
clone = gtk_constraint_new (find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), target),
gtk_constraint_get_target_attribute (constraint),
gtk_constraint_get_relation (constraint),
find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), source),
source_attr,
gtk_constraint_get_multiplier (constraint),
gtk_constraint_get_constant (constraint),
gtk_constraint_get_strength (constraint));
constraint_view_add_constraint (CONSTRAINT_VIEW (self->view), clone);
@@ -202,36 +192,43 @@ constraint_editor_window_load (ConstraintEditorWindow *self,
}
static void
open_response_cb (GObject *source,
GAsyncResult *result,
void *user_data)
open_response_cb (GtkNativeDialog *dialog,
gint response,
ConstraintEditorWindow *self)
{
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
ConstraintEditorWindow *self = user_data;
GFile *file;
gtk_native_dialog_hide (dialog);
file = gtk_file_dialog_open_finish (dialog, result, NULL);
if (file)
if (response == GTK_RESPONSE_ACCEPT)
{
GFile *file;
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
constraint_editor_window_load (self, file);
g_object_unref (file);
}
gtk_native_dialog_destroy (dialog);
}
static void
open_cb (GtkWidget *button,
ConstraintEditorWindow *self)
{
GtkFileDialog *dialog;
GFile *cwd;
GtkFileChooserNative *dialog;
dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_title (dialog, "Open file");
cwd = g_file_new_for_path (".");
gtk_file_dialog_set_initial_folder (dialog, cwd);
dialog = gtk_file_chooser_native_new ("Open file",
GTK_WINDOW (self),
GTK_FILE_CHOOSER_ACTION_OPEN,
"_Load",
"_Cancel");
gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (dialog), TRUE);
GFile *cwd = g_file_new_for_path (".");
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), cwd, NULL);
g_object_unref (cwd);
gtk_file_dialog_open (dialog, GTK_WINDOW (self), NULL, open_response_cb, self);
g_object_unref (dialog);
g_signal_connect (dialog, "response", G_CALLBACK (open_response_cb), self);
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
}
static void
@@ -287,24 +284,23 @@ serialize_model (GListModel *list)
static void
save_response_cb (GObject *source,
GAsyncResult *result,
void *user_data)
save_response_cb (GtkNativeDialog *dialog,
gint response,
ConstraintEditorWindow *self)
{
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
ConstraintEditorWindow *self = user_data;
GFile *file;
gtk_native_dialog_hide (dialog);
file = gtk_file_dialog_save_finish (dialog, result, NULL);
if (file)
if (response == GTK_RESPONSE_ACCEPT)
{
GListModel *model;
GFile *file;
char *text;
GError *error = NULL;
model = constraint_view_get_model (CONSTRAINT_VIEW (self->view));
text = serialize_model (model);
g_file_replace_contents (file, text, strlen (text),
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
g_file_replace_contents (file, text, -1,
NULL, FALSE,
G_FILE_CREATE_NONE,
NULL,
@@ -312,46 +308,54 @@ save_response_cb (GObject *source,
&error);
if (error != NULL)
{
GtkAlertDialog *alert;
GtkWidget *message_dialog;
alert = gtk_alert_dialog_new ("Saving failed");
gtk_alert_dialog_set_detail (alert, error->message);
gtk_alert_dialog_show (alert,
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self))));
g_object_unref (alert);
message_dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self))),
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_OK,
"Saving failed");
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog),
"%s", error->message);
g_signal_connect (message_dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
gtk_widget_show (message_dialog);
g_error_free (error);
}
g_free (text);
g_object_unref (file);
}
gtk_native_dialog_destroy (dialog);
}
static void
save_cb (GtkWidget *button,
ConstraintEditorWindow *self)
{
GtkFileDialog *dialog;
GFile *cwd;
GtkFileChooserNative *dialog;
dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_title (dialog, "Save constraints");
cwd = g_file_new_for_path (".");
gtk_file_dialog_set_initial_folder (dialog, cwd);
dialog = gtk_file_chooser_native_new ("Save constraints",
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
GTK_FILE_CHOOSER_ACTION_SAVE,
"_Save",
"_Cancel");
gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (dialog), TRUE);
GFile *cwd = g_file_new_for_path (".");
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), cwd, NULL);
g_object_unref (cwd);
gtk_file_dialog_save (dialog,
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
NULL,
save_response_cb, self);
g_object_unref (dialog);
g_signal_connect (dialog, "response", G_CALLBACK (save_response_cb), self);
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
}
static void
constraint_editor_window_dispose (GObject *object)
constraint_editor_window_finalize (GObject *object)
{
gtk_widget_dispose_template (GTK_WIDGET (object), CONSTRAINT_EDITOR_WINDOW_TYPE);
//ConstraintEditorWindow *self = (ConstraintEditorWindow *)object;
G_OBJECT_CLASS (constraint_editor_window_parent_class)->dispose (object);
G_OBJECT_CLASS (constraint_editor_window_parent_class)->finalize (object);
}
static int child_counter;
@@ -426,7 +430,7 @@ edit_constraint (ConstraintEditorWindow *win,
g_signal_connect (editor, "done", G_CALLBACK (constraint_editor_done), win);
gtk_window_present (GTK_WINDOW (window));
gtk_widget_show (window);
}
static void
@@ -459,7 +463,7 @@ edit_guide (ConstraintEditorWindow *win,
gtk_window_set_child (GTK_WINDOW (window), GTK_WIDGET (editor));
g_signal_connect (editor, "done", G_CALLBACK (guide_editor_done), win);
gtk_window_present (GTK_WINDOW (window));
gtk_widget_show (window);
}
static void
@@ -483,9 +487,7 @@ constraint_editor_window_class_init (ConstraintEditorWindowClass *class)
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
g_type_ensure (CONSTRAINT_VIEW_TYPE);
object_class->dispose = constraint_editor_window_dispose;
object_class->finalize = constraint_editor_window_finalize;
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gtk/gtk4/constraint-editor/constraint-editor-window.ui");

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="ConstraintEditorWindow" parent="GtkApplicationWindow">
<style>
<class name="devel"/>
</style>
<property name="title" translatable="yes">GTK Constraint Editor</property>
<property name="default-width">1024</property>
<property name="default-height">768</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header">
<property name="show-title-buttons">1</property>
<child type="start">
<object class="GtkButton">
<property name="icon-name">document-open-symbolic</property>

View File

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

View File

@@ -1,21 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkStringList" id="targets">
<items>
<item>None</item>
<item>Left</item>
<item>Right</item>
<item>Top</item>
<item>Bottom</item>
<item>Start</item>
<item>End</item>
<item>Width</item>
<item>Height</item>
<item>Center X</item>
<item>Center Y</item>
<item>Baseline</item>
</items>
</object>
<template class="ConstraintEditor" parent="GtkWidget">
<child>
<object class="GtkGrid" id="grid">
@@ -29,28 +13,27 @@
<object class="GtkLabel">
<property name="label">Target</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkDropDown" id="target">
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<signal name="notify::selected" handler="update_button" swapped="yes"/>
<object class="GtkComboBoxText" id="target">
<signal name="changed" handler="update_preview" swapped="yes"/>
<signal name="changed" handler="update_button" swapped="yes"/>
<layout>
<property name="column">1</property>
<property name="row">1</property>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkDropDown" id="target_attr">
<property name="model">targets</property>
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<object class="GtkComboBoxText" id="target_attr">
<signal name="changed" handler="update_preview" swapped="yes"/>
<layout>
<property name="column">2</property>
<property name="row">1</property>
<property name="left-attach">2</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
@@ -58,26 +41,17 @@
<object class="GtkLabel">
<property name="label">Relation</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkDropDown" id="relation">
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<property name="model">
<object class="GtkStringList">
<items>
<item>≤</item>
<item>=</item>
<item>≥</item>
</items>
</object>
</property>
<object class="GtkComboBoxText" id="relation">
<signal name="changed" handler="update_preview" swapped="yes"/>
<layout>
<property name="column">1</property>
<property name="row">2</property>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
</layout>
</object>
</child>
@@ -85,30 +59,28 @@
<object class="GtkLabel">
<property name="label">Source</property>
<layout>
<property name="column">0</property>
<property name="row">3</property>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkDropDown" id="source">
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<signal name="notify::selected" handler="update_button" swapped="yes"/>
<object class="GtkComboBoxText" id="source">
<signal name="changed" handler="update_preview" swapped="yes"/>
<signal name="changed" handler="update_button" swapped="yes"/>
<layout>
<property name="column">1</property>
<property name="row">3</property>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkDropDown" id="source_attr">
<property name="model">targets</property>
<signal name="notify::selected" handler="update_preview" swapped="yes"/>
<signal name="notify::selected" handler="source_attr_changed" swapped="yes"/>
<signal name="notify::selected" handler="update_button" swapped="yes"/>
<object class="GtkComboBoxText" id="source_attr">
<signal name="changed" handler="update_preview" swapped="yes"/>
<signal name="changed" handler="source_attr_changed" swapped="yes"/>
<layout>
<property name="column">2</property>
<property name="row">3</property>
<property name="left-attach">2</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>
@@ -116,8 +88,8 @@
<object class="GtkLabel">
<property name="label">Multiplier</property>
<layout>
<property name="column">0</property>
<property name="row">4</property>
<property name="left-attach">0</property>
<property name="top-attach">4</property>
</layout>
</object>
</child>
@@ -125,8 +97,8 @@
<object class="GtkEntry" id="multiplier">
<signal name="changed" handler="update_preview" swapped="yes"/>
<layout>
<property name="column">1</property>
<property name="row">4</property>
<property name="left-attach">1</property>
<property name="top-attach">4</property>
</layout>
</object>
</child>
@@ -134,8 +106,8 @@
<object class="GtkLabel">
<property name="label">Constant</property>
<layout>
<property name="column">0</property>
<property name="row">5</property>
<property name="left-attach">0</property>
<property name="top-attach">5</property>
</layout>
</object>
</child>
@@ -143,8 +115,8 @@
<object class="GtkEntry" id="constant">
<signal name="changed" handler="update_preview" swapped="yes"/>
<layout>
<property name="column">1</property>
<property name="row">5</property>
<property name="left-attach">1</property>
<property name="top-attach">5</property>
</layout>
</object>
</child>
@@ -152,26 +124,16 @@
<object class="GtkLabel">
<property name="label">Strength</property>
<layout>
<property name="column">0</property>
<property name="row">6</property>
<property name="left-attach">0</property>
<property name="top-attach">6</property>
</layout>
</object>
</child>
<child>
<object class="GtkDropDown" id="strength">
<property name="model">
<object class="GtkStringList">
<items>
<item>Weak</item>
<item>Medium</item>
<item>Strong</item>
<item>Required</item>
</items>
</object>
</property>
<object class="GtkComboBoxText" id="strength">
<layout>
<property name="column">1</property>
<property name="row">6</property>
<property name="left-attach">1</property>
<property name="top-attach">6</property>
</layout>
</object>
</child>
@@ -179,8 +141,8 @@
<object class="GtkLabel" id="preview">
<property name="xalign">0</property>
<layout>
<property name="column">1</property>
<property name="row">7</property>
<property name="left-attach">1</property>
<property name="top-attach">7</property>
<property name="column-span">2</property>
</layout>
<attributes>
@@ -193,8 +155,8 @@
<property name="label">Create</property>
<signal name="clicked" handler="create_constraint"/>
<layout>
<property name="column">2</property>
<property name="row">8</property>
<property name="left-attach">2</property>
<property name="top-attach">8</property>
</layout>
</object>
</child>

View File

@@ -174,25 +174,28 @@ constraint_view_init (ConstraintView *self)
manager = gtk_constraint_layout_new ();
gtk_widget_set_layout_manager (GTK_WIDGET (self), manager);
guides = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (manager));
all_constraints = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (manager));
filter = GTK_FILTER (gtk_custom_filter_new (omit_internal, NULL, NULL));
constraints = (GListModel *)gtk_filter_list_model_new (all_constraints, filter);
all_children = gtk_widget_observe_children (GTK_WIDGET (self));
filter = GTK_FILTER (gtk_custom_filter_new (omit_internal, NULL, NULL));
all_constraints = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (manager));
guides = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (manager));
filter = gtk_custom_filter_new (omit_internal, NULL, NULL);
constraints = (GListModel *)gtk_filter_list_model_new (all_constraints, filter);
g_object_unref (filter);
filter = gtk_custom_filter_new (omit_internal, NULL, NULL);
children = (GListModel *)gtk_filter_list_model_new (all_children, filter);
g_object_unref (filter);
list = g_list_store_new (G_TYPE_LIST_MODEL);
g_list_store_append (list, children);
g_list_store_append (list, guides);
g_list_store_append (list, constraints);
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list)));
g_object_unref (children);
g_object_unref (guides);
g_object_unref (constraints);
g_object_unref (all_children);
g_object_unref (all_constraints);
g_object_unref (list);
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_LIST_MODEL (list)));
controller = (GtkEventController *)gtk_gesture_drag_new ();
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);

View File

@@ -57,30 +57,25 @@ static guint signals[LAST_SIGNAL];
G_DEFINE_TYPE(GuideEditor, guide_editor, GTK_TYPE_WIDGET);
static GtkConstraintStrength
get_strength (unsigned int id)
static void
guide_strength_combo (GtkWidget *combo)
{
switch (id)
{
case 0: return GTK_CONSTRAINT_STRENGTH_WEAK;
case 1: return GTK_CONSTRAINT_STRENGTH_MEDIUM;
case 2: return GTK_CONSTRAINT_STRENGTH_STRONG;
case 3: return GTK_CONSTRAINT_STRENGTH_REQUIRED;
default: g_assert_not_reached ();
}
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "weak", "Weak");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "medium", "Medium");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "strong", "Strong");
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "required", "Required");
}
static unsigned int
get_strength_id (GtkConstraintStrength strength)
static GtkConstraintStrength
get_strength (const char *id)
{
switch (strength)
{
case GTK_CONSTRAINT_STRENGTH_WEAK: return 0;
case GTK_CONSTRAINT_STRENGTH_MEDIUM: return 1;
case GTK_CONSTRAINT_STRENGTH_STRONG: return 2;
case GTK_CONSTRAINT_STRENGTH_REQUIRED: return 3;
default: g_assert_not_reached ();
}
GtkConstraintStrength strength;
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
GEnumValue *value = g_enum_get_value_by_nick (class, id);
strength = value->value;
g_type_class_unref (class);
return strength;
}
static const char *
@@ -121,11 +116,11 @@ static void
create_guide (GtkButton *button,
GuideEditor *editor)
{
const char *id;
int strength;
const char *name;
int w, h;
GtkConstraintGuide *guide;
unsigned int id;
if (editor->guide)
guide = g_object_ref (editor->guide);
@@ -147,7 +142,7 @@ create_guide (GtkButton *button,
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->max_height));
gtk_constraint_guide_set_max_size (guide, w, h);
id = gtk_drop_down_get_selected (GTK_DROP_DOWN (editor->strength));
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->strength));
strength = get_strength (id);
gtk_constraint_guide_set_strength (guide, strength);
@@ -194,9 +189,14 @@ guide_editor_constructed (GObject *object)
{
GuideEditor *editor = GUIDE_EDITOR (object);
guide_strength_combo (editor->strength);
g_signal_connect (editor->min_width, "input", G_CALLBACK (min_input), NULL);
g_signal_connect (editor->min_height, "input", G_CALLBACK (min_input), NULL);
g_signal_connect (editor->max_width, "input", G_CALLBACK (max_input), NULL);
g_signal_connect (editor->max_height, "input", G_CALLBACK (max_input), NULL);
if (editor->guide)
@@ -222,7 +222,8 @@ guide_editor_constructed (GObject *object)
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), h);
strength = gtk_constraint_guide_get_strength (editor->guide);
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (strength));
nick = get_strength_nick (strength);
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), nick);
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
}
@@ -242,7 +243,7 @@ guide_editor_constructed (GObject *object)
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_width), G_MAXINT);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), G_MAXINT);
gtk_drop_down_set_selected (GTK_DROP_DOWN (editor->strength), get_strength_id (GTK_CONSTRAINT_STRENGTH_MEDIUM));
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), "medium");
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
}
@@ -293,10 +294,9 @@ guide_editor_dispose (GObject *object)
{
GuideEditor *self = (GuideEditor *)object;
g_clear_pointer (&self->grid, gtk_widget_unparent);
g_clear_object (&self->guide);
gtk_widget_dispose_template (GTK_WIDGET (self), GUIDE_EDITOR_TYPE);
G_OBJECT_CLASS (guide_editor_parent_class)->dispose (object);
}

View File

@@ -55,8 +55,8 @@
<object class="GtkLabel">
<property name="label">Name</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
@@ -64,8 +64,8 @@
<object class="GtkEntry" id="name">
<property name="max-width-chars">20</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
<property name="column-span">2</property>
</layout>
</object>
@@ -74,8 +74,8 @@
<object class="GtkLabel">
<property name="label">Min Size</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
@@ -84,8 +84,8 @@
<property name="adjustment">min_width_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="column">1</property>
<property name="row">1</property>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
@@ -94,8 +94,8 @@
<property name="adjustment">min_height_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="column">2</property>
<property name="row">1</property>
<property name="left-attach">2</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
@@ -103,8 +103,8 @@
<object class="GtkLabel">
<property name="label">Nat Size</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</layout>
</object>
</child>
@@ -113,8 +113,8 @@
<property name="adjustment">nat_width_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="column">1</property>
<property name="row">2</property>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
</layout>
</object>
</child>
@@ -123,8 +123,8 @@
<property name="adjustment">nat_height_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="column">2</property>
<property name="row">2</property>
<property name="left-attach">2</property>
<property name="top-attach">2</property>
</layout>
</object>
</child>
@@ -132,8 +132,8 @@
<object class="GtkLabel">
<property name="label">Max Size</property>
<layout>
<property name="column">0</property>
<property name="row">3</property>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>
@@ -142,8 +142,8 @@
<property name="adjustment">max_width_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="column">1</property>
<property name="row">3</property>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>
@@ -152,8 +152,8 @@
<property name="adjustment">max_height_adj</property>
<property name="max-width-chars">5</property>
<layout>
<property name="column">2</property>
<property name="row">3</property>
<property name="left-attach">2</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>
@@ -161,26 +161,16 @@
<object class="GtkLabel">
<property name="label">Strength</property>
<layout>
<property name="column">0</property>
<property name="row">4</property>
<property name="left-attach">0</property>
<property name="top-attach">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkDropDown" id="strength">
<property name="model">
<object class="GtkStringList">
<items>
<item>Weak</item>
<item>Medium</item>
<item>Strong</item>
<item>Required</item>
</items>
</object>
</property>
<object class="GtkComboBoxText" id="strength">
<layout>
<property name="column">1</property>
<property name="row">4</property>
<property name="left-attach">1</property>
<property name="top-attach">4</property>
<property name="column-span">2</property>
</layout>
</object>
@@ -190,8 +180,8 @@
<property name="label">Create</property>
<signal name="clicked" handler="create_guide"/>
<layout>
<property name="column">2</property>
<property name="row">5</property>
<property name="left-attach">2</property>
<property name="top-attach">5</property>
</layout>
</object>
</child>

View File

@@ -8,16 +8,14 @@ constraint_editor_sources = [
]
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
'constraint-editor.gresource.xml',
source_dir: meson.current_source_dir(),
)
'constraint-editor.gresource.xml',
source_dir: '.')
executable('gtk4-constraint-editor',
sources: [ constraint_editor_sources, constraint_editor_resources, ],
c_args: common_cflags,
dependencies: libgtk_dep,
include_directories: confinc,
win_subsystem: 'windows',
link_args: extra_demo_ldflags,
install: false,
)
constraint_editor_sources, constraint_editor_resources,
c_args: common_cflags,
dependencies: libgtk_dep,
include_directories: confinc,
gui_app: true,
link_args: extra_demo_ldflags,
install: false)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,345 +0,0 @@
// Originally from: https://www.shadertoy.com/view/wsjBD3
// License CC0: A battered alien planet
// Been experimenting with space inspired shaders
#define PI 3.141592654
#define TAU (2.0*PI)
#define TOLERANCE 0.00001
#define MAX_ITER 65
#define MIN_DISTANCE 0.01
#define MAX_DISTANCE 9.0
const vec3 skyCol1 = vec3(0.35, 0.45, 0.6);
const vec3 skyCol2 = vec3(0.4, 0.7, 1.0);
const vec3 skyCol3 = pow(skyCol1, vec3(0.25));
const vec3 sunCol1 = vec3(1.0,0.6,0.4);
const vec3 sunCol2 = vec3(1.0,0.9,0.7);
const vec3 smallSunCol1 = vec3(1.0,0.5,0.25)*0.5;
const vec3 smallSunCol2 = vec3(1.0,0.5,0.25)*0.5;
const vec3 mountainColor = 1.0*sqrt(vec3(0.95, 0.65, 0.45));
const float cellWidth = 1.0;
const vec4 planet = vec4(80.0, -20.0, 100.0, 50.0)*1000.0;
void rot(inout vec2 p, float a) {
float c = cos(a);
float s = sin(a);
p = vec2(p.x*c + p.y*s, -p.x*s + p.y*c);
}
vec2 mod2(inout vec2 p, vec2 size) {
vec2 c = floor((p + size*0.5)/size);
p = mod(p + size*0.5,size) - size*0.5;
return c;
}
float circle(vec2 p, float r) {
return length(p) - r;
}
float egg(vec2 p, float ra, float rb) {
const float k = sqrt(3.0);
p.x = abs(p.x);
float r = ra - rb;
return ((p.y<0.0) ? length(vec2(p.x, p.y )) - r :
(k*(p.x+r)<p.y) ? length(vec2(p.x, p.y-k*r)) :
length(vec2(p.x+r,p.y )) - 2.0*r) - rb;
}
vec2 hash(vec2 p) {
p = vec2(dot (p, vec2 (127.1, 311.7)), dot (p, vec2 (269.5, 183.3)));
return -1. + 2.*fract (sin (p)*43758.5453123);
}
vec2 raySphere(vec3 ro, vec3 rd, vec4 sphere) {
vec3 center = sphere.xyz;
float radius = sphere.w;
vec3 m = ro - center.xyz;
float b = dot(m, rd);
float c = dot(m, m) - radius*radius;
if(c > 0.0 && b > 0.0) return vec2(-1.0, -1.0);
float discr = b * b - c;
if(discr < 0.0) return vec2(-1.0);
float normalMultiplier = 1.0;
float s = sqrt(discr);
float t0 = -b - s;
float t1 = -b + s;;
return vec2(t0, t1);
}
float noize1(vec2 p) {
vec2 n = mod2(p, vec2(cellWidth));
vec2 hh = hash(sqrt(2.0)*(n+1000.0));
hh.x *= hh.y;
float r = 0.225*cellWidth;
float d = circle(p, 2.0*r);
float h = hh.x*smoothstep(0.0, r, -d);
return h*0.25;
}
float noize2(vec2 p) {
vec2 n = mod2(p, vec2(cellWidth));
vec2 hh = hash(sqrt(2.0)*(n+1000.0));
hh.x *= hh.y;
rot(p, TAU*hh.y);
float r = 0.45*cellWidth;
// float d = circle(p, 1.0*r);
float d = egg(p, 0.75*r, 0.5*r*abs(hh.y));
float h = (hh.x)*smoothstep(0.0, r, -2.0*d);
return h*0.275;
}
float height(vec2 p, float dd, int mx) {
const float aa = 0.45;
const float ff = 2.03;
const float tt = 1.2;
const float oo = 3.93;
const float near = 0.25;
const float far = 0.65;
float a = 1.0;
float o = 0.2;
float s = 0.0;
float d = 0.0;
int i = 0;
for (; i < 4;++i) {
float nn = a*noize2(p);
s += nn;
d += abs(a);
p += o;
a *= aa;
p *= ff;
o *= oo;
rot(p, tt);
}
float lod = s/d;
float rdd = dd/MAX_DISTANCE;
mx = int(mix(float(4), float(mx), step(rdd, far)));
for (; i < mx; ++i) {
float nn = a*noize1(p);
s += nn;
d += abs(a);
p += o;
a *= aa;
p *= ff;
o *= oo;
rot(p, tt);
}
float hid = (s/d);
return mix(hid, lod, smoothstep(near, far, rdd));
}
float loheight(vec2 p, float d) {
return height(p, d, 0);
}
float height(vec2 p, float d) {
return height(p, d, 6);
}
float hiheight(vec2 p, float d) {
return height(p, d, 8);
}
vec3 normal(vec2 p, float d) {
vec2 eps = vec2(0.00125, 0.0);
vec3 n;
n.x = (hiheight(p - eps.xy, d) - hiheight(p + eps.xy, d));
n.y = 2.0*eps.x;
n.z = (hiheight(p - eps.yx, d) - hiheight(p + eps.yx, d));
return normalize(n);
}
const float stepLength[] = float[](0.9, 0.25);
float march(vec3 ro, vec3 rd, out int max_iter) {
float dt = 0.1;
float d = MIN_DISTANCE;
int currentStep = 0;
float lastd = d;
for (int i = 0; i < MAX_ITER; ++i)
{
vec3 p = ro + d*rd;
float h = height(p.xz, d);
if (d > MAX_DISTANCE) {
max_iter = i;
return MAX_DISTANCE;
}
float hd = p.y - h;
if (hd < TOLERANCE) {
++currentStep;
if (currentStep >= stepLength.length()) {
max_iter = i;
return d;
}
d = lastd;
continue;
}
float sl = stepLength[currentStep];
dt = max(hd, TOLERANCE)*sl + 0.0025*d;
lastd = d;
d += dt;
}
max_iter = MAX_ITER;
return MAX_DISTANCE;
}
vec3 sunDirection() {
return normalize(vec3(-0.5, 0.085, 1.0));
}
vec3 smallSunDirection() {
return normalize(vec3(-0.2, -0.05, 1.0));
}
float psin(float f) {
return 0.5 + 0.5*sin(f);
}
vec3 skyColor(vec3 ro, vec3 rd) {
vec3 sunDir = sunDirection();
vec3 smallSunDir = smallSunDirection();
float sunDot = max(dot(rd, sunDir), 0.0);
float smallSunDot = max(dot(rd, smallSunDir), 0.0);
float angle = atan(rd.y, length(rd.xz))*2.0/PI;
vec3 skyCol = mix(mix(skyCol1, skyCol2, max(0.0, angle)), skyCol3, clamp(-angle*2.0, 0.0, 1.0));
vec3 sunCol = 0.5*sunCol1*pow(sunDot, 20.0) + 8.0*sunCol2*pow(sunDot, 2000.0);
vec3 smallSunCol = 0.5*smallSunCol1*pow(smallSunDot, 200.0) + 8.0*smallSunCol2*pow(smallSunDot, 20000.0);
vec3 dust = pow(sunCol2*mountainColor, vec3(1.75))*smoothstep(0.05, -0.1, rd.y)*0.5;
vec2 si = raySphere(ro, rd, planet);
vec3 planetSurface = ro + si.x*rd;
vec3 planetNormal = normalize(planetSurface - planet.xyz);
float planetDiff = max(dot(planetNormal, sunDir), 0.0);
float planetBorder = max(dot(planetNormal, -rd), 0.0);
float planetLat = (planetSurface.x+planetSurface.y)*0.0005;
vec3 planetCol = mix(1.3*vec3(0.9, 0.8, 0.7), 0.3*vec3(0.9, 0.8, 0.7), pow(psin(planetLat+1.0)*psin(sqrt(2.0)*planetLat+2.0)*psin(sqrt(3.5)*planetLat+3.0), 0.5));
vec3 final = vec3(0.0);
final += step(0.0, si.x)*pow(planetDiff, 0.75)*planetCol*smoothstep(-0.075, 0.0, rd.y)*smoothstep(0.0, 0.1, planetBorder);
final += skyCol + sunCol + smallSunCol + dust;
return final;
}
vec3 getColor(vec3 ro, vec3 rd) {
int max_iter = 0;
vec3 skyCol = skyColor(ro, rd);
vec3 col = vec3(0);
float d = march(ro, rd, max_iter);
if (d < MAX_DISTANCE) {
vec3 sunDir = sunDirection();
vec3 osunDir = sunDir*vec3(-1.0, .0, -1.0);
vec3 p = ro + d*rd;
vec3 normal = normal(p.xz, d);
float amb = 0.2;
float dif1 = max(0.0, dot(sunDir, normal));
vec3 shd1 = sunCol2*mix(amb, 1.0, pow(dif1, 0.75));
float dif2 = max(0.0, dot(osunDir, normal));
vec3 shd2 = sunCol1*mix(amb, 1.0, pow(dif2, 0.75));
vec3 ref = reflect(rd, normal);
vec3 rcol = skyColor(p, ref);
col = mountainColor*amb*skyCol3;
col += mix(shd1, shd2, -0.5)*mountainColor;
float fre = max(dot(normal, -rd), 0.0);
fre = pow(1.0 - fre, 5.0);
col += rcol*fre*0.5;
col += (1.0*p.y);
col = tanh(col);
col = mix(col, skyCol, smoothstep(0.5*MAX_DISTANCE, 1.0*MAX_DISTANCE, d));
} else {
col = skyCol;
}
// col += vec3(1.1, 0.0, 0.0)* smoothstep(0.25, 1.0,(float(max_iter)/float(MAX_ITER)));
return col;
}
vec3 getSample1(vec2 p, float time) {
float off = 0.5*iTime;
vec3 ro = vec3(0.5, 1.0-0.25, -2.0 + off);
vec3 la = ro + vec3(0.0, -0.30, 2.0);
vec3 ww = normalize(la - ro);
vec3 uu = normalize(cross(vec3(0.0,1.0,0.0), ww));
vec3 vv = normalize(cross(ww, uu));
vec3 rd = normalize(p.x*uu + p.y*vv + 2.0*ww);
vec3 col = getColor(ro, rd) ;
return col;
}
vec3 getSample2(vec2 p, float time) {
p.y-=time*0.25;
float h = height(p, 0.0);
vec3 n = normal(p, 0.0);
vec3 lp = vec3(10.0, -1.2, 0.0);
vec3 ld = normalize(vec3(p.x, h, p.y)- lp);
float d = max(dot(ld, n), 0.0);
vec3 col = vec3(0.0);
col = vec3(1.0)*(h+0.1);
col += vec3(1.5)*pow(d, 0.75);
return col;
}
void mainImage(out vec4 fragColor, vec2 fragCoord) {
vec2 q = fragCoord.xy/iResolution.xy;
vec2 p = -1.0 + 2.0*q;
p.x *= iResolution.x/iResolution.y;
vec3 col = getSample1(p, iTime);
fragColor = vec4(col, 1.0);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,3 +1,4 @@
#include "config.h"
#include <gtk/gtk.h>
@@ -33,12 +34,22 @@ static void create_window (GApplication *app, const char *contents);
static void
show_action_dialog (GSimpleAction *action)
{
GtkAlertDialog *dialog;
const gchar *name;
GtkWidget *dialog;
dialog = gtk_alert_dialog_new ("You activated action: \"%s\"",
g_action_get_name (G_ACTION (action)));
gtk_alert_dialog_show (dialog, NULL);
g_object_unref (dialog);
name = g_action_get_name (G_ACTION (action));
dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
"You activated action: \"%s\"",
name);
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_window_destroy), NULL);
gtk_widget_show (dialog);
}
static void
@@ -47,9 +58,9 @@ show_action_infobar (GSimpleAction *action,
gpointer data)
{
DemoApplicationWindow *window = data;
char *text;
const char *name;
const char *value;
gchar *text;
const gchar *name;
const gchar *value;
name = g_action_get_name (G_ACTION (action));
value = g_variant_get_string (parameter, NULL);
@@ -57,7 +68,7 @@ show_action_infobar (GSimpleAction *action,
text = g_strdup_printf ("You activated radio action: \"%s\".\n"
"Current value: %s", name, value);
gtk_label_set_text (GTK_LABEL (window->message), text);
gtk_widget_set_visible (window->infobar, TRUE);
gtk_widget_show (window->infobar);
g_free (text);
}
@@ -80,38 +91,43 @@ activate_new (GSimpleAction *action,
}
static void
open_response_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
open_response_cb (GtkNativeDialog *dialog,
gint response_id,
gpointer user_data)
{
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
GApplication *app = G_APPLICATION (user_data);
GtkFileChooserNative *native = user_data;
GApplication *app = g_object_get_data (G_OBJECT (native), "app");
GtkWidget *message_dialog;
GFile *file;
char *contents;
GError *error = NULL;
file = gtk_file_dialog_open_finish (dialog, result, &error);
if (file)
if (response_id == GTK_RESPONSE_ACCEPT)
{
char *contents;
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (native));
if (g_file_load_contents (file, NULL, &contents, NULL, NULL, &error))
{
create_window (app, contents);
g_free (contents);
}
else
{
message_dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Error loading file: \"%s\"",
error->message);
g_signal_connect (message_dialog, "response",
G_CALLBACK (gtk_window_destroy), NULL);
gtk_widget_show (message_dialog);
g_error_free (error);
}
}
if (error)
{
GtkAlertDialog *alert;
alert = gtk_alert_dialog_new ("Error loading file: \"%s\"", error->message);
gtk_alert_dialog_show (alert, NULL);
g_object_unref (alert);
g_error_free (error);
}
g_object_unref (app);
gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (native));
g_object_unref (native);
}
@@ -121,11 +137,21 @@ activate_open (GSimpleAction *action,
gpointer user_data)
{
GApplication *app = user_data;
GtkFileDialog *dialog;
GtkFileChooserNative *native;
dialog = gtk_file_dialog_new ();
gtk_file_dialog_open (dialog, NULL, NULL, open_response_cb, g_object_ref (app));
g_object_unref (dialog);
native = gtk_file_chooser_native_new ("Open File",
NULL,
GTK_FILE_CHOOSER_ACTION_OPEN,
"_Open",
"_Cancel");
g_object_set_data_full (G_OBJECT (native), "app", g_object_ref (app), g_object_unref);
g_signal_connect (native,
"response",
G_CALLBACK (open_response_cb),
native);
gtk_native_dialog_show (GTK_NATIVE_DIALOG (native));
}
static void
@@ -159,7 +185,7 @@ activate_about (GSimpleAction *action,
{
GtkWidget *window = user_data;
const char *authors[] = {
const gchar *authors[] = {
"Peter Mattis",
"Spencer Kimball",
"Josh MacDonald",
@@ -167,7 +193,7 @@ activate_about (GSimpleAction *action,
NULL
};
const char *documentors[] = {
const gchar *documentors[] = {
"Owen Taylor",
"Tony Gale",
"Matthias Clasen <mclasen@redhat.com>",
@@ -214,52 +240,17 @@ activate_quit (GSimpleAction *action,
}
}
static void
delete_messages (gpointer data)
{
g_list_free_full ((GList *)data, g_free);
}
static void
pop_message (GtkWidget *status)
{
GList *messages = (GList *) g_object_steal_data (G_OBJECT (status), "messages");
if (messages)
{
char *message = messages->data;
messages = g_list_remove (messages, message);
g_object_set_data_full (G_OBJECT (status), "messages",
messages, delete_messages);
gtk_label_set_label (GTK_LABEL (status), message);
}
}
static void
push_message (GtkWidget *status,
const char *message)
{
GList *messages = (GList *) g_object_steal_data (G_OBJECT (status), "messages");
gtk_label_set_label (GTK_LABEL (status), message);
messages = g_list_prepend (messages, g_strdup (message));
g_object_set_data_full (G_OBJECT (status), "messages",
messages, delete_messages);
}
static void
update_statusbar (GtkTextBuffer *buffer,
DemoApplicationWindow *window)
{
char *msg;
int row, col;
int count;
gchar *msg;
gint row, col;
gint count;
GtkTextIter iter;
/* clear any previous message, underflow is allowed */
pop_message (window->status);
gtk_statusbar_pop (GTK_STATUSBAR (window->status), 0);
count = gtk_text_buffer_get_char_count (buffer);
@@ -273,7 +264,7 @@ update_statusbar (GtkTextBuffer *buffer,
msg = g_strdup_printf ("Cursor at row %d column %d - %d chars in document",
row, col, count);
push_message (window->status, msg);
gtk_statusbar_push (GTK_STATUSBAR (window->status), 0, msg);
g_free (msg);
}
@@ -330,7 +321,7 @@ static GActionEntry win_entries[] = {
static void
clicked_cb (GtkWidget *widget, DemoApplicationWindow *window)
{
gtk_widget_set_visible (window->infobar, FALSE);
gtk_widget_hide (window->infobar);
}
static void
@@ -475,18 +466,18 @@ demo_application_window_size_allocate (GtkWidget *widget,
baseline);
if (!window->maximized && !window->fullscreen)
gtk_window_get_default_size (GTK_WINDOW (window), &window->width, &window->height);
gtk_window_get_size (GTK_WINDOW (window), &window->width, &window->height);
}
static void
surface_state_changed (GtkWidget *widget)
{
DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
GdkToplevelState new_state;
GdkSurfaceState new_state;
new_state = gdk_toplevel_get_state (GDK_TOPLEVEL (gtk_native_get_surface (GTK_NATIVE (widget))));
window->maximized = (new_state & GDK_TOPLEVEL_STATE_MAXIMIZED) != 0;
window->fullscreen = (new_state & GDK_TOPLEVEL_STATE_FULLSCREEN) != 0;
window->maximized = (new_state & GDK_SURFACE_STATE_MAXIMIZED) != 0;
window->fullscreen = (new_state & GDK_SURFACE_STATE_FULLSCREEN) != 0;
}
static void
@@ -514,8 +505,6 @@ demo_application_window_dispose (GObject *object)
demo_application_window_store_state (window);
gtk_widget_dispose_template (GTK_WIDGET (window), demo_application_window_get_type ());
G_OBJECT_CLASS (demo_application_window_parent_class)->dispose (object);
}

View File

@@ -31,8 +31,8 @@
</object>
</child>
<layout>
<property name="column">0</property>
<property name="row">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
@@ -54,8 +54,8 @@
</object>
</child>
<layout>
<property name="column">0</property>
<property name="row">1</property>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
@@ -70,22 +70,17 @@
</object>
</child>
<layout>
<property name="column">0</property>
<property name="row">2</property>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel" id="status">
<object class="GtkStatusbar" id="status">
<property name="hexpand">1</property>
<property name="xalign">0</property>
<property name="margin-start">2</property>
<property name="margin-end">2</property>
<property name="margin-top">2</property>
<property name="margin-bottom">2</property>
<layout>
<property name="column">0</property>
<property name="row">3</property>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>

View File

@@ -16,8 +16,8 @@ static GtkWidget *placeholder;
static void
on_name_appeared (GDBusConnection *connection,
const char *name,
const char *name_owner,
const gchar *name,
const gchar *name_owner,
gpointer user_data)
{
name_seen = TRUE;
@@ -25,7 +25,7 @@ on_name_appeared (GDBusConnection *connection,
static void
on_name_vanished (GDBusConnection *connection,
const char *name,
const gchar *name,
gpointer user_data)
{
if (!name_seen)
@@ -55,7 +55,7 @@ do_application_demo (GtkWidget *toplevel)
if (placeholder == NULL)
{
const char *command;
const gchar *command;
GError *error = NULL;
if (g_file_test ("./gtk4-demo-application" APP_EXTENSION, G_FILE_TEST_IS_EXECUTABLE))

View File

@@ -1,20 +1,18 @@
/* Assistant
*
* Demonstrates a sample multi-step assistant with GtkAssistant. Assistants
* are used to divide an operation into several simpler sequential steps,
* and to guide the user through these steps.
* Demonstrates a sample multi-step assistant. Assistants are used to divide
* an operation into several simpler sequential steps, and to guide the user
* through these steps.
*/
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static GtkWidget *progress_bar = NULL;
static gboolean
apply_changes_gradually (gpointer data)
{
double fraction;
gdouble fraction;
/* Work, work, work... */
fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (progress_bar));
@@ -49,8 +47,8 @@ on_assistant_close_cancel (GtkWidget *widget, gpointer data)
static void
on_assistant_prepare (GtkWidget *widget, GtkWidget *page, gpointer data)
{
int current_page, n_pages;
char *title;
gint current_page, n_pages;
gchar *title;
current_page = gtk_assistant_get_current_page (GTK_ASSISTANT (widget));
n_pages = gtk_assistant_get_n_pages (GTK_ASSISTANT (widget));
@@ -72,8 +70,8 @@ on_entry_changed (GtkWidget *widget, gpointer data)
{
GtkAssistant *assistant = GTK_ASSISTANT (data);
GtkWidget *current_page;
int page_number;
const char *text;
gint page_number;
const gchar *text;
page_number = gtk_assistant_get_current_page (assistant);
current_page = gtk_assistant_get_nth_page (assistant, page_number);
@@ -100,9 +98,6 @@ create_page1 (GtkWidget *assistant)
gtk_box_append (GTK_BOX (box), label);
entry = gtk_entry_new ();
gtk_accessible_update_relation (GTK_ACCESSIBLE (entry),
GTK_ACCESSIBLE_RELATION_LABELLED_BY, label, NULL,
-1);
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
gtk_widget_set_valign (entry, GTK_ALIGN_CENTER);
gtk_box_append (GTK_BOX (box), entry);
@@ -142,6 +137,7 @@ create_page3 (GtkWidget *assistant)
label = gtk_label_new ("This is a confirmation page, press 'Apply' to apply changes");
gtk_widget_show (label);
gtk_assistant_append_page (GTK_ASSISTANT (assistant), label);
gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), label, GTK_ASSISTANT_PAGE_CONFIRM);
gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), label, TRUE);
@@ -158,14 +154,11 @@ create_page4 (GtkWidget *assistant)
gtk_widget_set_margin_start (progress_bar, 40);
gtk_widget_set_margin_end (progress_bar, 40);
gtk_widget_show (progress_bar);
gtk_assistant_append_page (GTK_ASSISTANT (assistant), progress_bar);
gtk_assistant_set_page_type (GTK_ASSISTANT (assistant), progress_bar, GTK_ASSISTANT_PAGE_PROGRESS);
gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), progress_bar, "Applying changes");
gtk_accessible_update_property (GTK_ACCESSIBLE (progress_bar),
GTK_ACCESSIBLE_PROPERTY_LABEL, "Applying changes",
-1);
/* This prevents the assistant window from being
* closed while we're "busy" applying changes.
*/
@@ -203,7 +196,7 @@ do_assistant (GtkWidget *do_widget)
}
if (!gtk_widget_get_visible (assistant))
gtk_widget_set_visible (assistant, TRUE);
gtk_widget_show (assistant);
else
gtk_window_destroy (GTK_WINDOW (assistant));

247
demos/gtk-demo/award.c Normal file
View File

@@ -0,0 +1,247 @@
/*
* Copyright © 2018 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include "award.h"
struct _GtkAward
{
GObject parent;
char *explanation;
char *name;
char *title;
GDateTime *granted; /* or NULL if not granted */
};
enum {
PROP_0,
PROP_EXPLANATION,
PROP_NAME,
PROP_TITLE,
PROP_GRANTED,
N_PROPS,
};
static GParamSpec *properties[N_PROPS] = { NULL, };
G_DEFINE_TYPE (GtkAward, gtk_award, G_TYPE_OBJECT)
static void
gtk_award_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkAward *self = GTK_AWARD (object);
switch (prop_id)
{
case PROP_EXPLANATION:
self->explanation = g_value_dup_string (value);
break;
case PROP_NAME:
self->name = g_value_dup_string (value);
break;
case PROP_TITLE:
self->title = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_award_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkAward *self = GTK_AWARD (object);
switch (prop_id)
{
case PROP_EXPLANATION:
g_value_set_string (value, self->explanation);
break;
case PROP_NAME:
g_value_set_string (value, self->name);
break;
case PROP_TITLE:
g_value_set_string (value, self->title);
break;
case PROP_GRANTED:
g_value_set_boxed (value, self->granted);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_award_dispose (GObject *object)
{
GtkAward *self = GTK_AWARD (object);
g_clear_pointer (&self->name, g_free);
g_clear_pointer (&self->title, g_free);
g_clear_pointer (&self->granted, g_date_time_unref);
G_OBJECT_CLASS (gtk_award_parent_class)->dispose (object);
}
static void
gtk_award_class_init (GtkAwardClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
gobject_class->set_property = gtk_award_set_property;
gobject_class->get_property = gtk_award_get_property;
gobject_class->dispose = gtk_award_dispose;
properties[PROP_EXPLANATION] =
g_param_spec_string ("explanation",
"Explanation",
"How to get the title",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_NAME] =
g_param_spec_string ("name",
"Name",
"internal name of the award",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_TITLE] =
g_param_spec_string ("title",
"Title",
"user-visible title",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_GRANTED] =
g_param_spec_boxed ("granted",
"Granted",
"Timestamp the award was granted or NULL if not granted yet",
G_TYPE_DATE_TIME,
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
gtk_award_init (GtkAward *self)
{
}
GListModel *
gtk_award_get_list (void)
{
static GListModel *list = NULL;
if (list == NULL)
{
GtkBuilder *builder;
g_type_ensure (GTK_TYPE_AWARD);
builder = gtk_builder_new_from_resource ("/awards.ui");
list = G_LIST_MODEL (gtk_builder_get_object (builder, "list"));
g_object_ref (list);
g_object_unref (builder);
}
return g_object_ref (list);
}
const char *
gtk_award_get_name (GtkAward *award)
{
return award->name;
}
const char *
gtk_award_get_title (GtkAward *award)
{
return award->title;
}
GDateTime *
gtk_award_get_granted (GtkAward *award)
{
return award->granted;
}
GtkAward *
award_find (const char *name)
{
GListModel *list;
GtkAward *self;
guint i;
list = gtk_award_get_list ();
g_object_unref (list);
for (i = 0; i < g_list_model_get_n_items (list); i++)
{
self = g_list_model_get_item (list, i);
g_object_unref (self);
if (g_ascii_strcasecmp (name, self->name) == 0)
return self;
}
return NULL;
}
void
award (const char *name)
{
GtkAward *self;
GNotification *notification;
self = award_find (name);
if (self == NULL)
{
g_warning ("Did not find award \"%s\"", name);
return;
}
if (self->granted)
return;
self->granted = g_date_time_new_now_utc ();
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_GRANTED]);
notification = g_notification_new ("You won an award!");
g_notification_set_body (notification, self->title);
g_application_send_notification (g_application_get_default (), NULL, notification);
g_object_unref (notification);
}

18
demos/gtk-demo/award.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef __AWARD_H__
#define __AWARD_H__
#include <gtk/gtk.h>
#define GTK_TYPE_AWARD (gtk_award_get_type ())
G_DECLARE_FINAL_TYPE (GtkAward, gtk_award, GTK, AWARD, GObject)
GListModel * gtk_award_get_list (void);
const char * gtk_award_get_name (GtkAward *award);
const char * gtk_award_get_title (GtkAward *award);
GDateTime * gtk_award_get_granted (GtkAward *award);
void award (const char *name);
#endif /* __AWARD_H__ */

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface domain="gtk40">
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="label" bind-source="GtkListItem" bind-property="position"></property>
<property name="margin">6</property>
</object>
</property>
</template>
</interface>

89
demos/gtk-demo/awards.ui Normal file
View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GListStore" id="list">
<property name="item-type">GtkAward</property>
<child>
<object class="GtkAward">
<property name="name">demo-inspector</property>
<!-- Transformers -->
<property name="title" translatable="yes">You got a high-rise double-pump carburetor.</property>
<property name="explanation" translatable="yes">Launch the inspector</property>
</object>
</child>
<child>
<object class="GtkAward">
<property name="name">demo-start</property>
<!-- The Matrix -->
<property name="title" translatable="yes">After this, there is no turning back.</property>
<property name="explanation" translatable="yes">Start gtk-demo</property>
</object>
</child>
<child>
<object class="GtkAward">
<property name="name">listbox-reshare</property>
<!-- Mean Girls -->
<property name="title" translatable="yes">Trying to make fetch happen</property>
<property name="explanation" translatable="yes">Reshare a tweet</property>
</object>
</child>
<child>
<object class="GtkAward">
<property name="name">listbox-100th-row</property>
<!-- Aladdin -->
<property name="title" translatable="yes">The ever impressive, long contained, often imitated, but never duplicated Genie of the lamp.</property>
<property name="explanation" translatable="yes">Select a 100th row in a list</property>
</object>
</child>
<child>
<object class="GtkAward">
<property name="name">password-best</property>
<!-- Spaceballs -->
<property name="title" translatable="yes">I've got the same combination on my luggage!</property>
<property name="explanation" translatable="yes">Use "12345" as the password</property>
</object>
</child>
<child>
<object class="GtkAward">
<property name="name">password-correct</property>
<!-- Stanley Parable -->
<property name="title" translatable="yes">Night Shark 1-1-5</property>
<property name="explanation" translatable="yes">Correctly enter a password</property>
</object>
</child>
<child>
<object class="GtkAward">
<property name="name">puzzle-give-up</property>
<!-- Pretty Woman -->
<property name="title" translatable="yes">Big Mistake. Big. Huge!</property>
<property name="explanation" translatable="yes">Close the puzzle without finishing it</property>
</object>
</child>
<child>
<object class="GtkAward">
<property name="name">puzzle-solve</property>
<!-- The Incredibles -->
<property name="title" translatable="yes">That was totally wicked!</property>
<property name="explanation" translatable="yes">Solve a puzzle</property>
</object>
</child>
<child>
<object class="GtkAward">
<property name="name">puzzle-solve-animated</property>
<!-- The Phantom Menace -->
<property name="title" translatable="yes">A surprise to be sure but a welcome one.</property>
<property name="explanation" translatable="yes">Solve an animated puzzle</property>
</object>
</child>
<child>
<object class="GtkAward">
<property name="name">puzzle-solve-large</property>
<!-- Portal -->
<property name="title" translatable="yes">Science isn't about WHY. It's about WHY NOT?!</property>
<property name="explanation" translatable="yes">Solve a puzzle with at least 20 pieces</property>
</object>
</child>
</object>
</interface>

View File

@@ -0,0 +1,48 @@
/* Awards
*
* This demo demonstrates how to use lists to show the awards you have collected
* while exploring this demo.
*
*/
#include <gtk/gtk.h>
/* Include the header for accessing the awards */
#include "award.h"
static GtkWidget *window = NULL;
GtkWidget *
do_awardview (GtkWidget *do_widget)
{
if (!window)
{
GtkWidget *sw, *listview;
GListModel *list;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Awards");
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_window_set_child (GTK_WINDOW (window), sw);
listview = gtk_list_view_new_with_factory (
gtk_builder_list_item_factory_new_from_resource (NULL, "/awardview/awardlistitem.ui"));
list = gtk_award_get_list ();
gtk_list_view_set_model (GTK_LIST_VIEW (listview), list);
g_object_unref (list);
gtk_list_view_set_show_separators (GTK_LIST_VIEW (listview), TRUE);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,26 +0,0 @@
uniform float u_time;
void
mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
vec2 pos = (fragCoord.xy * 2.0 - resolution.xy)/ min (resolution.x, resolution.y) ;
float t0 = sin ((u_time + 0.00)*1.0);
float t1 = sin ((u_time + 0.30)*0.4);
float t2 = cos ((u_time + 0.23)*0.9);
float t3 = cos ((u_time + 0.41)*0.6);
float t4 = cos ((u_time + 0.11)*0.3);
vec2 p0 = vec2 (t1, t0) ;
vec2 p1 = vec2 (t2, t3) ;
vec2 p2 = vec2 (t4, t3) ;
float r = 1.0/distance (pos, p0);
float g = 1.0/distance (pos, p1);
float b = 1.0/distance (pos, p2);
float sum = r + g + b;
float alpha = 1.0 - pow (1.0/(sum), 40.0)*pow (10.0, 40.0*0.7);
fragColor = vec4 (r*0.5, g*0.5, b*0.5, 1.0) * alpha;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="window">
<property name="resizable">0</property>
<property name="title">CSS Blend Modes</property>
@@ -7,10 +8,6 @@
<property name="default-height">300</property>
<child>
<object class="GtkGrid">
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="row-spacing">12</property>
<property name="column-spacing">12</property>
<child>
@@ -21,8 +18,8 @@
<class name="dim-label"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
@@ -32,8 +29,8 @@
<property name="has-frame">1</property>
<property name="min-content-width">150</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
@@ -43,8 +40,8 @@
<property name="hexpand">1</property>
<property name="stack">stack</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
@@ -70,8 +67,8 @@
<object class="GtkLabel">
<property name="label" translatable="yes">Duck</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
@@ -79,8 +76,8 @@
<object class="GtkLabel">
<property name="label" translatable="yes">Background</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
@@ -90,8 +87,8 @@
<class name="duck"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">1</property>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
@@ -101,8 +98,8 @@
<class name="gradient"/>
</style>
<layout>
<property name="column">1</property>
<property name="row">1</property>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
@@ -111,8 +108,8 @@
<property name="label" translatable="yes">
Blended picture</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="column-span">2</property>
</layout>
</object>
@@ -124,8 +121,8 @@ Blended picture</property>
<class name="blend0"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">3</property>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
<property name="column-span">2</property>
</layout>
</object>
@@ -149,8 +146,8 @@ Blended picture</property>
<object class="GtkLabel">
<property name="label" translatable="yes">Red</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
@@ -158,8 +155,8 @@ Blended picture</property>
<object class="GtkLabel">
<property name="label" translatable="yes">Blue</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
@@ -169,8 +166,8 @@ Blended picture</property>
<class name="red"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">1</property>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
@@ -180,8 +177,8 @@ Blended picture</property>
<class name="blue"/>
</style>
<layout>
<property name="column">1</property>
<property name="row">1</property>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
@@ -190,8 +187,8 @@ Blended picture</property>
<property name="label" translatable="yes">
Blended picture</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="column-span">2</property>
</layout>
</object>
@@ -203,8 +200,8 @@ Blended picture</property>
<class name="blend1"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">3</property>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
<property name="column-span">2</property>
</layout>
</object>
@@ -231,8 +228,8 @@ Blended picture</property>
<class name="cyan"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">1</property>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
@@ -242,8 +239,8 @@ Blended picture</property>
<class name="magenta"/>
</style>
<layout>
<property name="column">1</property>
<property name="row">1</property>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>
@@ -253,8 +250,8 @@ Blended picture</property>
<class name="yellow"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">3</property>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>
@@ -265,8 +262,8 @@ Blended picture</property>
<class name="blend2"/>
</style>
<layout>
<property name="column">1</property>
<property name="row">3</property>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</layout>
</object>
</child>
@@ -278,8 +275,8 @@ Blended picture</property>
<class name="dim-label"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
@@ -291,8 +288,8 @@ Blended picture</property>
<class name="dim-label"/>
</style>
<layout>
<property name="column">1</property>
<property name="row">0</property>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</layout>
</object>
</child>
@@ -304,8 +301,8 @@ Blended picture</property>
<class name="dim-label"/>
</style>
<layout>
<property name="column">0</property>
<property name="row">2</property>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</layout>
</object>
</child>
@@ -317,8 +314,8 @@ Blended picture</property>
<attribute name="weight" value="bold"></attribute>
</attributes>
<layout>
<property name="column">1</property>
<property name="row">2</property>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
</layout>
</object>
</child>
@@ -327,8 +324,8 @@ Blended picture</property>
</object>
</child>
<layout>
<property name="column">1</property>
<property name="row">1</property>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</layout>
</object>
</child>

View File

@@ -116,8 +116,7 @@ effective_align (GtkAlign align,
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_START : GTK_ALIGN_END;
case GTK_ALIGN_FILL:
case GTK_ALIGN_CENTER:
case GTK_ALIGN_BASELINE_FILL:
case GTK_ALIGN_BASELINE_CENTER:
case GTK_ALIGN_BASELINE:
default:
return align;
}
@@ -133,10 +132,10 @@ blur_overlay_child_update_style_classes (BlurOverlay *overlay,
gboolean is_left, is_right, is_top, is_bottom;
gboolean has_left, has_right, has_top, has_bottom;
has_left = gtk_widget_has_css_class (child, "left");
has_right = gtk_widget_has_css_class (child, "right");
has_top = gtk_widget_has_css_class (child, "top");
has_bottom = gtk_widget_has_css_class (child, "bottom");
has_left = gtk_widget_has_css_class (child, GTK_STYLE_CLASS_LEFT);
has_right = gtk_widget_has_css_class (child, GTK_STYLE_CLASS_RIGHT);
has_top = gtk_widget_has_css_class (child, GTK_STYLE_CLASS_TOP);
has_bottom = gtk_widget_has_css_class (child, GTK_STYLE_CLASS_BOTTOM);
is_left = is_right = is_top = is_bottom = FALSE;
@@ -159,24 +158,24 @@ blur_overlay_child_update_style_classes (BlurOverlay *overlay,
is_bottom = (child_allocation->y + child_allocation->height == height);
if (has_left && !is_left)
gtk_widget_remove_css_class (child, "left");
gtk_widget_remove_css_class (child, GTK_STYLE_CLASS_LEFT);
else if (!has_left && is_left)
gtk_widget_add_css_class (child, "left");
gtk_widget_add_css_class (child, GTK_STYLE_CLASS_LEFT);
if (has_right && !is_right)
gtk_widget_remove_css_class (child, "right");
gtk_widget_remove_css_class (child, GTK_STYLE_CLASS_RIGHT);
else if (!has_right && is_right)
gtk_widget_add_css_class (child, "right");
gtk_widget_add_css_class (child, GTK_STYLE_CLASS_RIGHT);
if (has_top && !is_top)
gtk_widget_remove_css_class (child, "top");
gtk_widget_remove_css_class (child, GTK_STYLE_CLASS_TOP);
else if (!has_top && is_top)
gtk_widget_add_css_class (child, "top");
gtk_widget_add_css_class (child, GTK_STYLE_CLASS_TOP);
if (has_bottom && !is_bottom)
gtk_widget_remove_css_class (child, "bottom");
gtk_widget_remove_css_class (child, GTK_STYLE_CLASS_BOTTOM);
else if (!has_bottom && is_bottom)
gtk_widget_add_css_class (child, "bottom");
gtk_widget_add_css_class (child, GTK_STYLE_CLASS_BOTTOM);
}
static void
@@ -259,8 +258,7 @@ blur_overlay_get_child_position (BlurOverlay *overlay,
case GTK_ALIGN_END:
alloc->x += width - alloc->width;
break;
case GTK_ALIGN_BASELINE_FILL:
case GTK_ALIGN_BASELINE_CENTER:
case GTK_ALIGN_BASELINE:
default:
g_assert_not_reached ();
break;
@@ -283,8 +281,7 @@ blur_overlay_get_child_position (BlurOverlay *overlay,
case GTK_ALIGN_END:
alloc->y += height - alloc->height;
break;
case GTK_ALIGN_BASELINE_FILL:
case GTK_ALIGN_BASELINE_CENTER:
case GTK_ALIGN_BASELINE:
default:
g_assert_not_reached ();
break;
@@ -300,13 +297,12 @@ blur_overlay_snapshot (GtkWidget *widget,
GtkWidget *main_widget;
GskRenderNode *main_widget_node = NULL;
GtkWidget *child;
int width, height;
GtkAllocation main_alloc;
cairo_region_t *clip = NULL;
int i;
main_widget = BLUR_OVERLAY (widget)->main_widget;
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
gtk_widget_get_allocation (widget, &main_alloc);
for (child = gtk_widget_get_first_child (widget);
child != NULL;
@@ -319,7 +315,7 @@ blur_overlay_snapshot (GtkWidget *widget,
if (blur > 0)
{
cairo_rectangle_int_t rect;
GtkAllocation alloc;
graphene_rect_t bounds;
if (main_widget_node == NULL)
@@ -331,8 +327,8 @@ blur_overlay_snapshot (GtkWidget *widget,
main_widget_node = gtk_snapshot_free_to_node (child_snapshot);
}
if (!gtk_widget_compute_bounds (child, gtk_widget_get_parent (child), &bounds))
graphene_rect_init (&bounds, 0, 0, 0, 0);
gtk_widget_get_allocation (child, &alloc);
graphene_rect_init (&bounds, alloc.x, alloc.y, alloc.width, alloc.height);
gtk_snapshot_push_blur (snapshot, blur);
gtk_snapshot_push_clip (snapshot, &bounds);
gtk_snapshot_append_node (snapshot, main_widget_node);
@@ -341,17 +337,13 @@ blur_overlay_snapshot (GtkWidget *widget,
if (clip == NULL)
{
cairo_rectangle_int_t rect;
rect.x = rect.y = 0;
rect.width = width;
rect.height = height;
rect.width = main_alloc.width;
rect.height = main_alloc.height;
clip = cairo_region_create_rectangle (&rect);
}
rect.x = floor (bounds.origin.x);
rect.y = floor (bounds.origin.y);
rect.width = ceil (bounds.origin.x + bounds.size.width - rect.x);
rect.height = ceil (bounds.origin.y + bounds.size.height - rect.y);
cairo_region_subtract_rectangle (clip, &rect);
cairo_region_subtract_rectangle (clip, (cairo_rectangle_int_t *)&alloc);
}
}

View File

@@ -18,7 +18,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef __BLUR_OVERLAY_H__
#define __BLUR_OVERLAY_H__
#include <gtk/gtk.h>
@@ -50,12 +51,18 @@ struct _BlurOverlayClass
GtkAllocation *allocation);
};
GDK_AVAILABLE_IN_ALL
GType blur_overlay_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkWidget *blur_overlay_new (void);
GDK_AVAILABLE_IN_ALL
void blur_overlay_add_overlay (BlurOverlay *overlay,
GtkWidget *widget,
double blur);
GDK_AVAILABLE_IN_ALL
void blur_overlay_set_child (BlurOverlay *overlay,
GtkWidget *widget);
G_END_DECLS
#endif /* __BLUR_OVERLAY_H__ */

View File

@@ -1,8 +1,6 @@
/* Builder
* #Keywords: GMenu, GtkPopoverMenuBar, GtkBuilder, GtkShortcutController, toolbar
*
* Demonstrates a traditional interface, loaded from a XML description,
* and shows how to connect actions to the menu items and toolbar buttons.
* Demonstrates an interface loaded from a XML description.
*/
#include <gtk/gtk.h>
@@ -23,46 +21,15 @@ about_activate (GSimpleAction *action,
gpointer user_data)
{
GtkWidget *window = user_data;
GtkBuilder *builder;
GtkWidget *about_dlg;
about_dlg = GTK_WIDGET (g_object_get_data (G_OBJECT (window), "about"));
gtk_window_present (GTK_WINDOW (about_dlg));
}
static void
remove_timeout (gpointer data)
{
guint id = GPOINTER_TO_UINT (data);
g_source_remove (id);
}
static int
pop_message (gpointer data)
{
GtkWidget *status = data;
gtk_label_set_label (GTK_LABEL (status), "");
g_object_set_data (G_OBJECT (status), "timeout", GUINT_TO_POINTER (0));
return G_SOURCE_REMOVE;
}
static void
status_message (GtkWidget *status,
const char *text)
{
guint id;
id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (status), "timeout"));
if (id)
g_source_remove (id);
gtk_label_set_text (GTK_LABEL (status), text);
id = g_timeout_add (5000, pop_message, status);
g_object_set_data_full (G_OBJECT (status), "timeout", GUINT_TO_POINTER (id), remove_timeout);
builder = g_object_get_data (G_OBJECT (window), "builder");
about_dlg = GTK_WIDGET (gtk_builder_get_object (builder, "aboutdialog1"));
gtk_window_set_transient_for (GTK_WINDOW (about_dlg), GTK_WINDOW (window));
gtk_window_set_hide_on_close (GTK_WINDOW (about_dlg), TRUE);
g_signal_connect (about_dlg, "response", G_CALLBACK (gtk_widget_hide), NULL);
gtk_widget_show (about_dlg);
}
static void
@@ -70,10 +37,7 @@ help_activate (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkWidget *status;
status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status"));
status_message (status, "Help not available");
g_print ("Help not available\n");
}
static void
@@ -81,13 +45,7 @@ not_implemented (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkWidget *status;
char *text;
text = g_strdup_printf ("Action “%s” not implemented", g_action_get_name (G_ACTION (action)));
status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status"));
status_message (status, text);
g_free (text);
g_print ("Action “%s” not implemented\n", g_action_get_name (G_ACTION (action)));
}
static GActionEntry win_entries[] = {
@@ -112,9 +70,6 @@ do_builder (GtkWidget *do_widget)
if (!window)
{
GtkBuilder *builder;
GtkWidget *about;
GtkWidget *status;
GtkEventController *controller;
builder = gtk_builder_new_from_resource ("/builder/demo.ui");
@@ -128,55 +83,11 @@ do_builder (GtkWidget *do_widget)
window);
gtk_widget_insert_action_group (window, "win", actions);
controller = gtk_shortcut_controller_new ();
gtk_shortcut_controller_set_scope (GTK_SHORTCUT_CONTROLLER (controller),
GTK_SHORTCUT_SCOPE_GLOBAL);
gtk_widget_add_controller (window, controller);
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_n, GDK_CONTROL_MASK),
gtk_named_action_new ("win.new")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_o, GDK_CONTROL_MASK),
gtk_named_action_new ("win.open")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_s, GDK_CONTROL_MASK),
gtk_named_action_new ("win.save")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_s, GDK_CONTROL_MASK|GDK_SHIFT_MASK),
gtk_named_action_new ("win.save-as")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_q, GDK_CONTROL_MASK),
gtk_named_action_new ("win.quit")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_c, GDK_CONTROL_MASK),
gtk_named_action_new ("win.copy")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_x, GDK_CONTROL_MASK),
gtk_named_action_new ("win.cut")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_v, GDK_CONTROL_MASK),
gtk_named_action_new ("win.paste")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_F1, 0),
gtk_named_action_new ("win.help")));
gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
gtk_shortcut_new (gtk_keyval_trigger_new (GDK_KEY_F7, 0),
gtk_named_action_new ("win.about")));
about = GTK_WIDGET (gtk_builder_get_object (builder, "aboutdialog1"));
gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (window));
gtk_window_set_hide_on_close (GTK_WINDOW (about), TRUE);
g_object_set_data_full (G_OBJECT (window), "about",
about, (GDestroyNotify)gtk_window_destroy);
status = GTK_WIDGET (gtk_builder_get_object (builder, "statusbar1"));
g_object_set_data (G_OBJECT (window), "status", status);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,11 +1,12 @@
/* Clipboard
* #Keywords: drag-and-drop, dnd
*
* GdkClipboard is used for clipboard handling. This demo shows how to
* copy and paste text, images, colors or files to and from the clipboard.
* copy and paste text to and from the clipboard.
*
* You can also use Drag-And-Drop to copy the data from the source to the
* target.
* It also shows how to transfer images via the clipboard or via
* drag-and-drop, and how to make clipboard contents persist after
* the application exits. Clipboard persistence requires a clipboard
* manager to run.
*/
#include <glib/gi18n.h>
@@ -13,103 +14,22 @@
#include <string.h>
#include "demoimage.h"
static GtkWidget *window = NULL;
static void
copy_button_clicked (GtkStack *source_stack,
gpointer user_data)
copy_button_clicked (GtkWidget *button,
gpointer user_data)
{
GtkWidget *entry;
GdkClipboard *clipboard;
const char *visible_child_name;
GtkWidget *visible_child;
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (source_stack));
entry = GTK_WIDGET (user_data);
visible_child = gtk_stack_get_visible_child (source_stack);
visible_child_name = gtk_stack_get_visible_child_name (source_stack);
/* Get the clipboard object */
clipboard = gtk_widget_get_clipboard (entry);
if (strcmp (visible_child_name, "Text") == 0)
{
gdk_clipboard_set_text (clipboard, gtk_editable_get_text (GTK_EDITABLE (visible_child)));
}
else if (strcmp (visible_child_name, "Image") == 0)
{
GtkWidget *child;
for (child = gtk_widget_get_first_child (visible_child); child; child = gtk_widget_get_next_sibling (child))
{
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (child)))
{
GtkWidget *image = gtk_widget_get_first_child (child);
GdkPaintable *paintable = gtk_image_get_paintable (GTK_IMAGE (image));
if (GDK_IS_TEXTURE (paintable))
gdk_clipboard_set (clipboard, GDK_TYPE_TEXTURE, paintable);
else
gdk_clipboard_set (clipboard, GDK_TYPE_PAINTABLE, paintable);
break;
}
}
}
else if (strcmp (visible_child_name, "Color") == 0)
{
const GdkRGBA *color;
color = gtk_color_dialog_button_get_rgba (GTK_COLOR_DIALOG_BUTTON (visible_child));
gdk_clipboard_set (clipboard, GDK_TYPE_RGBA, color);
}
else if (strcmp (visible_child_name, "File") == 0)
{
gdk_clipboard_set (clipboard, G_TYPE_FILE, g_object_get_data (G_OBJECT (visible_child), "file"), NULL);
}
else
{
g_print ("TODO");
}
}
static void
present_value (GtkStack *dest_stack,
const GValue *value)
{
GtkWidget *child;
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
{
GFile *file;
gtk_stack_set_visible_child_name (dest_stack, "File");
child = gtk_stack_get_visible_child (dest_stack);
file = g_value_get_object (value);
g_object_set (child, "label", g_file_peek_path (file), NULL);
}
else if (G_VALUE_HOLDS (value, GDK_TYPE_RGBA))
{
GdkRGBA *color;
gtk_stack_set_visible_child_name (dest_stack, "Color");
child = gtk_widget_get_first_child (gtk_stack_get_visible_child (dest_stack));
color = g_value_get_boxed (value);
g_object_set (child, "rgba", color, NULL);
}
else if (G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE) ||
G_VALUE_HOLDS (value, GDK_TYPE_PAINTABLE))
{
GdkPaintable *paintable;
gtk_stack_set_visible_child_name (dest_stack, "Image");
child = gtk_stack_get_visible_child (dest_stack);
paintable = g_value_get_object (value);
g_object_set (child, "paintable", paintable, NULL);
}
else if (G_VALUE_HOLDS (value, G_TYPE_STRING))
{
gtk_stack_set_visible_child_name (dest_stack, "Text");
child = gtk_stack_get_visible_child (dest_stack);
gtk_label_set_label (GTK_LABEL (child), g_value_get_string (value));
}
/* Set clipboard text */
gdk_clipboard_set_text (clipboard, gtk_editable_get_text (GTK_EDITABLE (entry)));
}
static void
@@ -117,295 +37,153 @@ paste_received (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
GtkStack *dest_stack = user_data;
GdkClipboard *clipboard;
const GValue *value;
GtkWidget *entry;
char *text;
GError *error = NULL;
clipboard = GDK_CLIPBOARD (source_object);
entry = GTK_WIDGET (user_data);
value = gdk_clipboard_read_value_finish (clipboard, result, &error);
if (value)
/* Get the resulting text of the read operation */
text = gdk_clipboard_read_text_finish (clipboard, result, &error);
if (text)
{
present_value (dest_stack, value);
/* Set the entry text */
gtk_editable_set_text (GTK_EDITABLE (entry), text);
g_free (text);
}
else
{
g_print ("%s\n", error->message);
GtkWidget *dialog;
/* Show an error about why pasting failed.
* Usually you probably want to ignore such failures,
* but for demonstration purposes, we show the error.
*/
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Could not paste text: %s",
error->message);
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_window_destroy), NULL);
gtk_widget_show (dialog);
g_error_free (error);
}
}
static void
paste_button_clicked (GtkStack *dest_stack,
gpointer user_data)
paste_button_clicked (GtkWidget *button,
gpointer user_data)
{
GtkWidget *entry;
GdkClipboard *clipboard;
GdkContentFormats *formats;
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (dest_stack));
formats = gdk_clipboard_get_formats (clipboard);
entry = GTK_WIDGET (user_data);
if (gdk_content_formats_contain_gtype (formats, GDK_TYPE_TEXTURE))
gdk_clipboard_read_value_async (clipboard, GDK_TYPE_TEXTURE, 0, NULL, paste_received, dest_stack);
else if (gdk_content_formats_contain_gtype (formats, GDK_TYPE_PAINTABLE))
gdk_clipboard_read_value_async (clipboard, GDK_TYPE_PAINTABLE, 0, NULL, paste_received, dest_stack);
else if (gdk_content_formats_contain_gtype (formats, GDK_TYPE_RGBA))
gdk_clipboard_read_value_async (clipboard, GDK_TYPE_RGBA, 0, NULL, paste_received, dest_stack);
else if (gdk_content_formats_contain_gtype (formats, G_TYPE_FILE))
gdk_clipboard_read_value_async (clipboard, G_TYPE_FILE, 0, NULL, paste_received, dest_stack);
else if (gdk_content_formats_contain_gtype (formats, G_TYPE_STRING))
gdk_clipboard_read_value_async (clipboard, G_TYPE_STRING, 0, NULL, paste_received, dest_stack);
}
/* Get the clipboard object */
clipboard = gtk_widget_get_clipboard (entry);
static void
update_copy_button_sensitivity (GtkWidget *source_stack)
{
GtkButton *copy_button;
const char *visible_child_name;
GtkWidget *visible_child;
gboolean sensitive;
copy_button = GTK_BUTTON (g_object_get_data (G_OBJECT (source_stack), "copy-button"));
visible_child = gtk_stack_get_visible_child (GTK_STACK (source_stack));
visible_child_name = gtk_stack_get_visible_child_name (GTK_STACK (source_stack));
if (strcmp (visible_child_name, "Text") == 0)
{
sensitive = strlen (gtk_editable_get_text (GTK_EDITABLE (visible_child))) > 0;
}
else if (strcmp (visible_child_name, "Color") == 0 ||
strcmp (visible_child_name, "Image") == 0)
{
sensitive = TRUE;
}
else if (strcmp (visible_child_name, "File") == 0)
{
sensitive = g_object_get_data (G_OBJECT (visible_child), "file") != NULL;
}
else
{
sensitive = FALSE;
}
gtk_widget_set_sensitive (GTK_WIDGET (copy_button), sensitive);
}
static void
source_changed_cb (GtkButton *copy_button,
GParamSpec *pspec,
GtkWidget *source_stack)
{
update_copy_button_sensitivity (source_stack);
}
static void
text_changed_cb (GtkButton *copy_button,
GParamSpec *pspec,
GtkWidget *entry)
{
update_copy_button_sensitivity (gtk_widget_get_ancestor (entry, GTK_TYPE_STACK));
}
static void
file_button_set_file (GtkButton *button,
GFile *file)
{
gtk_label_set_label (GTK_LABEL (gtk_button_get_child (button)), g_file_peek_path (file));
g_object_set_data_full (G_OBJECT (button), "file", g_object_ref (file), g_object_unref);
}
static void
file_chooser_response (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
GtkButton *button = GTK_BUTTON (user_data);
GFile *file;
file = gtk_file_dialog_open_finish (dialog, result, NULL);
if (file)
{
file_button_set_file (button, file);
g_object_unref (file);
update_copy_button_sensitivity (gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_STACK));
}
}
static void
open_file_cb (GtkWidget *button)
{
GtkFileDialog *dialog;
dialog = gtk_file_dialog_new ();
gtk_file_dialog_open (dialog,
GTK_WINDOW (gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW)),
NULL,
file_chooser_response, button);
g_object_unref (dialog);
}
static void
folder_chooser_response (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
GtkButton *button = GTK_BUTTON (user_data);
GFile *file;
file = gtk_file_dialog_select_folder_finish (dialog, result, NULL);
if (file)
{
file_button_set_file (button, file);
g_object_unref (file);
update_copy_button_sensitivity (gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_STACK));
}
}
static void
open_folder_cb (GtkWidget *button)
{
GtkFileDialog *dialog;
dialog = gtk_file_dialog_new ();
gtk_file_dialog_select_folder (dialog,
GTK_WINDOW (gtk_widget_get_ancestor (button, GTK_TYPE_WINDOW)),
NULL,
folder_chooser_response, button);
g_object_unref (dialog);
}
static void
update_paste_button_sensitivity (GdkClipboard *clipboard,
GtkWidget *paste_button)
{
GdkContentFormats *formats;
gboolean sensitive = FALSE;
formats = gdk_clipboard_get_formats (clipboard);
if (gdk_content_formats_contain_gtype (formats, G_TYPE_FILE) ||
gdk_content_formats_contain_gtype (formats, GDK_TYPE_RGBA) ||
gdk_content_formats_contain_gtype (formats, GDK_TYPE_TEXTURE) ||
gdk_content_formats_contain_gtype (formats, GDK_TYPE_PAINTABLE) ||
gdk_content_formats_contain_gtype (formats, G_TYPE_STRING))
sensitive = TRUE;
gtk_widget_set_sensitive (paste_button, sensitive);
}
static void
unset_clipboard_handler (gpointer data)
{
GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
g_signal_handlers_disconnect_by_func (clipboard, update_paste_button_sensitivity, data);
}
static gboolean
on_drop (GtkStack *dest_stack,
const GValue *value,
double x,
double y,
gpointer data)
{
present_value (dest_stack, value);
return TRUE;
}
static GdkContentProvider *
drag_prepare (GtkDragSource *drag_source,
double x,
double y,
gpointer data)
{
GtkWidget *button;
GValue value = G_VALUE_INIT;
button = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (drag_source));
if (GTK_IS_TOGGLE_BUTTON (button))
{
GtkWidget *image = gtk_widget_get_first_child (button);
GdkPaintable *paintable = gtk_image_get_paintable (GTK_IMAGE (image));
if (GDK_IS_TEXTURE (paintable))
{
g_value_init (&value, GDK_TYPE_TEXTURE);
g_value_set_object (&value, paintable);
}
else
{
g_value_init (&value, GDK_TYPE_PAINTABLE);
g_value_set_object (&value, paintable);
}
}
else
{
GFile *file = g_object_get_data (G_OBJECT (button), "file");
if (file)
{
g_value_init (&value, G_TYPE_FILE);
g_value_set_object (&value, file);
}
else
return NULL;
}
return gdk_content_provider_new_for_value (&value);
/* Request the contents of the clipboard, contents_received will be
called when we do get the contents.
*/
gdk_clipboard_read_text_async (clipboard, NULL, paste_received, entry);
}
GtkWidget *
do_clipboard (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkBuilderScope *scope;
GtkBuilder *builder;
GtkWidget *button;
GtkWidget *vbox, *hbox;
GtkWidget *label;
GtkWidget *entry, *button;
GtkWidget *image;
scope = gtk_builder_cscope_new ();
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, open_folder_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);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Clipboard");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
button = GTK_WIDGET (gtk_builder_get_object (builder, "copy_button"));
g_object_set_data (gtk_builder_get_object (builder, "source_stack"), "copy-button", button);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_margin_start (vbox, 8);
gtk_widget_set_margin_end (vbox, 8);
gtk_widget_set_margin_top (vbox, 8);
gtk_widget_set_margin_bottom (vbox, 8);
button = GTK_WIDGET (gtk_builder_get_object (builder, "paste_button"));
g_signal_connect (gtk_widget_get_clipboard (button), "changed",
G_CALLBACK (update_paste_button_sensitivity), button);
g_object_set_data_full (G_OBJECT (button), "clipboard-handler", button, unset_clipboard_handler);
gtk_window_set_child (GTK_WINDOW (window), vbox);
g_object_unref (builder);
g_object_unref (scope);
label = gtk_label_new ("\"Copy\" will copy the text\nin the entry to the clipboard");
gtk_box_append (GTK_BOX (vbox), label);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_widget_set_margin_start (hbox, 8);
gtk_widget_set_margin_end (hbox, 8);
gtk_widget_set_margin_top (hbox, 8);
gtk_widget_set_margin_bottom (hbox, 8);
gtk_box_append (GTK_BOX (vbox), hbox);
/* Create the first entry */
entry = gtk_entry_new ();
gtk_box_append (GTK_BOX (hbox), entry);
/* Create the button */
button = gtk_button_new_with_mnemonic (_("_Copy"));
gtk_box_append (GTK_BOX (hbox), button);
g_signal_connect (button, "clicked",
G_CALLBACK (copy_button_clicked), entry);
label = gtk_label_new ("\"Paste\" will paste the text from the clipboard to the entry");
gtk_box_append (GTK_BOX (vbox), label);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_widget_set_margin_start (hbox, 8);
gtk_widget_set_margin_end (hbox, 8);
gtk_widget_set_margin_top (hbox, 8);
gtk_widget_set_margin_bottom (hbox, 8);
gtk_box_append (GTK_BOX (vbox), hbox);
/* Create the second entry */
entry = gtk_entry_new ();
gtk_box_append (GTK_BOX (hbox), entry);
/* Create the button */
button = gtk_button_new_with_mnemonic (_("_Paste"));
gtk_box_append (GTK_BOX (hbox), button);
g_signal_connect (button, "clicked",
G_CALLBACK (paste_button_clicked), entry);
label = gtk_label_new ("Images can be transferred via the clipboard, too");
gtk_box_append (GTK_BOX (vbox), label);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_widget_set_margin_start (hbox, 8);
gtk_widget_set_margin_end (hbox, 8);
gtk_widget_set_margin_top (hbox, 8);
gtk_widget_set_margin_bottom (hbox, 8);
gtk_box_append (GTK_BOX (vbox), hbox);
/* Create the first image */
image = demo_image_new ("dialog-warning");
gtk_box_append (GTK_BOX (hbox), image);
/* Create the second image */
image = demo_image_new ("process-stop");
gtk_box_append (GTK_BOX (hbox), image);
/* Create the third image */
image = demo_image_new ("weather-clear");
gtk_box_append (GTK_BOX (hbox), image);
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));

View File

@@ -1,362 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="resizable">1</property>
<property name="title">Clipboard</property>
<accessibility>
<relation name="described-by">label</relation>
</accessibility>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel" id="label">
<property name="label">“Copy” will copy the selected data the clipboard, “Paste” will show the current clipboard contents. You can also drag the data to the bottom.</property>
<property name="wrap">1</property>
<property name="max-width-chars">40</property>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">12</property>
<child>
<object class="GtkDropDown" id="source_chooser">
<accessibility>
<property name="label">Source Type</property>
</accessibility>
<property name="valign">center</property>
<property name="model">
<object class="GtkStringList">
<items>
<item>Text</item>
<item>Color</item>
<item>Image</item>
<item>File</item>
<item>Folder</item>
</items>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStack" id="source_stack">
<signal name="notify::visible-child" handler="source_changed_cb" object="copy_button"/>
<property name="vexpand">1</property>
<binding name="visible-child-name">
<lookup name="string" type="GtkStringObject">
<lookup name="selected-item">
source_chooser
</lookup>
</lookup>
</binding>
<child>
<object class="GtkStackPage">
<property name="name">Text</property>
<property name="child">
<object class="GtkEntry" id="source_text">
<accessibility>
<property name="label">Text Drag Source</property>
</accessibility>
<property name="valign">center</property>
<signal name="notify::text" handler="text_changed_cb" object="copy_button"/>
<property name="text">Copy this!</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">Color</property>
<property name="child">
<object class="GtkColorDialogButton" id="source_color">
<accessibility>
<property name="label">Color Drag Source</property>
</accessibility>
<property name="dialog">
<object class="GtkColorDialog">
</object>
</property>
<property name="valign">center</property>
<property name="rgba">purple</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">Image</property>
<property name="child">
<object class="GtkBox">
<property name="valign">center</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkToggleButton" id="image_rose">
<accessibility>
<property name="label">Photo Drag Source</property>
</accessibility>
<property name="active">1</property>
<child>
</child>
<child>
<object class="GtkImage">
<accessibility>
<property name="label">Portland Rose Photo</property>
</accessibility>
<style>
<class name="large-icons"/>
</style>
<property name="paintable">resource:///transparent/portland-rose.jpg</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToggleButton" id="image_floppy">
<accessibility>
<property name="label">Icon Drag Source</property>
</accessibility>
<property name="group">image_rose</property>
<child>
<object class="GtkDragSource">
<signal name="prepare" handler="drag_prepare"/>
</object>
</child>
<child>
<object class="GtkImage">
<accessibility>
<property name="label">Floppy Buddy Icon</property>
</accessibility>
<style>
<class name="large-icons"/>
</style>
<property name="paintable">resource:///images/floppybuddy.gif</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToggleButton" id="image_logo">
<accessibility>
<property name="label">SVG Drag Source</property>
</accessibility>
<property name="group">image_floppy</property>
<child>
<object class="GtkDragSource">
<signal name="prepare" handler="drag_prepare"/>
</object>
</child>
<child>
<object class="GtkImage">
<accessibility>
<property name="label">gtk-demo logo</property>
</accessibility>
<style>
<class name="large-icons"/>
</style>
<property name="paintable">resource:///images/org.gtk.Demo4.svg</property>
</object>
</child>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">File</property>
<property name="child">
<object class="GtkButton" id="source_file">
<accessibility>
<property name="label">File Drag Source</property>
</accessibility>
<child>
<object class="GtkDragSource">
<property name="propagation-phase">capture</property>
<signal name="prepare" handler="drag_prepare"/>
</object>
</child>
<property name="valign">center</property>
<property name="child">
<object class="GtkLabel">
<property name="label">—</property>
<property name="xalign">0</property>
<property name="ellipsize">start</property>
</object>
</property>
<signal name="clicked" handler="open_file_cb"/>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">Folder</property>
<property name="child">
<object class="GtkButton" id="source_folder">
<accessibility>
<property name="label">Folder Drag Source</property>
</accessibility>
<child>
<object class="GtkDragSource">
<property name="propagation-phase">capture</property>
<signal name="prepare" handler="drag_prepare"/>
</object>
</child>
<property name="valign">center</property>
<property name="child">
<object class="GtkLabel">
<property name="label">—</property>
<property name="xalign">0</property>
<property name="ellipsize">start</property>
</object>
</property>
<signal name="clicked" handler="open_folder_cb"/>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="copy_button">
<property name="valign">center</property>
<property name="label" translatable="yes">_Copy</property>
<signal name="clicked" handler="copy_button_clicked" object="source_stack"/>
<property name="use-underline">1</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparator">
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">12</property>
<child>
<object class="GtkDropTarget">
<property name="actions">copy</property>
<property name="formats">GdkTexture GdkPaintable GFile GdkRGBA gchararray</property>
<signal name="drop" handler="on_drop" object="dest_stack"/>
</object>
</child>
<child>
<object class="GtkButton" id="paste_button">
<property name="label" translatable="yes">_Paste</property>
<signal name="clicked" handler="paste_button_clicked" object="dest_stack"/>
<property name="use-underline">1</property>
</object>
</child>
<child>
<object class="GtkLabel" id="paste_label">
<property name="xalign">0</property>
<binding name="label">
<lookup name="visible-child-name" type="GtkStack">
dest_stack
</lookup>
</binding>
</object>
</child>
<child>
<object class="GtkStack" id="dest_stack">
<property name="halign">end</property>
<property name="valign">center</property>
<child>
<object class="GtkStackPage">
<property name="name"></property>
<property name="child">
<object class="GtkLabel">
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">Text</property>
<property name="child">
<object class="GtkLabel">
<accessibility>
<relation name="labelled-by">paste_label</relation>
</accessibility>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="xalign">0</property>
<property name="ellipsize">end</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">Image</property>
<property name="child">
<object class="GtkImage">
<accessibility>
<relation name="labelled-by">paste_label</relation>
</accessibility>
<property name="halign">end</property>
<property name="valign">center</property>
<style>
<class name="large-icons"/>
</style>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">Color</property>
<property name="child">
<object class="GtkBox">
<property name="halign">end</property>
<property name="valign">center</property>
<child>
<object class="GtkColorSwatch">
<accessibility>
<relation name="labelled-by">paste_label</relation>
</accessibility>
<property name="accessible-role">img</property>
<property name="can-focus">0</property>
<property name="selectable">0</property>
<property name="has-menu">0</property>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">File</property>
<property name="child">
<object class="GtkLabel">
<accessibility>
<relation name="labelled-by">paste_label</relation>
</accessibility>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="xalign">0</property>
<property name="hexpand">1</property>
<property name="ellipsize">start</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -1,224 +0,0 @@
// Originally from: https://www.shadertoy.com/view/3ljyDD
// License CC0: Hexagonal tiling + cog wheels
// Nothing fancy, just hexagonal tiling + cog wheels
#define PI 3.141592654
#define TAU (2.0*PI)
#define MROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
float hash(in vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,58.233))) * 13758.5453);
}
float pcos(float a) {
return 0.5 + 0.5*cos(a);
}
void rot(inout vec2 p, float a) {
float c = cos(a);
float s = sin(a);
p = vec2(c*p.x + s*p.y, -s*p.x + c*p.y);
}
float modPolar(inout vec2 p, float repetitions) {
float angle = 2.0*PI/repetitions;
float a = atan(p.y, p.x) + angle/2.;
float r = length(p);
float c = floor(a/angle);
a = mod(a,angle) - angle/2.;
p = vec2(cos(a), sin(a))*r;
// For an odd number of repetitions, fix cell index of the cell in -x direction
// (cell index would be e.g. -5 and 5 in the two halves of the cell):
if (abs(c) >= (repetitions/2.0)) c = abs(c);
return c;
}
float pmin(float a, float b, float k) {
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
return mix( b, a, h ) - k*h*(1.0-h);
}
const vec2 sz = vec2(1.0, sqrt(3.0));
const vec2 hsz = 0.5*sz;
const float smallCount = 16.0;
vec2 hextile(inout vec2 p) {
// See Art of Code: Hexagonal Tiling Explained!
// https://www.youtube.com/watch?v=VmrIDyYiJBA
vec2 p1 = mod(p, sz)-hsz;
vec2 p2 = mod(p - hsz*1.0, sz)-hsz;
vec2 p3 = mix(p2, p1, vec2(length(p1) < length(p2)));
vec2 n = p3 - p;
p = p3;
return n;
}
float circle(vec2 p, float r) {
return length(p) - r;
}
float box(vec2 p, vec2 b) {
vec2 d = abs(p)-b;
return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
}
float unevenCapsule(vec2 p, float r1, float r2, float h) {
p.x = abs(p.x);
float b = (r1-r2)/h;
float a = sqrt(1.0-b*b);
float k = dot(p,vec2(-b,a));
if( k < 0.0 ) return length(p) - r1;
if( k > a*h ) return length(p-vec2(0.0,h)) - r2;
return dot(p, vec2(a,b) ) - r1;
}
float cogwheel(vec2 p, float innerRadius, float outerRadius, float cogs, float holes) {
float cogWidth = 0.25*innerRadius*TAU/cogs;
float d0 = circle(p, innerRadius);
vec2 icp = p;
modPolar(icp, holes);
icp -= vec2(innerRadius*0.55, 0.0);
float d1 = circle(icp, innerRadius*0.25);
vec2 cp = p;
modPolar(cp, cogs);
cp -= vec2(innerRadius, 0.0);
float d2 = unevenCapsule(cp.yx, cogWidth, cogWidth*0.75, (outerRadius-innerRadius));
float d3 = circle(p, innerRadius*0.20);
float d = 1E6;
d = min(d, d0);
d = pmin(d, d2, 0.5*cogWidth);
d = min(d, d2);
d = max(d, -d1);
d = max(d, -d3);
return d;
}
float ccell1(vec2 p, float r) {
float d = 1E6;
const float bigCount = 60.0;
vec2 cp0 = p;
rot(cp0, -iTime*TAU/bigCount);
float d0 = cogwheel(cp0, 0.36, 0.38, bigCount, 5.0);
vec2 cp1 = p;
float nm = modPolar(cp1, 6.0);
cp1 -= vec2(0.5, 0.0);
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
d = min(d, d0);
d = min(d, d1);
return d;
}
float ccell2(vec2 p, float r) {
float d = 1E6;
vec2 cp0 = p;
float nm = modPolar(cp0, 6.0);
vec2 cp1 = cp0;
const float off = 0.275;
const float count = smallCount + 2.0;
cp0 -= vec2(off, 0.0);
rot(cp0, 0.+TAU*nm/2.0 - iTime*TAU/count);
float d0 = cogwheel(cp0, 0.09, 0.105, count, 5.0);
cp1 -= vec2(0.5, 0.0);
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
float l = length(p);
float d2 = l - (off+0.055);
float d3 = d2 + 0.020;;
vec2 tp0 = p;
modPolar(tp0, 60.0);
tp0.x -= off;
float d4 = box(tp0, vec2(0.0125, 0.005));
float ctime = -(iTime*0.05 + r)*TAU;
vec2 tp1 = p;
rot(tp1, ctime*12.0);
tp1.x -= 0.13;
float d5 = box(tp1, vec2(0.125, 0.005));
vec2 tp2 = p;
rot(tp2, ctime);
tp2.x -= 0.13*0.5;
float d6 = box(tp2, vec2(0.125*0.5, 0.0075));
float d7 = l - 0.025;
float d8 = l - 0.0125;
d = min(d, d0);
d = min(d, d1);
d = min(d, d2);
d = max(d, -d3);
d = min(d, d4);
d = min(d, d5);
d = min(d, d6);
d = min(d, d7);
d = max(d, -d8);
return d;
}
float df(vec2 p, float scale, inout vec2 nn) {
p /= scale;
nn = hextile(p);
nn = floor(nn + 0.5);
float r = hash(nn);
float d;;
if (r < 0.5) {
d = ccell1(p, r);
} else {
d = ccell2(p, r);
}
return d*scale;
}
vec3 postProcess(vec3 col, vec2 q) {
//col = saturate(col);
col=pow(clamp(col,0.0,1.0),vec3(0.75));
col=col*0.6+0.4*col*col*(3.0-2.0*col); // contrast
col=mix(col, vec3(dot(col, vec3(0.33))), -0.4); // satuation
col*=0.5+0.5*pow(19.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7); // vigneting
return col;
}
void mainImage(out vec4 fragColor, vec2 fragCoord) {
vec2 q = fragCoord/iResolution.xy;
vec2 p = -1.0 + 2.0*q;
p.x *= iResolution.x/iResolution.y;
float tm = iTime*0.1;
p += vec2(cos(tm), sin(tm*sqrt(0.5)));
float z = mix(0.5, 1.0, pcos(tm*sqrt(0.3)));
float aa = 4.0 / iResolution.y;
vec2 nn = vec2(0.0);
float d = df(p, z, nn);
vec3 col = vec3(160.0)/vec3(255.0);
vec3 baseCol = vec3(0.3);
vec4 logoCol = vec4(baseCol, 1.0)*smoothstep(-aa, 0.0, -d);
col = mix(col, logoCol.xyz, pow(logoCol.w, 8.0));
col += 0.4*pow(abs(sin(20.0*d)), 0.6);
col = postProcess(col, q);
fragColor = vec4(col, 1.0);
}

View File

@@ -1,226 +0,0 @@
uniform float iTime;
// Originally from: https://www.shadertoy.com/view/3ljyDD
// License CC0: Hexagonal tiling + cog wheels
// Nothing fancy, just hexagonal tiling + cog wheels
#define PI 3.141592654
#define TAU (2.0*PI)
#define MROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
float hash(in vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,58.233))) * 13758.5453);
}
float pcos(float a) {
return 0.5 + 0.5*cos(a);
}
void rot(inout vec2 p, float a) {
float c = cos(a);
float s = sin(a);
p = vec2(c*p.x + s*p.y, -s*p.x + c*p.y);
}
float modPolar(inout vec2 p, float repetitions) {
float angle = 2.0*PI/repetitions;
float a = atan(p.y, p.x) + angle/2.;
float r = length(p);
float c = floor(a/angle);
a = mod(a,angle) - angle/2.;
p = vec2(cos(a), sin(a))*r;
// For an odd number of repetitions, fix cell index of the cell in -x direction
// (cell index would be e.g. -5 and 5 in the two halves of the cell):
if (abs(c) >= (repetitions/2.0)) c = abs(c);
return c;
}
float pmin(float a, float b, float k) {
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
return mix( b, a, h ) - k*h*(1.0-h);
}
const vec2 sz = vec2(1.0, sqrt(3.0));
const vec2 hsz = 0.5*sz;
const float smallCount = 16.0;
vec2 hextile(inout vec2 p) {
// See Art of Code: Hexagonal Tiling Explained!
// https://www.youtube.com/watch?v=VmrIDyYiJBA
vec2 p1 = mod(p, sz)-hsz;
vec2 p2 = mod(p - hsz*1.0, sz)-hsz;
vec2 p3 = mix(p2, p1, vec2(length(p1) < length(p2)));
vec2 n = p3 - p;
p = p3;
return n;
}
float circle(vec2 p, float r) {
return length(p) - r;
}
float box(vec2 p, vec2 b) {
vec2 d = abs(p)-b;
return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
}
float unevenCapsule(vec2 p, float r1, float r2, float h) {
p.x = abs(p.x);
float b = (r1-r2)/h;
float a = sqrt(1.0-b*b);
float k = dot(p,vec2(-b,a));
if( k < 0.0 ) return length(p) - r1;
if( k > a*h ) return length(p-vec2(0.0,h)) - r2;
return dot(p, vec2(a,b) ) - r1;
}
float cogwheel(vec2 p, float innerRadius, float outerRadius, float cogs, float holes) {
float cogWidth = 0.25*innerRadius*TAU/cogs;
float d0 = circle(p, innerRadius);
vec2 icp = p;
modPolar(icp, holes);
icp -= vec2(innerRadius*0.55, 0.0);
float d1 = circle(icp, innerRadius*0.25);
vec2 cp = p;
modPolar(cp, cogs);
cp -= vec2(innerRadius, 0.0);
float d2 = unevenCapsule(cp.yx, cogWidth, cogWidth*0.75, (outerRadius-innerRadius));
float d3 = circle(p, innerRadius*0.20);
float d = 1E6;
d = min(d, d0);
d = pmin(d, d2, 0.5*cogWidth);
d = min(d, d2);
d = max(d, -d1);
d = max(d, -d3);
return d;
}
float ccell1(vec2 p, float r) {
float d = 1E6;
const float bigCount = 60.0;
vec2 cp0 = p;
rot(cp0, -iTime*TAU/bigCount);
float d0 = cogwheel(cp0, 0.36, 0.38, bigCount, 5.0);
vec2 cp1 = p;
float nm = modPolar(cp1, 6.0);
cp1 -= vec2(0.5, 0.0);
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
d = min(d, d0);
d = min(d, d1);
return d;
}
float ccell2(vec2 p, float r) {
float d = 1E6;
vec2 cp0 = p;
float nm = modPolar(cp0, 6.0);
vec2 cp1 = cp0;
const float off = 0.275;
const float count = smallCount + 2.0;
cp0 -= vec2(off, 0.0);
rot(cp0, 0.+TAU*nm/2.0 - iTime*TAU/count);
float d0 = cogwheel(cp0, 0.09, 0.105, count, 5.0);
cp1 -= vec2(0.5, 0.0);
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
float l = length(p);
float d2 = l - (off+0.055);
float d3 = d2 + 0.020;;
vec2 tp0 = p;
modPolar(tp0, 60.0);
tp0.x -= off;
float d4 = box(tp0, vec2(0.0125, 0.005));
float ctime = -(iTime*0.05 + r)*TAU;
vec2 tp1 = p;
rot(tp1, ctime*12.0);
tp1.x -= 0.13;
float d5 = box(tp1, vec2(0.125, 0.005));
vec2 tp2 = p;
rot(tp2, ctime);
tp2.x -= 0.13*0.5;
float d6 = box(tp2, vec2(0.125*0.5, 0.0075));
float d7 = l - 0.025;
float d8 = l - 0.0125;
d = min(d, d0);
d = min(d, d1);
d = min(d, d2);
d = max(d, -d3);
d = min(d, d4);
d = min(d, d5);
d = min(d, d6);
d = min(d, d7);
d = max(d, -d8);
return d;
}
float df(vec2 p, float scale, inout vec2 nn) {
p /= scale;
nn = hextile(p);
nn = floor(nn + 0.5);
float r = hash(nn);
float d;;
if (r < 0.5) {
d = ccell1(p, r);
} else {
d = ccell2(p, r);
}
return d*scale;
}
vec3 postProcess(vec3 col, vec2 q) {
//col = saturate(col);
col=pow(clamp(col,0.0,1.0),vec3(0.75));
col=col*0.6+0.4*col*col*(3.0-2.0*col); // contrast
col=mix(col, vec3(dot(col, vec3(0.33))), -0.4); // satuation
col*=0.5+0.5*pow(19.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7); // vigneting
return col;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv) {
vec2 q = fragCoord/resolution.xy;
vec2 p = -1.0 + 2.0*q;
p.x *= resolution.x/resolution.y;
float tm = iTime*0.1;
p += vec2(cos(tm), sin(tm*sqrt(0.5)));
float z = mix(0.5, 1.0, pcos(tm*sqrt(0.3)));
float aa = 4.0 / resolution.y;
vec2 nn = vec2(0.0);
float d = df(p, z, nn);
vec3 col = vec3(160.0)/vec3(255.0);
vec3 baseCol = vec3(0.3);
vec4 logoCol = vec4(baseCol, 1.0)*smoothstep(-aa, 0.0, -d);
col = mix(col, logoCol.xyz, pow(logoCol.w, 8.0));
col += 0.4*pow(abs(sin(20.0*d)), 0.6);
col = postProcess(col, q);
fragColor = vec4(col, 1.0);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,5 +1,4 @@
/* Combo Boxes
* #Keywords: GtkCellRenderer
*
* The GtkComboBox widget allows to select one option out of a list.
* The GtkComboBoxEntry additionally allows the user to enter a value
@@ -11,8 +10,6 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
enum
{
ICON_NAME_COL,
@@ -41,7 +38,7 @@ create_icon_store (void)
GtkTreeIter iter;
GtkListStore *store;
int i;
gint i;
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
@@ -80,7 +77,7 @@ set_sensitive (GtkCellLayout *cell_layout,
gpointer data)
{
GtkTreePath *path;
int *indices;
gint *indices;
gboolean sensitive;
path = gtk_tree_model_get_path (tree_model, iter);
@@ -178,7 +175,7 @@ create_capital_store (void)
GtkTreeIter iter, iter2;
GtkTreeStore *store;
int i;
gint i;
store = gtk_tree_store_new (1, G_TYPE_STRING);
@@ -449,7 +446,7 @@ do_combobox (GtkWidget *do_widget)
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));

View File

@@ -1,16 +1,8 @@
/* Constraints/Simple Constraints
* #Keywords: GtkLayoutManager
/* Constraints/Simple
*
* GtkConstraintLayout provides a layout manager that uses relations
* between widgets (also known as constraints) to compute the position
* between widgets (also known as "constraints") to compute the position
* and size of each child.
*
* In addition to child widgets, the constraints can involve spacer
* objects (also known as “guides”). This example has a guide between
* the two buttons in the top row.
*
* Try resizing the window to see how the constraints react to update
* the layout.
*/
#include <glib/gi18n.h>
@@ -241,12 +233,15 @@ simple_grid_init (SimpleGrid *self)
self->button1 = gtk_button_new_with_label ("Child 1");
gtk_widget_set_parent (self->button1, widget);
gtk_widget_set_name (self->button1, "button1");
self->button2 = gtk_button_new_with_label ("Child 2");
gtk_widget_set_parent (self->button2, widget);
gtk_widget_set_name (self->button2, "button2");
self->button3 = gtk_button_new_with_label ("Child 3");
gtk_widget_set_parent (self->button3, widget);
gtk_widget_set_name (self->button3, "button3");
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
@@ -259,12 +254,15 @@ do_constraints (GtkWidget *do_widget)
if (!window)
{
GtkWidget *box, *grid;
GtkWidget *header, *box, *grid, *button;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Simple Constraints");
gtk_window_set_default_size (GTK_WINDOW (window), 260, -1);
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
@@ -274,10 +272,16 @@ do_constraints (GtkWidget *do_widget)
gtk_widget_set_hexpand (grid, TRUE);
gtk_widget_set_vexpand (grid, TRUE);
gtk_box_append (GTK_BOX (box), grid);
button = gtk_button_new_with_label ("Close");
gtk_box_append (GTK_BOX (box), button);
gtk_widget_set_hexpand (grid, TRUE);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_window_destroy), window);
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));

View File

@@ -0,0 +1,245 @@
/* Constraints/Interactive
*
* Demonstrate how constraints can be updates during
* user interaction.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE (InteractiveGrid, interactive_grid, INTERACTIVE, GRID, GtkWidget)
struct _InteractiveGrid
{
GtkWidget parent_instance;
GtkWidget *button1, *button2;
GtkWidget *button3;
GtkConstraintGuide *guide;
GtkConstraint *constraint;
};
G_DEFINE_TYPE (InteractiveGrid, interactive_grid, GTK_TYPE_WIDGET)
static void
interactive_grid_dispose (GObject *object)
{
InteractiveGrid *self = INTERACTIVE_GRID (object);
g_clear_pointer (&self->button1, gtk_widget_unparent);
g_clear_pointer (&self->button2, gtk_widget_unparent);
g_clear_pointer (&self->button3, gtk_widget_unparent);
G_OBJECT_CLASS (interactive_grid_parent_class)->dispose (object);
}
static void
interactive_grid_class_init (InteractiveGridClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = interactive_grid_dispose;
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
}
static void
build_constraints (InteractiveGrid *self,
GtkConstraintLayout *manager)
{
self->guide = g_object_new (GTK_TYPE_CONSTRAINT_GUIDE, NULL);
gtk_constraint_layout_add_guide (manager, self->guide);
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide),
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
GTK_CONSTRAINT_RELATION_EQ,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (NULL,
GTK_CONSTRAINT_ATTRIBUTE_START,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->button1),
GTK_CONSTRAINT_ATTRIBUTE_START,
1.0,
-8.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button1),
GTK_CONSTRAINT_ATTRIBUTE_END,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->guide),
GTK_CONSTRAINT_ATTRIBUTE_START,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
GTK_CONSTRAINT_ATTRIBUTE_START,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->guide),
GTK_CONSTRAINT_ATTRIBUTE_END,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
GTK_CONSTRAINT_ATTRIBUTE_END,
GTK_CONSTRAINT_RELATION_EQ,
NULL,
GTK_CONSTRAINT_ATTRIBUTE_END,
1.0,
-8.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (NULL,
GTK_CONSTRAINT_ATTRIBUTE_START,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->button3),
GTK_CONSTRAINT_ATTRIBUTE_START,
1.0,
-8.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
GTK_CONSTRAINT_ATTRIBUTE_END,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->guide),
GTK_CONSTRAINT_ATTRIBUTE_START,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (NULL,
GTK_CONSTRAINT_ATTRIBUTE_TOP,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->button1),
GTK_CONSTRAINT_ATTRIBUTE_TOP,
1.0,
-8.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
GTK_CONSTRAINT_ATTRIBUTE_TOP,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->button1),
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
GTK_CONSTRAINT_ATTRIBUTE_TOP,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->button2),
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
GTK_CONSTRAINT_RELATION_EQ,
NULL,
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
1.0,
-8.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
}
static void
drag_cb (GtkGestureDrag *drag,
double offset_x,
double offset_y,
InteractiveGrid *self)
{
GtkConstraintLayout *layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (self)));
double x, y;
if (self->constraint)
{
gtk_constraint_layout_remove_constraint (layout, self->constraint);
g_clear_object (&self->constraint);
}
gtk_gesture_drag_get_start_point (drag, &x, &y);
self->constraint = gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide),
GTK_CONSTRAINT_ATTRIBUTE_LEFT,
GTK_CONSTRAINT_RELATION_EQ,
x + offset_x,
GTK_CONSTRAINT_STRENGTH_REQUIRED);
gtk_constraint_layout_add_constraint (layout, g_object_ref (self->constraint));
gtk_widget_queue_allocate (GTK_WIDGET (self));
}
static void
interactive_grid_init (InteractiveGrid *self)
{
GtkWidget *widget = GTK_WIDGET (self);
GtkGesture *drag;
self->button1 = gtk_button_new_with_label ("Child 1");
gtk_widget_set_parent (self->button1, widget);
gtk_widget_set_name (self->button1, "button1");
self->button2 = gtk_button_new_with_label ("Child 2");
gtk_widget_set_parent (self->button2, widget);
gtk_widget_set_name (self->button2, "button2");
self->button3 = gtk_button_new_with_label ("Child 3");
gtk_widget_set_parent (self->button3, widget);
gtk_widget_set_name (self->button3, "button3");
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
drag = gtk_gesture_drag_new ();
g_signal_connect (drag, "drag-update", G_CALLBACK (drag_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (drag));
}
GtkWidget *
do_constraints2 (GtkWidget *do_widget)
{
static GtkWidget *window;
if (!window)
{
GtkWidget *header, *box, *grid, *button;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_window_set_child (GTK_WINDOW (window), box);
grid = g_object_new (interactive_grid_get_type (), NULL);
gtk_widget_set_hexpand (grid, TRUE);
gtk_widget_set_vexpand (grid, TRUE);
gtk_box_append (GTK_BOX (box), grid);
button = gtk_button_new_with_label ("Close");
gtk_box_append (GTK_BOX (box), button);
gtk_widget_set_hexpand (grid, TRUE);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_window_destroy), window);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -0,0 +1,165 @@
/* Constraints/VFL
*
* GtkConstraintLayout allows defining constraints using a
* compact syntax called Visual Format Language, or VFL.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE (VflGrid, vfl_grid, VFL, GRID, GtkWidget)
struct _VflGrid
{
GtkWidget parent_instance;
GtkWidget *button1, *button2;
GtkWidget *button3;
};
G_DEFINE_TYPE (VflGrid, vfl_grid, GTK_TYPE_WIDGET)
static void
vfl_grid_dispose (GObject *object)
{
VflGrid *self = VFL_GRID (object);
g_clear_pointer (&self->button1, gtk_widget_unparent);
g_clear_pointer (&self->button2, gtk_widget_unparent);
g_clear_pointer (&self->button3, gtk_widget_unparent);
G_OBJECT_CLASS (vfl_grid_parent_class)->dispose (object);
}
static void
vfl_grid_class_init (VflGridClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = vfl_grid_dispose;
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
}
/* Layout:
*
* +-----------------------------+
* | +-----------+ +-----------+ |
* | | Child 1 | | Child 2 | |
* | +-----------+ +-----------+ |
* | +-------------------------+ |
* | | Child 3 | |
* | +-------------------------+ |
* +-----------------------------+
*
* Constraints:
*
* super.start = child1.start - 8
* child1.width = child2.width
* child1.end = child2.start - 12
* child2.end = super.end - 8
* super.start = child3.start - 8
* child3.end = super.end - 8
* super.top = child1.top - 8
* super.top = child2.top - 8
* child1.bottom = child3.top - 12
* child2.bottom = child3.top - 12
* child3.height = child1.height
* child3.height = child2.height
* child3.bottom = super.bottom - 8
*
* Visual format:
*
* H:|-8-[view1(==view2)-12-[view2]-8-|
* H:|-8-[view3]-8-|
* V:|-8-[view1]-12-[view3(==view1)]-8-|
* V:|-8-[view2]-12-[view3(==view2)]-8-|
*/
static void
build_constraints (VflGrid *self,
GtkConstraintLayout *manager)
{
const char * const vfl[] = {
"H:|-[button1(==button2)]-12-[button2]-|",
"H:|-[button3]-|",
"V:|-[button1]-12-[button3(==button1)]-|",
"V:|-[button2]-12-[button3(==button2)]-|",
};
GError *error = NULL;
gtk_constraint_layout_add_constraints_from_description (manager, vfl, G_N_ELEMENTS (vfl),
8, 8,
&error,
"button1", self->button1,
"button2", self->button2,
"button3", self->button3,
NULL);
if (error != NULL)
{
g_printerr ("VFL parsing error:\n%s", error->message);
g_error_free (error);
}
}
static void
vfl_grid_init (VflGrid *self)
{
GtkWidget *widget = GTK_WIDGET (self);
self->button1 = gtk_button_new_with_label ("Child 1");
gtk_widget_set_parent (self->button1, widget);
gtk_widget_set_name (self->button1, "button1");
self->button2 = gtk_button_new_with_label ("Child 2");
gtk_widget_set_parent (self->button2, widget);
gtk_widget_set_name (self->button2, "button2");
self->button3 = gtk_button_new_with_label ("Child 3");
gtk_widget_set_parent (self->button3, widget);
gtk_widget_set_name (self->button3, "button3");
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
}
GtkWidget *
do_constraints3 (GtkWidget *do_widget)
{
static GtkWidget *window;
if (!window)
{
GtkWidget *header, *box, *grid, *button;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_window_set_child (GTK_WINDOW (window), box);
grid = g_object_new (vfl_grid_get_type (), NULL);
gtk_widget_set_hexpand (grid, TRUE);
gtk_widget_set_vexpand (grid, TRUE);
gtk_box_append (GTK_BOX (box), grid);
button = gtk_button_new_with_label ("Close");
gtk_box_append (GTK_BOX (box), button);
gtk_widget_set_hexpand (grid, TRUE);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (gtk_window_destroy), window);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,74 +0,0 @@
/* Constraints/Builder
*
* GtkConstraintLayouts can be created in .ui files, and constraints can
* be set up at that time as well, as this example demonstrates. It shows
* various ways to do spacing and sizing with constraints.
*
* Make the window wider to see the rows react differently
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE (ConstraintsGrid, constraints_grid, CONSTRAINTS, GRID, GtkWidget)
struct _ConstraintsGrid
{
GtkWidget parent_instance;
};
G_DEFINE_TYPE (ConstraintsGrid, constraints_grid, GTK_TYPE_WIDGET)
static void
constraints_grid_init (ConstraintsGrid *grid)
{
}
static void
constraints_grid_dispose (GObject *object)
{
GtkWidget *widget = GTK_WIDGET (object);
GtkWidget *child;
while ((child = gtk_widget_get_first_child (widget)))
gtk_widget_unparent (child);
G_OBJECT_CLASS (constraints_grid_parent_class)->dispose (object);
}
static void
constraints_grid_class_init (ConstraintsGridClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = constraints_grid_dispose;
}
GtkWidget *
do_constraints_builder (GtkWidget *do_widget)
{
static GtkWidget *window;
if (!window)
{
GtkBuilder *builder;
g_type_ensure (constraints_grid_get_type ());
builder = gtk_builder_new_from_resource ("/constraints_builder/constraints_builder.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,460 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window1">
<property name="title" translatable="yes">ConstraintsBuilder</property>
<property name="default-width">260</property>
<child>
<object class="ConstraintsGrid">
<property name="halign">fill</property>
<property name="valign">fill</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="layout-manager">
<object class="GtkConstraintLayout">
<constraints>
<guide name="guide1" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide2" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide3" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide4" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide5" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide6" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide7" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide8" min-width="10" nat-width="200" strength="weak"/>
<guide name="guide9" min-width="0" nat-width="200" strength="weak"/>
<guide name="guide10" min-width="0" nat-width="200" strength="weak"/>
<guide name="barrier1" min-height="10"/>
<guide name="barrier2" min-height="10"/>
<guide name="barrier3" min-height="10"/>
<guide name="barrier4" min-height="10"/>
<!-- Spread Chain -->
<constraint target="super" target-attribute="top"
relation="eq"
source="button1" source-attribute="top"
strength="required"/>
<constraint target="super" target-attribute="top"
relation="eq"
source="button2" source-attribute="top"
strength="required"/>
<constraint target="super" target-attribute="top"
relation="eq"
source="button3" source-attribute="top"
strength="required"/>
<constraint target="super" target-attribute="left"
relation="eq"
source="guide1" source-attribute="left"
strength="required"/>
<constraint target="button1" target-attribute="left"
relation="eq"
source="guide1" source-attribute="right"
strength="required"/>
<constraint target="guide2" target-attribute="left"
relation="eq"
source="button1" source-attribute="right"
strength="required"/>
<constraint target="button2" target-attribute="left"
relation="eq"
source="guide2" source-attribute="right"
strength="required"/>
<constraint target="guide3" target-attribute="left"
relation="eq"
source="button2" source-attribute="right"
strength="required"/>
<constraint target="button3" target-attribute="left"
relation="eq"
source="guide3" source-attribute="right"
strength="required"/>
<constraint target="guide4" target-attribute="left"
relation="eq"
source="button3" source-attribute="right"
strength="required"/>
<constraint target="super" target-attribute="right"
relation="eq"
source="guide4" source-attribute="right"
strength="required"/>
<constraint target="guide1" target-attribute="width"
relation="eq"
source="guide2" source-attribute="width"
strength="required"/>
<constraint target="guide2" target-attribute="width"
relation="eq"
source="guide3" source-attribute="width"
strength="required"/>
<constraint target="guide3" target-attribute="width"
relation="eq"
source="guide4" source-attribute="width"
strength="required"/>
<constraint target="button1" target-attribute="width"
relation="eq"
source="button2" source-attribute="width"
strength="required"/>
<constraint target="button2" target-attribute="width"
relation="eq"
source="button3" source-attribute="width"
strength="required"/>
<constraint target="button1" target-attribute="bottom"
relation="eq"
source="barrier1" source-attribute="top"
strength="required"/>
<constraint target="button2" target-attribute="bottom"
relation="eq"
source="barrier1" source-attribute="top"
strength="required"/>
<constraint target="button3" target-attribute="bottom"
relation="eq"
source="barrier1" source-attribute="top"
strength="required"/>
<!-- Spread Inside Chain -->
<constraint target="super" target-attribute="left"
relation="eq"
source="button4" source-attribute="left"
strength="required"/>
<constraint target="guide5" target-attribute="left"
relation="eq"
source="button4" source-attribute="right"
strength="required"/>
<constraint target="button5" target-attribute="left"
relation="eq"
source="guide5" source-attribute="right"
strength="required"/>
<constraint target="guide6" target-attribute="left"
relation="eq"
source="button5" source-attribute="right"
strength="required"/>
<constraint target="button6" target-attribute="left"
relation="eq"
source="guide6" source-attribute="right"
strength="required"/>
<constraint target="super" target-attribute="right"
relation="eq"
source="button6" source-attribute="right"
strength="required"/>
<constraint target="guide5" target-attribute="width"
relation="eq"
source="guide6" source-attribute="width"
strength="required"/>
<constraint target="button4" target-attribute="width"
relation="eq"
source="button5" source-attribute="width"
strength="required"/>
<constraint target="button5" target-attribute="width"
relation="eq"
source="button6" source-attribute="width"
strength="required"/>
<constraint target="button4" target-attribute="top"
relation="eq"
source="barrier1" source-attribute="bottom"
strength="required"/>
<constraint target="button5" target-attribute="top"
relation="eq"
source="barrier1" source-attribute="bottom"
strength="required"/>
<constraint target="button6" target-attribute="top"
relation="eq"
source="barrier1" source-attribute="bottom"
strength="required"/>
<constraint target="button4" target-attribute="bottom"
relation="eq"
source="barrier2" source-attribute="top"
strength="required"/>
<constraint target="button5" target-attribute="bottom"
relation="eq"
source="barrier2" source-attribute="top"
strength="required"/>
<constraint target="button6" target-attribute="bottom"
relation="eq"
source="barrier2" source-attribute="top"
strength="required"/>
<!-- Weighted Chain -->
<constraint target="super" target-attribute="left"
relation="eq"
source="button7" source-attribute="left"
strength="required"/>
<constraint target="button8" target-attribute="left"
relation="eq"
source="button7" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="button9" target-attribute="left"
relation="eq"
source="button8" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="super" target-attribute="right"
relation="eq"
source="button9" source-attribute="right"
strength="required"/>
<constraint target="button8" target-attribute="width"
relation="eq"
source="button7" source-attribute="width"
multiplier="2"
strength="required"/>
<constraint target="button9" target-attribute="width"
relation="eq"
source="button7" source-attribute="width"
multiplier="3"
strength="required"/>
<constraint target="button7" target-attribute="top"
relation="eq"
source="barrier2" source-attribute="bottom"
strength="required"/>
<constraint target="button8" target-attribute="top"
relation="eq"
source="barrier2" source-attribute="bottom"
strength="required"/>
<constraint target="button9" target-attribute="top"
relation="eq"
source="barrier2" source-attribute="bottom"
strength="required"/>
<constraint target="button7" target-attribute="bottom"
relation="eq"
source="barrier3" source-attribute="top"
strength="required"/>
<constraint target="button8" target-attribute="bottom"
relation="eq"
source="barrier3" source-attribute="top"
strength="required"/>
<constraint target="button9" target-attribute="bottom"
relation="eq"
source="barrier3" source-attribute="top"
strength="required"/>
<!-- Packed Chain -->
<constraint target="super" target-attribute="left"
relation="eq"
source="guide7" source-attribute="left"
strength="required"/>
<constraint target="button10" target-attribute="left"
relation="eq"
source="guide7" source-attribute="right"
strength="required"/>
<constraint target="button11" target-attribute="left"
relation="eq"
source="button10" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="button12" target-attribute="left"
relation="eq"
source="button11" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="guide8" target-attribute="left"
relation="eq"
source="button12" source-attribute="right"
strength="required"/>
<constraint target="super" target-attribute="right"
relation="eq"
source="guide8" source-attribute="right"
strength="required"/>
<constraint target="guide7" target-attribute="width"
relation="eq"
source="guide8" source-attribute="width"
strength="required"/>
<constraint target="button10" target-attribute="width"
relation="eq"
source="button11" source-attribute="width"
strength="required"/>
<constraint target="button11" target-attribute="width"
relation="eq"
source="button12" source-attribute="width"
strength="required"/>
<constraint target="button10" target-attribute="top"
relation="eq"
source="barrier3" source-attribute="bottom"
strength="required"/>
<constraint target="button11" target-attribute="top"
relation="eq"
source="barrier3" source-attribute="bottom"
strength="required"/>
<constraint target="button12" target-attribute="top"
relation="eq"
source="barrier3" source-attribute="bottom"
strength="required"/>
<constraint target="button10" target-attribute="bottom"
relation="eq"
source="barrier4" source-attribute="top"
strength="required"/>
<constraint target="button11" target-attribute="bottom"
relation="eq"
source="barrier4" source-attribute="top"
strength="required"/>
<constraint target="button12" target-attribute="bottom"
relation="eq"
source="barrier4" source-attribute="top"
strength="required"/>
<!-- Packed Chain with Bias -->
<constraint target="super" target-attribute="left"
relation="eq"
source="guide9" source-attribute="left"
strength="required"/>
<constraint target="button13" target-attribute="left"
relation="eq"
source="guide9" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="button14" target-attribute="left"
relation="eq"
source="button13" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="button15" target-attribute="left"
relation="eq"
source="button14" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="guide10" target-attribute="left"
relation="eq"
source="button15" source-attribute="right"
constant="10"
strength="required"/>
<constraint target="super" target-attribute="right"
relation="eq"
source="guide10" source-attribute="right"
strength="required"/>
<constraint target="guide9" target-attribute="width"
relation="eq"
source="guide10" source-attribute="width"
multiplier="4"
strength="required"/>
<constraint target="button13" target-attribute="width"
relation="eq"
source="button14" source-attribute="width"
strength="required"/>
<constraint target="button14" target-attribute="width"
relation="eq"
source="button15" source-attribute="width"
strength="required"/>
<constraint target="button13" target-attribute="top"
relation="eq"
source="barrier4" source-attribute="bottom"
strength="required"/>
<constraint target="button14" target-attribute="top"
relation="eq"
source="barrier4" source-attribute="bottom"
strength="required"/>
<constraint target="button15" target-attribute="top"
relation="eq"
source="barrier4" source-attribute="bottom"
strength="required"/>
<constraint target="super" target-attribute="bottom"
relation="ge"
source="button13" source-attribute="bottom"
strength="required"/>
<constraint target="super" target-attribute="bottom"
relation="ge"
source="button14" source-attribute="bottom"
strength="required"/>
<constraint target="super" target-attribute="bottom"
relation="ge"
source="button15" source-attribute="bottom"
strength="required"/>
</constraints>
</object>
</property>
<child>
<object class="GtkButton" id="button1">
<property name="label">A</property>
</object>
</child>
<child>
<object class="GtkButton" id="button2">
<property name="label">B</property>
</object>
</child>
<child>
<object class="GtkButton" id="button3">
<property name="label">C</property>
</object>
</child>
<child>
<object class="GtkButton" id="button4">
<property name="label">A</property>
</object>
</child>
<child>
<object class="GtkButton" id="button5">
<property name="label">B</property>
</object>
</child>
<child>
<object class="GtkButton" id="button6">
<property name="label">C</property>
</object>
</child>
<child>
<object class="GtkButton" id="button7">
<property name="label">A</property>
</object>
</child>
<child>
<object class="GtkButton" id="button8">
<property name="label">B</property>
</object>
</child>
<child>
<object class="GtkButton" id="button9">
<property name="label">C</property>
</object>
</child>
<child>
<object class="GtkButton" id="button10">
<property name="label">A</property>
</object>
</child>
<child>
<object class="GtkButton" id="button11">
<property name="label">B</property>
</object>
</child>
<child>
<object class="GtkButton" id="button12">
<property name="label">C</property>
</object>
</child>
<child>
<object class="GtkButton" id="button13">
<property name="label">A</property>
</object>
</child>
<child>
<object class="GtkButton" id="button14">
<property name="label">B</property>
</object>
</child>
<child>
<object class="GtkButton" id="button15">
<property name="label">C</property>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -1,237 +0,0 @@
/* Constraints/Interactive Constraints
* #Keywords: GtkConstraintLayout
*
* This example shows how constraints can be updated during user interaction.
* The vertical edge between the buttons can be dragged with the mouse.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE (InteractiveGrid, interactive_grid, INTERACTIVE, GRID, GtkWidget)
struct _InteractiveGrid
{
GtkWidget parent_instance;
GtkWidget *button1, *button2;
GtkWidget *button3;
GtkConstraintGuide *guide;
GtkConstraint *constraint;
};
G_DEFINE_TYPE (InteractiveGrid, interactive_grid, GTK_TYPE_WIDGET)
static void
interactive_grid_dispose (GObject *object)
{
InteractiveGrid *self = INTERACTIVE_GRID (object);
g_clear_pointer (&self->button1, gtk_widget_unparent);
g_clear_pointer (&self->button2, gtk_widget_unparent);
g_clear_pointer (&self->button3, gtk_widget_unparent);
G_OBJECT_CLASS (interactive_grid_parent_class)->dispose (object);
}
static void
interactive_grid_class_init (InteractiveGridClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = interactive_grid_dispose;
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
}
static void
build_constraints (InteractiveGrid *self,
GtkConstraintLayout *manager)
{
self->guide = g_object_new (GTK_TYPE_CONSTRAINT_GUIDE, NULL);
gtk_constraint_layout_add_guide (manager, self->guide);
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide),
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
GTK_CONSTRAINT_RELATION_EQ,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (NULL,
GTK_CONSTRAINT_ATTRIBUTE_START,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->button1),
GTK_CONSTRAINT_ATTRIBUTE_START,
1.0,
-8.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button1),
GTK_CONSTRAINT_ATTRIBUTE_END,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->guide),
GTK_CONSTRAINT_ATTRIBUTE_START,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
GTK_CONSTRAINT_ATTRIBUTE_START,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->guide),
GTK_CONSTRAINT_ATTRIBUTE_END,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
GTK_CONSTRAINT_ATTRIBUTE_END,
GTK_CONSTRAINT_RELATION_EQ,
NULL,
GTK_CONSTRAINT_ATTRIBUTE_END,
1.0,
-8.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (NULL,
GTK_CONSTRAINT_ATTRIBUTE_START,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->button3),
GTK_CONSTRAINT_ATTRIBUTE_START,
1.0,
-8.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
GTK_CONSTRAINT_ATTRIBUTE_END,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->guide),
GTK_CONSTRAINT_ATTRIBUTE_START,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (NULL,
GTK_CONSTRAINT_ATTRIBUTE_TOP,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->button1),
GTK_CONSTRAINT_ATTRIBUTE_TOP,
1.0,
-8.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
GTK_CONSTRAINT_ATTRIBUTE_TOP,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->button1),
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
GTK_CONSTRAINT_ATTRIBUTE_TOP,
GTK_CONSTRAINT_RELATION_EQ,
GTK_CONSTRAINT_TARGET (self->button2),
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
1.0,
0.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
gtk_constraint_layout_add_constraint (manager,
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
GTK_CONSTRAINT_RELATION_EQ,
NULL,
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
1.0,
-8.0,
GTK_CONSTRAINT_STRENGTH_REQUIRED));
}
static void
drag_cb (GtkGestureDrag *drag,
double offset_x,
double offset_y,
InteractiveGrid *self)
{
GtkConstraintLayout *layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (self)));
double x, y;
if (self->constraint)
{
gtk_constraint_layout_remove_constraint (layout, self->constraint);
g_clear_object (&self->constraint);
}
gtk_gesture_drag_get_start_point (drag, &x, &y);
self->constraint = gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide),
GTK_CONSTRAINT_ATTRIBUTE_LEFT,
GTK_CONSTRAINT_RELATION_EQ,
x + offset_x,
GTK_CONSTRAINT_STRENGTH_REQUIRED);
gtk_constraint_layout_add_constraint (layout, g_object_ref (self->constraint));
gtk_widget_queue_allocate (GTK_WIDGET (self));
}
static void
interactive_grid_init (InteractiveGrid *self)
{
GtkWidget *widget = GTK_WIDGET (self);
GtkGesture *drag;
self->button1 = gtk_button_new_with_label ("Child 1");
gtk_widget_set_parent (self->button1, widget);
gtk_widget_set_name (self->button1, "button1");
self->button2 = gtk_button_new_with_label ("Child 2");
gtk_widget_set_parent (self->button2, widget);
gtk_widget_set_name (self->button2, "button2");
self->button3 = gtk_button_new_with_label ("Child 3");
gtk_widget_set_parent (self->button3, widget);
gtk_widget_set_name (self->button3, "button3");
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
drag = gtk_gesture_drag_new ();
g_signal_connect (drag, "drag-update", G_CALLBACK (drag_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (drag));
}
GtkWidget *
do_constraints_interactive (GtkWidget *do_widget)
{
static GtkWidget *window;
if (!window)
{
GtkWidget *box, *grid;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Interactive Constraints");
gtk_window_set_default_size (GTK_WINDOW (window), 260, -1);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_window_set_child (GTK_WINDOW (window), box);
grid = g_object_new (interactive_grid_get_type (), NULL);
gtk_widget_set_hexpand (grid, TRUE);
gtk_widget_set_vexpand (grid, TRUE);
gtk_box_append (GTK_BOX (box), grid);
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,160 +0,0 @@
/* Constraints/VFL
*
* GtkConstraintLayout allows defining constraints using a
* compact syntax called Visual Format Language, or VFL.
*
* A typical example of a VFL specification looks like this:
*
* H:|-[button1(==button2)]-12-[button2]-|
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE (VflGrid, vfl_grid, VFL, GRID, GtkWidget)
struct _VflGrid
{
GtkWidget parent_instance;
GtkWidget *button1, *button2;
GtkWidget *button3;
};
G_DEFINE_TYPE (VflGrid, vfl_grid, GTK_TYPE_WIDGET)
static void
vfl_grid_dispose (GObject *object)
{
VflGrid *self = VFL_GRID (object);
g_clear_pointer (&self->button1, gtk_widget_unparent);
g_clear_pointer (&self->button2, gtk_widget_unparent);
g_clear_pointer (&self->button3, gtk_widget_unparent);
G_OBJECT_CLASS (vfl_grid_parent_class)->dispose (object);
}
static void
vfl_grid_class_init (VflGridClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = vfl_grid_dispose;
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
}
/* Layout:
*
* +-----------------------------+
* | +-----------+ +-----------+ |
* | | Child 1 | | Child 2 | |
* | +-----------+ +-----------+ |
* | +-------------------------+ |
* | | Child 3 | |
* | +-------------------------+ |
* +-----------------------------+
*
* Constraints:
*
* super.start = child1.start - 8
* child1.width = child2.width
* child1.end = child2.start - 12
* child2.end = super.end - 8
* super.start = child3.start - 8
* child3.end = super.end - 8
* super.top = child1.top - 8
* super.top = child2.top - 8
* child1.bottom = child3.top - 12
* child2.bottom = child3.top - 12
* child3.height = child1.height
* child3.height = child2.height
* child3.bottom = super.bottom - 8
*
* Visual format:
*
* H:|-8-[view1(==view2)-12-[view2]-8-|
* H:|-8-[view3]-8-|
* V:|-8-[view1]-12-[view3(==view1)]-8-|
* V:|-8-[view2]-12-[view3(==view2)]-8-|
*/
static void
build_constraints (VflGrid *self,
GtkConstraintLayout *manager)
{
const char * const vfl[] = {
"H:|-[button1(==button2)]-12-[button2]-|",
"H:|-[button3]-|",
"V:|-[button1]-12-[button3(==button1)]-|",
"V:|-[button2]-12-[button3(==button2)]-|",
};
GError *error = NULL;
gtk_constraint_layout_add_constraints_from_description (manager, vfl, G_N_ELEMENTS (vfl),
8, 8,
&error,
"button1", self->button1,
"button2", self->button2,
"button3", self->button3,
NULL);
if (error != NULL)
{
g_printerr ("VFL parsing error:\n%s", error->message);
g_error_free (error);
}
}
static void
vfl_grid_init (VflGrid *self)
{
GtkWidget *widget = GTK_WIDGET (self);
self->button1 = gtk_button_new_with_label ("Child 1");
gtk_widget_set_parent (self->button1, widget);
gtk_widget_set_name (self->button1, "button1");
self->button2 = gtk_button_new_with_label ("Child 2");
gtk_widget_set_parent (self->button2, widget);
gtk_widget_set_name (self->button2, "button2");
self->button3 = gtk_button_new_with_label ("Child 3");
gtk_widget_set_parent (self->button3, widget);
gtk_widget_set_name (self->button3, "button3");
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
}
GtkWidget *
do_constraints_vfl (GtkWidget *do_widget)
{
static GtkWidget *window;
if (!window)
{
GtkWidget *box, *grid;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "ConstraintsVFL");
gtk_window_set_default_size (GTK_WINDOW (window), 260, -1);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_window_set_child (GTK_WINDOW (window), box);
grid = g_object_new (vfl_grid_get_type (), NULL);
gtk_widget_set_hexpand (grid, TRUE);
gtk_widget_set_vexpand (grid, TRUE);
gtk_box_append (GTK_BOX (box), grid);
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1019 B

After

Width:  |  Height:  |  Size: 985 B

View File

@@ -1,27 +0,0 @@
uniform float progress;
uniform sampler2D u_texture1;
uniform sampler2D u_texture2;
vec4 getFromColor (vec2 uv) {
return GskTexture(u_texture1, uv);
}
vec4 getToColor (vec2 uv) {
return GskTexture(u_texture2, uv);
}
// Source: https://gl-transitions.com/editor/crosswarp
// Author: Eke Péter <peterekepeter@gmail.com>
// License: MIT
vec4 transition(vec2 p) {
float x = progress;
x=smoothstep(.0,1.0,(x*2.0+p.x-1.0));
return mix(getFromColor((p-.5)*(1.-x)+.5), getToColor((p-.5)*x+.5), x);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)
{
fragColor = transition(uv);
}

View File

@@ -7,10 +7,15 @@
#include <gtk/gtk.h>
static void
destroy_provider (GtkWidget *window,
GtkStyleProvider *provider)
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
{
gtk_style_context_remove_provider_for_display (gtk_widget_get_display (window), provider);
GtkWidget *child;
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
apply_css (child, provider);
}
GtkWidget *
@@ -20,8 +25,8 @@ do_css_accordion (GtkWidget *do_widget)
if (!window)
{
GtkWidget *container, *styled_box, *child;
GtkCssProvider *provider;
GtkWidget *container, *child;
GtkStyleProvider *provider;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "CSS Accordion");
@@ -29,13 +34,10 @@ do_css_accordion (GtkWidget *do_widget)
gtk_window_set_default_size (GTK_WINDOW (window), 600, 300);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
styled_box = gtk_frame_new (NULL);
gtk_window_set_child (GTK_WINDOW (window), styled_box);
gtk_widget_add_css_class (styled_box, "accordion");
container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_set_halign (container, GTK_ALIGN_CENTER);
gtk_widget_set_valign (container, GTK_ALIGN_CENTER);
gtk_frame_set_child (GTK_FRAME (styled_box), container);
gtk_window_set_child (GTK_WINDOW (window), container);
child = gtk_button_new_with_label ("This");
gtk_box_append (GTK_BOX (container), child);
@@ -55,20 +57,14 @@ do_css_accordion (GtkWidget *do_widget)
child = gtk_button_new_with_label (":-)");
gtk_box_append (GTK_BOX (container), child);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/css_accordion/css_accordion.css");
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
gtk_css_provider_load_from_resource (GTK_CSS_PROVIDER (provider), "/css_accordion/css_accordion.css");
gtk_style_context_add_provider_for_display (gtk_widget_get_display (window),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
g_signal_connect (window, "destroy",
G_CALLBACK (destroy_provider), provider);
g_object_unref (provider);
apply_css (window, provider);
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));

View File

@@ -1,13 +1,13 @@
.accordion, .accordion * {
all: unset;
@import url("resource://css_accordion/reset.css");
* {
transition-property: color, background-color, border-color, background-image, padding, border-width;
transition-duration: 1s;
font: 20px Cantarell;
}
.accordion {
window {
background: linear-gradient(153deg, #151515, #151515 5px, transparent 5px) 0 0,
linear-gradient(333deg, #151515, #151515 5px, transparent 5px) 10px 5px,
linear-gradient(153deg, #222, #222 5px, transparent 5px) 0 5px,
@@ -18,7 +18,7 @@
background-size: 20px 20px;
}
.accordion button {
button {
color: black;
background-color: #bbb;
border-style: solid;
@@ -28,25 +28,25 @@
padding: 12px 4px;
}
.accordion button:first-child {
button:first-child {
border-radius: 5px 0 0 5px;
}
.accordion button:last-child {
button:last-child {
border-radius: 0 5px 5px 0;
border-width: 2px;
}
.accordion button:hover {
button:hover {
padding: 12px 48px;
background-color: #4870bc;
}
.accordion button *:hover {
button *:hover {
color: white;
}
.accordion button:hover:active,
.accordion button:active {
button:hover:active,
button:active {
background-color: #993401;
}

View File

@@ -1,7 +1,8 @@
/* Theming/CSS Basics
*
* GTK themes are written using CSS. Every widget is build of multiple items
* Gtk themes are written using CSS. Every widget is build of multiple items
* that you can style very similarly to a regular website.
*
*/
#include <gtk/gtk.h>
@@ -47,23 +48,20 @@ css_text_changed (GtkTextBuffer *buffer,
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
gtk_css_provider_load_from_string (provider, text);
gtk_css_provider_load_from_data (provider, text, -1);
g_free (text);
}
static void
clear_provider (gpointer data)
{
GtkStyleProvider *provider = data;
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
}
static void
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
{
gtk_style_context_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
GtkWidget *child;
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
apply_css (child, provider);
}
GtkWidget *
@@ -82,7 +80,6 @@ do_css_basics (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "CSS Basics");
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
gtk_widget_add_css_class (window, "demo");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
text = gtk_text_buffer_new (NULL);
@@ -97,7 +94,7 @@ do_css_basics (GtkWidget *do_widget)
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
container = gtk_scrolled_window_new ();
container = gtk_scrolled_window_new (NULL, NULL);
gtk_window_set_child (GTK_WINDOW (window), container);
child = gtk_text_view_new_with_buffer (text);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (container), child);
@@ -117,7 +114,7 @@ do_css_basics (GtkWidget *do_widget)
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));

View File

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

View File

@@ -38,19 +38,19 @@ struct {
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
static void
update_css_for_blend_mode (GtkCssProvider *provider,
const char *blend_mode)
const gchar *blend_mode)
{
GBytes *bytes;
char *css;
gchar *css;
bytes = g_resources_lookup_data ("/css_blendmodes/css_blendmodes.css", 0, NULL);
css = g_strdup_printf ((char *) g_bytes_get_data (bytes, NULL),
css = g_strdup_printf ((gchar*) g_bytes_get_data (bytes, NULL),
blend_mode,
blend_mode,
blend_mode);
gtk_css_provider_load_from_string (provider, css);
gtk_css_provider_load_from_data (provider, css, -1);
g_bytes_unref (bytes);
g_free (css);
@@ -62,7 +62,7 @@ row_activated (GtkListBox *listbox,
GtkListBoxRow *row,
GtkCssProvider *provider)
{
const char *blend_mode;
const gchar *blend_mode;
blend_mode = blend_modes[gtk_list_box_row_get_index (row)].id;
@@ -75,7 +75,7 @@ setup_listbox (GtkBuilder *builder,
{
GtkWidget *normal_row;
GtkWidget *listbox;
int i;
gint i;
normal_row = NULL;
listbox = gtk_list_box_new ();
@@ -139,7 +139,7 @@ do_css_blendmodes (GtkWidget *do_widget)
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));

View File

@@ -1,7 +1,8 @@
/* Theming/Multiple Backgrounds
*
* GTK themes are written using CSS. Every widget is build of multiple items
* Gtk themes are written using CSS. Every widget is build of multiple items
* that you can style very similarly to a regular website.
*
*/
#include <gtk/gtk.h>
@@ -48,23 +49,33 @@ css_text_changed (GtkTextBuffer *buffer,
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
gtk_css_provider_load_from_string (provider, text);
gtk_css_provider_load_from_data (provider, text, -1);
g_free (text);
}
static void
clear_provider (gpointer data)
drawing_area_draw (GtkDrawingArea *da,
cairo_t *cr,
int width,
int height,
gpointer data)
{
GtkStyleProvider *provider = data;
GtkStyleContext *context = gtk_widget_get_style_context (GTK_WIDGET (da));
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
gtk_render_background (context, cr, 0, 0, width, height);
gtk_render_frame (context, cr, 0, 0, width, height);
}
static void
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
{
gtk_style_context_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
GtkWidget *child;
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
apply_css (child, provider);
}
GtkWidget *
@@ -83,17 +94,16 @@ do_css_multiplebgs (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Multiple Backgrounds");
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
gtk_widget_add_css_class (window, "demo");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
overlay = gtk_overlay_new ();
gtk_window_set_child (GTK_WINDOW (window), overlay);
child = gtk_drawing_area_new ();
/* Don't set a draw_func, since we are only interested in CSS drawing,
* which happens automatically.
*/
gtk_widget_set_name (child, "canvas");
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (child),
drawing_area_draw,
NULL, NULL);
gtk_overlay_set_child (GTK_OVERLAY (overlay), child);
child = gtk_button_new ();
@@ -122,7 +132,7 @@ do_css_multiplebgs (GtkWidget *do_widget)
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
sw = gtk_scrolled_window_new ();
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_paned_set_end_child (GTK_PANED (paned), sw);
child = gtk_text_view_new_with_buffer (text);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), child);
@@ -144,7 +154,7 @@ do_css_multiplebgs (GtkWidget *do_widget)
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));

View File

@@ -1,7 +1,6 @@
/* Theming/Animated Backgrounds
*
* This demo is in honour of a classic Pixbufs demo.
*
* This demo is done in honour of the Pixbufs demo further down.
* It is done exclusively with CSS as the background of the window.
*/
@@ -49,23 +48,20 @@ css_text_changed (GtkTextBuffer *buffer,
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
gtk_css_provider_load_from_string (provider, text);
gtk_css_provider_load_from_data (provider, text, -1);
g_free (text);
}
static void
clear_provider (gpointer data)
{
GtkStyleProvider *provider = data;
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
}
static void
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
{
gtk_style_context_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
GtkWidget *child;
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
apply_css (child, provider);
}
GtkWidget *
@@ -84,7 +80,6 @@ do_css_pixbufs (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Animated Backgrounds");
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
gtk_widget_add_css_class (window, "demo");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
@@ -106,7 +101,7 @@ do_css_pixbufs (GtkWidget *do_widget)
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
container = gtk_scrolled_window_new ();
container = gtk_scrolled_window_new (NULL, NULL);
gtk_paned_set_end_child (GTK_PANED (paned), container);
child = gtk_text_view_new_with_buffer (text);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (container), child);
@@ -126,7 +121,7 @@ do_css_pixbufs (GtkWidget *do_widget)
}
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));

View File

@@ -46,19 +46,19 @@
}
@keyframes size-the-image {
0% { background-size: 96px, 12px, 96px, 12px, 96px, 12px, 96px, 12px, auto; }
100% { background-size: 12px, 96px, 12px, 96px, 12px, 96px, 12px, 96px, auto; }
0% { background-size: 96px, 12px, 96px, 12px, 96px, 12px, 96px, 12px, auto }
100% { background-size: 12px, 96px, 12px, 96px, 12px, 96px, 12px, 96px, auto }
}
window.demo {
background-image: url("resource://css_pixbufs/images/apple-red.png"),
url("resource://css_pixbufs/images/gnome-applets.png"),
url("resource://css_pixbufs/images/gnome-calendar.png"),
url("resource://css_pixbufs/images/gnome-foot.png"),
url("resource://css_pixbufs/images/gnome-gmush.png"),
url("resource://css_pixbufs/images/gnome-gimp.png"),
url("resource://css_pixbufs/images/gnome-gsame.png"),
url("resource://css_pixbufs/images/gnu-keys.png"),
window {
background-image: url("resource://css_pixbufs/apple-red.png"),
url("resource://css_pixbufs/gnome-applets.png"),
url("resource://css_pixbufs/gnome-calendar.png"),
url("resource://css_pixbufs/gnome-foot.png"),
url("resource://css_pixbufs/gnome-gmush.png"),
url("resource://css_pixbufs/gnome-gimp.png"),
url("resource://css_pixbufs/gnome-gsame.png"),
url("resource://css_pixbufs/gnu-keys.png"),
url("resource://css_pixbufs/background.jpg");
background-position: 50.00% 75.00%, 67.68% 67.68%, 75.00% 50.00%, 67.68% 32.32%, 50.00% 25.00%, 32.32% 32.32%, 25.00% 50.00%, 32.32% 67.68%, 0% 0%;
background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, repeat;
@@ -66,11 +66,11 @@ window.demo {
}
/* Make the text editor has a nice style */
window.demo .view, scrollbar, separator {
.view, scrollbar, separator {
color: black;
background-color: rgba(255,255,255,0.5);
}
window.demo .view:selected {
.view:selected {
background-color: rgba(127,127,255,0.5);
}

View File

@@ -46,23 +46,20 @@ css_text_changed (GtkTextBuffer *buffer,
gtk_text_buffer_remove_all_tags (buffer, &start, &end);
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
gtk_css_provider_load_from_string (provider, text);
gtk_css_provider_load_from_data (provider, text, -1);
g_free (text);
}
static void
clear_provider (gpointer data)
{
GtkStyleProvider *provider = data;
gtk_style_context_remove_provider_for_display (gdk_display_get_default (), provider);
}
static void
apply_css (GtkWidget *widget, GtkStyleProvider *provider)
{
gtk_style_context_add_provider_for_display (gdk_display_get_default (), provider, G_MAXUINT);
g_object_set_data_full (G_OBJECT (widget), "provider", provider, clear_provider);
GtkWidget *child;
gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
for (child = gtk_widget_get_first_child (widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
apply_css (child, provider);
}
static GtkWidget *
@@ -102,7 +99,6 @@ do_css_shadows (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Shadows");
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
gtk_widget_add_css_class (window, "demo");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
paned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
@@ -110,7 +106,6 @@ do_css_shadows (GtkWidget *do_widget)
child = create_toolbar ();
gtk_paned_set_start_child (GTK_PANED (paned), child);
gtk_paned_set_resize_start_child (GTK_PANED (paned), FALSE);
text = gtk_text_buffer_new (NULL);
gtk_text_buffer_create_tag (text,
@@ -124,7 +119,7 @@ do_css_shadows (GtkWidget *do_widget)
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
container = gtk_scrolled_window_new ();
container = gtk_scrolled_window_new (NULL, NULL);
gtk_paned_set_end_child (GTK_PANED (paned), container);
child = gtk_text_view_new_with_buffer (text);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (container), child);
@@ -144,7 +139,7 @@ do_css_shadows (GtkWidget *do_widget)
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));

View File

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

View File

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

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